aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbarenblat@galois.com>2013-12-20 13:57:39 -0800
committerGravatar Benjamin Barenblat <bbarenblat@galois.com>2014-01-06 14:44:40 -0800
commita9067eb46b845f70c9282bad59fbe6e8dba0e515 (patch)
tree8bf9dcaf564127e26f07a21ad2fb95c755f66ce5
Initial commit
-rw-r--r--.dir-locals.el33
-rw-r--r--.gitignore50
-rw-r--r--COPYING674
-rw-r--r--INSTALL319
-rw-r--r--Makefile.am23
-rw-r--r--README115
-rw-r--r--configure.ac109
-rw-r--r--examples/simple.tttbin0 -> 507079 bytes
-rw-r--r--m4/ax_cxx_compile_stdcxx_11.m4133
-rw-r--r--m4/boost.m41239
-rw-r--r--src/Makefile.am97
-rw-r--r--src/automobile.cpp403
-rw-r--r--src/automobile.h30
-rw-r--r--src/csv-inl.h58
-rw-r--r--src/csv.cpp48
-rw-r--r--src/csv.h71
-rw-r--r--src/main.cpp137
-rw-r--r--src/main.h44
-rw-r--r--src/measurement-inl.h62
-rw-r--r--src/measurement.cpp68
-rw-r--r--src/measurement.h93
-rw-r--r--src/noise-inl.h51
-rw-r--r--src/noise.cpp73
-rw-r--r--src/noise.h72
-rw-r--r--src/vrep-inl.h118
-rw-r--r--src/vrep.cpp72
-rw-r--r--src/vrep.h104
-rw-r--r--src/vrepFfi-inl.h133
-rw-r--r--src/vrepFfi.cpp68
-rw-r--r--src/vrepFfi.h158
30 files changed, 4655 insertions, 0 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..d7ec655
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,33 @@
+;; .dir-locals.el -- directory-local variables for the car plugin
+;; Copyright (C) 2013 Galois, Inc.
+;;
+;; This library is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free Software
+;; Foundation, either version 3 of the License, or (at your option) any later
+;; version.
+;;
+;; This library is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+;; details.
+;;
+;; You should have received a copy of the GNU General Public License along with
+;; this library. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+;; or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+;; Oregon, 97204-1622.
+
+
+((nil . ((fill-column . 80)))
+ (autoconf-mode . ((indent-tabs-mode . nil)))
+ (makefile-automake-mode . ((indent-tabs-mode . t)))
+ (c++-mode . ((c-file-style . "bsd")
+ (c-basic-offset . 4)
+ (indent-tabs-mode . nil)))
+ ;; This is not a polyglot library, so open .h files in C++ mode.
+ (c-mode . ((mode . c++)
+ (c-file-style . "bsd")
+ (c-basic-offset . 4)
+ (indent-tabs-mode . nil)))
+ (text-mode . ((indent-tabs-mode . nil))))
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..495866c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,50 @@
+# .gitignore for the V-REP automobile plugin -*- conf -*-
+
+# Editor backup files
+*~
+\#*
+.\#*
+
+# autoscan
+autoscan.log
+configure.scan
+
+# aclocal
+aclocal.m4
+autom4te.cache/
+m4/libtool.m4
+m4/lt*.m4
+
+# autoconf
+configure
+
+# autoheader
+config.h.in
+
+# libtoolize
+ltmain.sh
+
+# automake
+Makefile.in
+ar-lib
+config.guess
+config.sub
+depcomp
+install-sh
+missing
+
+# configure
+.deps/
+Makefile
+config.h
+config.log
+config.status
+libtool
+ppamltracer.pc
+stamp-*
+
+# make
+.libs/
+*.la
+*.lo
+*.o
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..6733fd6
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,319 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, Inc.
+Copyright (C) 2013 Galois, Inc.
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and this
+notice are preserved. This file is offered as-is, without warranty of any kind.
+
+Basic Installation
+==================
+
+Briefly, the shell commands
+
+ export VREP=/path/to/vrep/installation
+ ./configure
+ make
+ make install
+
+should configure, build, and install this package.
+
+The `configure' shell script attempts to guess correct values for various
+system-dependent variables used during compilation. It uses those values to
+create a `Makefile' in the top-level directory of the package, as well as the
+`src' subdirectory. It also creates a `config.h' file containing
+system-dependent definitions. Finally, it creates a shell script
+`config.status' that you can run in the future to recreate the current
+configuration, and a file `config.log' containing compiler output (useful mainly
+for debugging `configure').
+
+It can also use an optional file (typically called `config.cache' and enabled
+with `--cache-file=config.cache' or simply `-C') that saves the results of its
+tests to speed up reconfiguring. Caching is disabled by default to prevent
+problems with accidental use of stale cache files.
+
+If you need to do unusual things to compile the package, please try to figure
+out how `configure' could check whether to do them, and mail diffs or
+instructions to the address given in the `README' so they can be considered for
+the next release. If you are using the cache, and at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+The file `configure.ac' is used to create `configure' by a program called
+`autoconf'. You need `configure.ac' if you want to change it or regenerate
+`configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. If you have not done so already, install V-REP and the Boost file system
+ library.
+
+ 2. Export the environment variable `VREP' such that it points to the top-level
+ directory of your V-REP installation.
+
+ 3. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 4. Type `make' to compile the package.
+
+ 5. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 6. You can remove the program object files from the source code directory by
+ typing `make clean'. To also remove the files that `configure' created (so
+ you can compile the package for a different kind of computer), type `make
+ distclean'. There is also a `make maintainer-clean' target, but that is
+ intended mainly for the package's developers. If you use it, you may have
+ to get all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 7. You can also type `make uninstall' to remove the installed files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for details on
+some of the pertinent environment variables.
+
+You can give `configure' initial values for configuration parameters by setting
+variables in the command line or in the environment. Here is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the same time,
+by placing the object files for each architecture in their own directory. To do
+this, you can use GNU `make'. `cd' to the directory where you want the object
+files and executables to go and run the `configure' script. `configure'
+automatically checks for the source code in the directory that `configure' is in
+and in `..'. This is known as a "VPATH" build.
+
+With a non-GNU `make', it is safer to compile the package for one architecture
+at a time in the source code directory. After you have installed the package
+for one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+On Mac OS X 10.5 and later systems, you can create libraries and executables
+that work on multiple system types--known as "fat" or "universal" binaries--by
+specifying multiple `-arch' options to the compiler but only a single `-arch'
+option to the preprocessor. Like this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+This is not guaranteed to produce working output in all cases, you may have to
+build one architecture at a time and combine the results using the `lipo' tool
+if you have problems.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's libraries under
+`/usr/local/lib'. You can specify an installation prefix other than
+`/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX
+must be an absolute file name.
+
+You can specify separate installation prefixes for architecture-specific files
+and architecture-independent files. If you pass the option
+`--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for
+installing programs and libraries. Documentation and other data files still use
+the regular prefix.
+
+In addition, if you use an unusual directory layout you can give options like
+`--bindir=DIR' to specify different values for particular kinds of files. Run
+`configure --help' for a list of the directories you can set and what kinds of
+files go in them. In general, the default for these options is expressed in
+terms of `${prefix}', so that specifying just `--prefix' will affect all of the
+other directory specifications that were not explicitly provided.
+
+The most portable way to affect installation locations is to pass the correct
+locations to `configure'; however, many packages provide one or both of the
+following shortcuts of passing variable assignments to the `make install'
+command line to change installation locations without having to reconfigure or
+recompile.
+
+The first method involves providing an override variable for each affected
+directory. For example, `make install prefix=/alternate/directory' will choose
+an alternate location for all directory configuration variables that were
+expressed in terms of `${prefix}'. Any directories that were specified during
+`configure', but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of makefile
+variable overrides for each directory variable is required by the GNU Coding
+Standards, and ideally causes no recompilation. However, some platforms have
+known limitations with the semantics of shared libraries that end up requiring
+recompilation when using this method, particularly noticeable in packages that
+use GNU Libtool.
+
+The second method involves providing the `DESTDIR' variable. For example, `make
+install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before
+all installation names. The approach of `DESTDIR' overrides is not required by
+the GNU Coding Standards, and does not work on platforms that have drive
+letters. On the other hand, it does better at avoiding recompilation issues,
+and works well even when some directory options were not specified in terms of
+`${prefix}' at `configure' time.
+
+Optional Features
+=================
+
+This package offers the ability to configure how verbose the execution of `make'
+will be. For these packages, running `./configure --enable-silent-rules' sets
+the default to minimal output, which can be overridden with `make V=1'; while
+running `./configure --disable-silent-rules' sets the default to verbose, which
+can be overridden with `make V=0'.
+
+Particular systems
+==================
+
+On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not
+installed, it is recommended to use the following options in order to use an
+ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+HP-UX `make' updates targets which have the same time stamps as their
+prerequisites, which makes it generally unusable when shipped generated files
+such as `configure' are involved. Use GNU `make' instead.
+
+On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its
+`<wchar.h>' header file. The option `-nodtk' can be used as a workaround. If
+GNU CC is not installed, it is therefore recommended to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains
+several dysfunctional programs; working variants of these programs are available
+in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_
+`/usr/bin'.
+
+On Haiku, software installed for all users goes in `/boot/common', not
+`/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically, but
+needs to determine by the type of machine the package will run on. Usually,
+assuming the package is built to be run on the _same_ architectures, `configure'
+can figure that out, but if it prints a message saying it cannot guess the
+machine type, give it the `--build=TYPE' option. TYPE can either be a short
+name for the system type, such as `sun4', or a canonical name which has the
+form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't need to
+know the machine type.
+
+If you are _building_ compiler tools for cross-compiling, you should use the
+option `--target=TYPE' to select the type of system they will produce code for.
+
+If you want to _use_ a cross compiler, that generates code for a platform
+different from the build platform, you should specify the "host" platform (i.e.,
+that on which the generated programs will eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you can
+create a site shell script called `config.site' that gives default values for
+variables like `CC', `cache_file', and `prefix'. `configure' looks for
+`PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it
+exists. Or, you can set the `CONFIG_SITE' environment variable to the location
+of the site script. A warning: not all `configure' scripts look for a site
+script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the environment
+passed to `configure'. However, some packages may run configure again during
+the build, and the customized values of these variables may be lost. In order
+to avoid this problem, you should set them in the `configure' command line,
+using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..aaef76e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,23 @@
+# Makefile.am -- automake script for the car plugin
+# Copyright (C) 2013 Galois, Inc.
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+# Oregon, 97204-1622.
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = src
diff --git a/README b/README
new file mode 100644
index 0000000..8d424b9
--- /dev/null
+++ b/README
@@ -0,0 +1,115 @@
+ ppaml-vrep-automobile-plugin, v1.0.0
+
+This package provides a data collection plugin for the V-REP robotics simulator
+<http://coppeliarobotics.com/>. The plugin is targeted at data collection
+following the model described at
+<http://prism2.mem.drexel.edu/~vefa/courses/SLAM/nebotJournal.pdf>, but it may
+be useful for other projects as well.
+
+For detailed installation instructions, see the INSTALL file.
+
+For examples of use, see the examples directory.
+
+Once you have installed the library and restarted V-REP, you'll have at your
+disposal five new Lua functions:
+
+ - simExtAutomobileInit(string directoryName, number L, number h, number a,
+ number b, number theta0, number max_distance,
+ number max_intensity)
+ Initializes the plugin. Consequently, you must call this at least once
+ during your run, and we strongly recommend you do so before collecting any
+ data. :) The parameters are:
+
+ - directoryName: The base directory for the output data. If the
+ directory does not exist, the plugin will create it. If the directory
+ does exist, the plugin will remove anything in it that looks like data
+ from a previous run.
+
+ - L, h, a, b, theta0: Model parameters as described in the paper.
+ Specifically:
+
+ - L: Distance between front and rear axles.
+
+ - h: Distance between center of rear axle and encoder on left rear
+ wheel. In examples/simple.ttt, this parameter is zero, as no
+ encoder is used; instead, we measure position directly at the
+ center of the rear axle.
+
+ - a, b: Distance between the rear axle and the lidar sensor,
+ expressed as a 2D vector. The basis vectors point in line with the
+ car and forward (for a) and in line with the axle and to the left
+ side of the vehicle (for b).
+
+ - theta0: Initial angle of the car, with 0 defined as due east and
+ increasing counterclockwise (i.e., in the positive k̂ direction).
+
+ - max_distance, max_intensity: Lidar parameters. max_distance should be
+ set to the distance between the lidar sensors' apertures and their far
+ clip planes; in examples/simple.ttt, this is 10. max_intensity is
+ entirely dependent on what code you're using to postprocess the data;
+ we've had it set at 32768, but you can pick whatever you want without
+ incident.
+
+ - simExtAutomobileRequestNoise(table2 xy, table2 angle, table2 speed,
+ table2 steeringAngle, table2 distance,
+ table2 intensity)
+ Requests that, in addition to the gathered data, the plugin also generate a
+ data set with artificial Gaussian noise added. Should you wish to use this
+ function, we strongly recommend you only call it once per run. The
+ parameters are two-element numeric tables describing the mean and standard
+ deviation for the noise applied to each measurement.
+
+ - simExtAutomobileSavePose(number simulationTime, number x, number y,
+ number theta)
+ Records a pose (position and angle). You should call this repeatedly to
+ save multiple poses over the course of a simulation.
+
+ - simExtAutomobileSaveControls(number simulationTime, number speed,
+ number steeringAngle)
+ Records measurements taken from control surfaces of the car--speed and
+ steering angle of the right front wheel. (This model has Ackermann
+ steering; hence, the two front wheels will generally not be oriented at
+ equal angles.) You should call this repeatedly to save multiple data over
+ the course of a simulation.
+
+ - simExtAutomobileSaveLaserPair(number simulationTime, table leftDepthBuffer,
+ table rightDepthBuffer, table leftImage,
+ table rightImage)
+ Records measurements from the lidar. You should call this repeatedbly to
+ save multiple data over the course of a simulation. So that you may
+ simulate a lidar with a wider angle than V-REP's distance sensor part
+ supports, you can pass two inputs, which will be concatenated in the plugin
+ before being written to the file. Your input tables may be of any length,
+ but they must be the same length on each call to this function throughout a
+ single run--should you fail to maintainf this invariant, the plugin will
+ crash with a C++ exception, bringing down V-REP with it.
+
+The output directory tree will look like this:
+
+ output_dir
+ ├── ground
+ │   ├── slam_control.csv
+ │   ├── slam_gps.csv
+ │   ├── slam_laser.csv
+ │   └── slam_sensor.csv
+ ├── noisy
+ │   ├── slam_control.csv
+ │   ├── slam_gps.csv
+ │   ├── slam_laser.csv
+ │   └── slam_sensor.csv
+ └── properties.csv
+
+The properties.csv file contains run properties written with
+simExtAutomobileInit. The ground subdirectory contains ground truth data; the
+noisy subdirectory contains data with additive noise. In each subdirectory,
+you'll find
+
+ - slam_sensor.csv: A "table of contents" file that describes which sensor was
+ sampled at what time.
+
+ - slam_gps.csv: All poses saved with simExtAutomobileSavePose.
+
+ - slam_sensor.csv: All data saved with simExtAutomobileSaveControls.
+
+ - slam_laser.csv: All lidar measurements saved with
+ simExtAutomobileSaveLaserPair.
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..1bf6e65
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,109 @@
+# configure.ac -- autoconf script for the car plugin
+# Copyright (C) 2013 Galois, Inc.
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+# Oregon, 97204-1622.
+
+# Fire up Autoconf.
+AC_PREREQ([2.69])
+AC_INIT([libv_repExtAutomobile], [1.0.0], [bbarenblat@galois.com])
+AC_CANONICAL_TARGET
+
+# This package will build but not function on OS X, so fail fast if we're on
+# Darwin.
+case "$target_os" in
+ darwin*)
+ AC_MSG_ERROR([this plugin will not function on OS X])
+ ;;
+esac
+
+# Fire up Automake.
+AM_INIT_AUTOMAKE([-Wall -Wno-gnu -Wno-override -Werror foreign no-dist-gzip dist-bzip2])
+AC_CONFIG_MACRO_DIR([m4])
+
+# Build quietly.
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# Build a C++ library.
+AC_CONFIG_SRCDIR([config.h.in])
+AC_CONFIG_HEADERS([config.h])
+AC_PROG_CXX
+AX_CXX_COMPILE_STDCXX_11([noext],[mandatory])
+# Automake 1.12 seems to require this, but automake 1.11 doesn't recognize it.
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+LT_INIT
+AC_PROG_LN_S
+
+# Dependencies
+AC_ARG_VAR([VREP], [path to V-REP installation])
+if test -z "$VREP"; then
+ AC_MSG_ERROR([empty VREP environment variable; please set it to the path to the V-REP installation directory])
+fi
+VREP_CXXFLAGS=-I$VREP/programming/include
+AC_SUBST([VREP])
+AC_SUBST([VREP_CXXFLAGS])
+
+BOOST_REQUIRE
+BOOST_FILESYSTEM
+BOOST_OPTIONAL([1.34])
+
+# C++11 initializer list syntax is nice! Sadly, it is not universally
+# supported. Notably, Clang <3.1 lacks support for initializer lists, and a
+# number of systems--e.g., Debian Wheezy machines--have pre-3.1 Clang.
+# TODO: Once Clang 3.0 and earlier disappear from the ecosystem, get rid of
+# HAVE_CXX11_INITIALIZER_LISTS and make this check fatal on error.
+AC_LANG_PUSH([C++])
+AC_MSG_CHECKING([for initializer list support])
+# Double brackets go around the argument to AC_LANG_SOURCE, lest m4 replace the
+# square brackets in the C++ code.
+AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[#include <vector>
+int main(int argc, char *argv[]) {
+ std::vector<int> test {1, 2, 3};
+ return 0;
+}]])],
+ [AC_DEFINE(
+ [HAVE_CXX11_INITIALIZER_LISTS],
+ [1],
+ [Define to 1 if your compiler supports C++11 initializer lists.])
+ AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])])
+AC_LANG_POP([C++])
+
+# Same for lambda expressions.
+AC_LANG_PUSH([C++])
+AC_MSG_CHECKING([for C++11 closure support])
+AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[int main(int argc, char *argv[]) {
+ auto test = [](int &n){ n++; };
+ return 0;
+}]])],
+ [AC_DEFINE(
+ [HAVE_CXX11_CLOSURES],
+ [1],
+ [Define to 1 if your compiler supports C++11 closure syntax.])
+ AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])])
+AC_LANG_POP([C++])
+
+# Generate Makefiles.
+AC_CONFIG_FILES([
+ Makefile
+ src/Makefile])
+
+# All done.
+AC_OUTPUT
diff --git a/examples/simple.ttt b/examples/simple.ttt
new file mode 100644
index 0000000..d95dca7
--- /dev/null
+++ b/examples/simple.ttt
Binary files differ
diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 0000000..af37acd
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,133 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the C++11
+# standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+# The first argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The second argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline C++11 support is required and that the macro
+# should error out if no mode with that support is found. If specified
+# 'optional', then configuration proceeds regardless, after defining
+# HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 3
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ typedef check<check<bool>> right_angle_brackets;
+
+ int a;
+ decltype(a) b;
+
+ typedef check<int> check_type;
+ check_type c;
+ check_type&& cr = static_cast<check_type&&>(c);
+
+ auto d = a;
+])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+ m4_if([$1], [], [],
+ [$1], [ext], [],
+ [$1], [noext], [],
+ [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+ [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+ [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+ AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+ ax_cv_cxx_compile_cxx11,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [ax_cv_cxx_compile_cxx11=yes],
+ [ax_cv_cxx_compile_cxx11=no])])
+ if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+ ac_success=yes
+ fi
+
+ m4_if([$1], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=gnu++11 -std=gnu++0x; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$1], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=c++11 -std=c++0x; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx11_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+ fi
+ else
+ if test x$ac_success = xno; then
+ HAVE_CXX11=0
+ AC_MSG_NOTICE([No compiler with C++11 support was found])
+ else
+ HAVE_CXX11=1
+ AC_DEFINE(HAVE_CXX11,1,
+ [define if the compiler supports basic C++11 syntax])
+ fi
+
+ AC_SUBST(HAVE_CXX11)
+ fi
+])
diff --git a/m4/boost.m4 b/m4/boost.m4
new file mode 100644
index 0000000..c8eb65a
--- /dev/null
+++ b/m4/boost.m4
@@ -0,0 +1,1239 @@
+# boost.m4: Locate Boost headers and libraries for autoconf-based projects.
+# Copyright (C) 2007, 2008, 2009, 2010, 2011 Benoit Sigoure <tsuna@lrde.epita.fr>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Additional permission under section 7 of the GNU General Public
+# License, version 3 ("GPLv3"):
+#
+# If you convey this file as part of a work that contains a
+# configuration script generated by Autoconf, you may do so under
+# terms of your choice.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+m4_define([_BOOST_SERIAL], [m4_translit([
+# serial 18
+], [#
+], [])])
+
+# Original sources can be found at http://github.com/tsuna/boost.m4
+# You can fetch the latest version of the script by doing:
+# wget http://github.com/tsuna/boost.m4/raw/master/build-aux/boost.m4
+
+# ------ #
+# README #
+# ------ #
+
+# This file provides several macros to use the various Boost libraries.
+# The first macro is BOOST_REQUIRE. It will simply check if it's possible to
+# find the Boost headers of a given (optional) minimum version and it will
+# define BOOST_CPPFLAGS accordingly. It will add an option --with-boost to
+# your configure so that users can specify non standard locations.
+# If the user's environment contains BOOST_ROOT and --with-boost was not
+# specified, --with-boost=$BOOST_ROOT is implicitly used.
+# For more README and documentation, go to http://github.com/tsuna/boost.m4
+# Note: THESE MACROS ASSUME THAT YOU USE LIBTOOL. If you don't, don't worry,
+# simply read the README, it will show you what to do step by step.
+
+m4_pattern_forbid([^_?(BOOST|Boost)_])
+
+
+# _BOOST_SED_CPP(SED-PROGRAM, PROGRAM,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# --------------------------------------------------------
+# Same as AC_EGREP_CPP, but leave the result in conftest.i.
+#
+# SED-PROGRAM is *not* overquoted, as in AC_EGREP_CPP. It is expanded
+# in double-quotes, so escape your double quotes.
+#
+# It could be useful to turn this into a macro which extracts the
+# value of any macro.
+m4_define([_BOOST_SED_CPP],
+[AC_LANG_PREPROC_REQUIRE()dnl
+AC_REQUIRE([AC_PROG_SED])dnl
+AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])])
+AS_IF([dnl eval is necessary to expand ac_cpp.
+dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell.
+dnl Beware of Windows end-of-lines, for instance if we are running
+dnl some Windows programs under Wine. In that case, boost/version.hpp
+dnl is certainly using "\r\n", but the regular Unix shell will only
+dnl strip `\n' with backquotes, not the `\r'. This results in
+dnl boost_cv_lib_version='1_37\r' for instance, which breaks
+dnl everything else.
+dnl Cannot use 'dnl' after [$4] because a trailing dnl may break AC_CACHE_CHECK
+(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
+ tr -d '\r' |
+ $SED -n -e "$1" >conftest.i 2>&1],
+ [$3],
+ [$4])
+rm -rf conftest*
+])# AC_EGREP_CPP
+
+
+
+# BOOST_REQUIRE([VERSION], [ACTION-IF-NOT-FOUND])
+# -----------------------------------------------
+# Look for Boost. If version is given, it must either be a literal of the form
+# "X.Y.Z" where X, Y and Z are integers (the ".Z" part being optional) or a
+# variable "$var".
+# Defines the value BOOST_CPPFLAGS. This macro only checks for headers with
+# the required version, it does not check for any of the Boost libraries.
+# On # success, defines HAVE_BOOST. On failure, calls the optional
+# ACTION-IF-NOT-FOUND action if one was supplied.
+# Otherwise aborts with an error message.
+AC_DEFUN([BOOST_REQUIRE],
+[AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_PROG_GREP])dnl
+echo "$as_me: this is boost.m4[]_BOOST_SERIAL" >&AS_MESSAGE_LOG_FD
+boost_save_IFS=$IFS
+boost_version_req=$1
+IFS=.
+set x $boost_version_req 0 0 0
+IFS=$boost_save_IFS
+shift
+boost_version_req=`expr "$[1]" '*' 100000 + "$[2]" '*' 100 + "$[3]"`
+boost_version_req_string=$[1].$[2].$[3]
+AC_ARG_WITH([boost],
+ [AS_HELP_STRING([--with-boost=DIR],
+ [prefix of Boost $1 @<:@guess@:>@])])dnl
+AC_ARG_VAR([BOOST_ROOT],[Location of Boost installation])dnl
+# If BOOST_ROOT is set and the user has not provided a value to
+# --with-boost, then treat BOOST_ROOT as if it the user supplied it.
+if test x"$BOOST_ROOT" != x; then
+ if test x"$with_boost" = x; then
+ AC_MSG_NOTICE([Detected BOOST_ROOT; continuing with --with-boost=$BOOST_ROOT])
+ with_boost=$BOOST_ROOT
+ else
+ AC_MSG_NOTICE([Detected BOOST_ROOT=$BOOST_ROOT, but overridden by --with-boost=$with_boost])
+ fi
+fi
+AC_SUBST([DISTCHECK_CONFIGURE_FLAGS],
+ ["$DISTCHECK_CONFIGURE_FLAGS '--with-boost=$with_boost'"])dnl
+boost_save_CPPFLAGS=$CPPFLAGS
+ AC_CACHE_CHECK([for Boost headers version >= $boost_version_req_string],
+ [boost_cv_inc_path],
+ [boost_cv_inc_path=no
+AC_LANG_PUSH([C++])dnl
+m4_pattern_allow([^BOOST_VERSION$])dnl
+ AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <boost/version.hpp>
+#if !defined BOOST_VERSION
+# error BOOST_VERSION is not defined
+#elif BOOST_VERSION < $boost_version_req
+# error Boost headers version < $boost_version_req
+#endif
+]])])
+ # If the user provided a value to --with-boost, use it and only it.
+ case $with_boost in #(
+ ''|yes) set x '' /opt/local/include /usr/local/include /opt/include \
+ /usr/include C:/Boost/include;; #(
+ *) set x "$with_boost/include" "$with_boost";;
+ esac
+ shift
+ for boost_dir
+ do
+ # Without --layout=system, Boost (or at least some versions) installs
+ # itself in <prefix>/include/boost-<version>. This inner loop helps to
+ # find headers in such directories.
+ #
+ # Any ${boost_dir}/boost-x_xx directories are searched in reverse version
+ # order followed by ${boost_dir}. The final '.' is a sentinel for
+ # searching $boost_dir" itself. Entries are whitespace separated.
+ #
+ # I didn't indent this loop on purpose (to avoid over-indented code)
+ boost_layout_system_search_list=`cd "$boost_dir" 2>/dev/null \
+ && ls -1 | "${GREP}" '^boost-' | sort -rn -t- -k2 \
+ && echo .`
+ for boost_inc in $boost_layout_system_search_list
+ do
+ if test x"$boost_inc" != x.; then
+ boost_inc="$boost_dir/$boost_inc"
+ else
+ boost_inc="$boost_dir" # Uses sentinel in boost_layout_system_search_list
+ fi
+ if test x"$boost_inc" != x; then
+ # We are going to check whether the version of Boost installed
+ # in $boost_inc is usable by running a compilation that
+ # #includes it. But if we pass a -I/some/path in which Boost
+ # is not installed, the compiler will just skip this -I and
+ # use other locations (either from CPPFLAGS, or from its list
+ # of system include directories). As a result we would use
+ # header installed on the machine instead of the /some/path
+ # specified by the user. So in that precise case (trying
+ # $boost_inc), make sure the version.hpp exists.
+ #
+ # Use test -e as there can be symlinks.
+ test -e "$boost_inc/boost/version.hpp" || continue
+ CPPFLAGS="$CPPFLAGS -I$boost_inc"
+ fi
+ AC_COMPILE_IFELSE([], [boost_cv_inc_path=yes], [boost_cv_version=no])
+ if test x"$boost_cv_inc_path" = xyes; then
+ if test x"$boost_inc" != x; then
+ boost_cv_inc_path=$boost_inc
+ fi
+ break 2
+ fi
+ done
+ done
+AC_LANG_POP([C++])dnl
+ ])
+ case $boost_cv_inc_path in #(
+ no)
+ boost_errmsg="cannot find Boost headers version >= $boost_version_req_string"
+ m4_if([$2], [], [AC_MSG_ERROR([$boost_errmsg])],
+ [AC_MSG_NOTICE([$boost_errmsg])])
+ $2
+ ;;#(
+ yes)
+ BOOST_CPPFLAGS=
+ ;;#(
+ *)
+ AC_SUBST([BOOST_CPPFLAGS], ["-I$boost_cv_inc_path"])dnl
+ ;;
+ esac
+ if test x"$boost_cv_inc_path" != xno; then
+ AC_DEFINE([HAVE_BOOST], [1],
+ [Defined if the requested minimum BOOST version is satisfied])
+ AC_CACHE_CHECK([for Boost's header version],
+ [boost_cv_lib_version],
+ [m4_pattern_allow([^BOOST_LIB_VERSION$])dnl
+ _BOOST_SED_CPP([/^boost-lib-version = /{s///;s/\"//g;p;q;}],
+ [#include <boost/version.hpp>
+boost-lib-version = BOOST_LIB_VERSION],
+ [boost_cv_lib_version=`cat conftest.i`])])
+ # e.g. "134" for 1_34_1 or "135" for 1_35
+ boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'`
+ case $boost_major_version in #(
+ '' | *[[!0-9]]*)
+ AC_MSG_ERROR([invalid value: boost_major_version=$boost_major_version])
+ ;;
+ esac
+fi
+CPPFLAGS=$boost_save_CPPFLAGS
+])# BOOST_REQUIRE
+
+# BOOST_STATIC()
+# --------------
+# Add the "--enable-static-boost" configure argument. If this argument is given
+# on the command line, static versions of the libraries will be looked up.
+AC_DEFUN([BOOST_STATIC],
+ [AC_ARG_ENABLE([static-boost],
+ [AS_HELP_STRING([--enable-static-boost],
+ [Prefer the static boost libraries over the shared ones [no]])],
+ [enable_static_boost=yes],
+ [enable_static_boost=no])])# BOOST_STATIC
+
+# BOOST_FIND_HEADER([HEADER-NAME], [ACTION-IF-NOT-FOUND], [ACTION-IF-FOUND])
+# --------------------------------------------------------------------------
+# Wrapper around AC_CHECK_HEADER for Boost headers. Useful to check for
+# some parts of the Boost library which are only made of headers and don't
+# require linking (such as Boost.Foreach).
+#
+# Default ACTION-IF-NOT-FOUND: Fail with a fatal error unless Boost couldn't be
+# found in the first place, in which case by default a notice is issued to the
+# user. Presumably if we haven't died already it's because it's OK to not have
+# Boost, which is why only a notice is issued instead of a hard error.
+#
+# Default ACTION-IF-FOUND: define the preprocessor symbol HAVE_<HEADER-NAME> in
+# case of success # (where HEADER-NAME is written LIKE_THIS, e.g.,
+# HAVE_BOOST_FOREACH_HPP).
+AC_DEFUN([BOOST_FIND_HEADER],
+[AC_REQUIRE([BOOST_REQUIRE])dnl
+if test x"$boost_cv_inc_path" = xno; then
+ m4_default([$2], [AC_MSG_NOTICE([Boost not available, not searching for $1])])
+else
+AC_LANG_PUSH([C++])dnl
+boost_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+AC_CHECK_HEADER([$1],
+ [m4_default([$3], [AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1],
+ [Define to 1 if you have <$1>])])],
+ [m4_default([$2], [AC_MSG_ERROR([cannot find $1])])])
+CPPFLAGS=$boost_save_CPPFLAGS
+AC_LANG_POP([C++])dnl
+fi
+])# BOOST_FIND_HEADER
+
+
+# BOOST_FIND_LIB([LIB-NAME], [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST],
+# [CXX-PROLOGUE])
+# -------------------------------------------------------------------------
+# Look for the Boost library LIB-NAME (e.g., LIB-NAME = `thread', for
+# libboost_thread). Check that HEADER-NAME works and check that
+# libboost_LIB-NAME can link with the code CXX-TEST. The optional argument
+# CXX-PROLOGUE can be used to include some C++ code before the `main'
+# function.
+#
+# Invokes BOOST_FIND_HEADER([HEADER-NAME]) (see above).
+#
+# Boost libraries typically come compiled with several flavors (with different
+# runtime options) so PREFERRED-RT-OPT is the preferred suffix. A suffix is one
+# or more of the following letters: sgdpn (in that order). s = static
+# runtime, d = debug build, g = debug/diagnostic runtime, p = STLPort build,
+# n = (unsure) STLPort build without iostreams from STLPort (it looks like `n'
+# must always be used along with `p'). Additionally, PREFERRED-RT-OPT can
+# start with `mt-' to indicate that there is a preference for multi-thread
+# builds. Some sample values for PREFERRED-RT-OPT: (nothing), mt, d, mt-d, gdp
+# ... If you want to make sure you have a specific version of Boost
+# (eg, >= 1.33) you *must* invoke BOOST_REQUIRE before this macro.
+AC_DEFUN([BOOST_FIND_LIB],
+[AC_REQUIRE([BOOST_REQUIRE])dnl
+AC_REQUIRE([_BOOST_FIND_COMPILER_TAG])dnl
+AC_REQUIRE([BOOST_STATIC])dnl
+AC_REQUIRE([_BOOST_GUESS_WHETHER_TO_USE_MT])dnl
+if test x"$boost_cv_inc_path" = xno; then
+ AC_MSG_NOTICE([Boost not available, not searching for the Boost $1 library])
+else
+dnl The else branch is huge and wasn't intended on purpose.
+AC_LANG_PUSH([C++])dnl
+AS_VAR_PUSHDEF([Boost_lib], [boost_cv_lib_$1])dnl
+AS_VAR_PUSHDEF([Boost_lib_LDFLAGS], [boost_cv_lib_$1_LDFLAGS])dnl
+AS_VAR_PUSHDEF([Boost_lib_LDPATH], [boost_cv_lib_$1_LDPATH])dnl
+AS_VAR_PUSHDEF([Boost_lib_LIBS], [boost_cv_lib_$1_LIBS])dnl
+BOOST_FIND_HEADER([$3])
+boost_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+# Now let's try to find the library. The algorithm is as follows: first look
+# for a given library name according to the user's PREFERRED-RT-OPT. For each
+# library name, we prefer to use the ones that carry the tag (toolset name).
+# Each library is searched through the various standard paths were Boost is
+# usually installed. If we can't find the standard variants, we try to
+# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist
+# but there's -obviously- libboost_threads-mt.dylib).
+AC_CACHE_CHECK([for the Boost $1 library], [Boost_lib],
+ [Boost_lib=no
+ case "$2" in #(
+ mt | mt-) boost_mt=-mt; boost_rtopt=;; #(
+ mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X$2" : 'Xmt-*\(.*\)'`;; #(
+ *) boost_mt=; boost_rtopt=$2;;
+ esac
+ if test $enable_static_boost = yes; then
+ boost_rtopt="s$boost_rtopt"
+ fi
+ # Find the proper debug variant depending on what we've been asked to find.
+ case $boost_rtopt in #(
+ *d*) boost_rt_d=$boost_rtopt;; #(
+ *[[sgpn]]*) # Insert the `d' at the right place (in between `sg' and `pn')
+ boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #(
+ *) boost_rt_d='-d';;
+ esac
+ # If the PREFERRED-RT-OPT are not empty, prepend a `-'.
+ test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt"
+ $boost_guess_use_mt && boost_mt=-mt
+ # Look for the abs path the static archive.
+ # $libext is computed by Libtool but let's make sure it's non empty.
+ test -z "$libext" &&
+ AC_MSG_ERROR([the libext variable is empty, did you invoke Libtool?])
+ boost_save_ac_objext=$ac_objext
+ # Generate the test file.
+ AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include <$3>
+$5], [$4])])
+dnl Optimization hacks: compiling C++ is slow, especially with Boost. What
+dnl we're trying to do here is guess the right combination of link flags
+dnl (LIBS / LDFLAGS) to use a given library. This can take several
+dnl iterations before it succeeds and is thus *very* slow. So what we do
+dnl instead is that we compile the code first (and thus get an object file,
+dnl typically conftest.o). Then we try various combinations of link flags
+dnl until we succeed to link conftest.o in an executable. The problem is
+dnl that the various TRY_LINK / COMPILE_IFELSE macros of Autoconf always
+dnl remove all the temporary files including conftest.o. So the trick here
+dnl is to temporarily change the value of ac_objext so that conftest.o is
+dnl preserved accross tests. This is obviously fragile and I will burn in
+dnl hell for not respecting Autoconf's documented interfaces, but in the
+dnl mean time, it optimizes the macro by a factor of 5 to 30.
+dnl Another small optimization: the first argument of AC_COMPILE_IFELSE left
+dnl empty because the test file is generated only once above (before we
+dnl start the for loops).
+ AC_COMPILE_IFELSE([],
+ [ac_objext=do_not_rm_me_plz],
+ [AC_MSG_ERROR([cannot compile a test that uses Boost $1])])
+ ac_objext=$boost_save_ac_objext
+ boost_failed_libs=
+# Don't bother to ident the 6 nested for loops, only the 2 innermost ones
+# matter.
+for boost_tag_ in -$boost_cv_lib_tag ''; do
+for boost_ver_ in -$boost_cv_lib_version ''; do
+for boost_mt_ in $boost_mt -mt ''; do
+for boost_rtopt_ in $boost_rtopt '' -d; do
+ for boost_lib in \
+ boost_$1$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \
+ boost_$1$boost_tag_$boost_rtopt_$boost_ver_ \
+ boost_$1$boost_tag_$boost_mt_$boost_ver_ \
+ boost_$1$boost_tag_$boost_ver_
+ do
+ # Avoid testing twice the same lib
+ case $boost_failed_libs in #(
+ *@$boost_lib@*) continue;;
+ esac
+ # If with_boost is empty, we'll search in /lib first, which is not quite
+ # right so instead we'll try to a location based on where the headers are.
+ boost_tmp_lib=$with_boost
+ test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include}
+ for boost_ldpath in "$boost_tmp_lib/lib" '' \
+ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \
+ "$with_boost" C:/Boost/lib /lib*
+ do
+ test -e "$boost_ldpath" || continue
+ boost_save_LDFLAGS=$LDFLAGS
+ # Are we looking for a static library?
+ case $boost_ldpath:$boost_rtopt_ in #(
+ *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt)
+ Boost_lib_LIBS="$boost_ldpath/lib$boost_lib.$libext"
+ test -e "$Boost_lib_LIBS" || continue;; #(
+ *) # No: use -lboost_foo to find the shared library.
+ Boost_lib_LIBS="-l$boost_lib";;
+ esac
+ boost_save_LIBS=$LIBS
+ LIBS="$Boost_lib_LIBS $LIBS"
+ test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath"
+dnl First argument of AC_LINK_IFELSE left empty because the test file is
+dnl generated only once above (before we start the for loops).
+ _BOOST_AC_LINK_IFELSE([],
+ [Boost_lib=yes], [Boost_lib=no])
+ ac_objext=$boost_save_ac_objext
+ LDFLAGS=$boost_save_LDFLAGS
+ LIBS=$boost_save_LIBS
+ if test x"$Boost_lib" = xyes; then
+ # Check or used cached result of whether or not using -R or -rpath makes sense.
+ # Some implementations of ld, such as for Mac OSX, require -rpath but
+ # -R is the flag known to work on other systems.
+ # https://github.com/tsuna/boost.m4/issues/19
+ AC_CACHE_VAL([boost_cv_rpath_link_ldflag],
+ [for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do
+ LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath"
+ LIBS="$boost_save_LIBS $Boost_lib_LIBS"
+ _BOOST_AC_LINK_IFELSE([],
+ [boost_rpath_link_ldflag_found=yes
+ break],
+ [boost_rpath_link_ldflag_found=no])
+ done
+ AS_IF([test "x$boost_rpath_link_ldflag_found" != "xyes"],
+ [AC_MSG_ERROR([Unable to determine whether to use -R or -rpath])])
+ LDFLAGS=$boost_save_LDFLAGS
+ LIBS=$boost_save_LIBS
+ ])
+ Boost_lib_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath"
+ Boost_lib_LDPATH="$boost_ldpath"
+ break 6
+ else
+ boost_failed_libs="$boost_failed_libs@$boost_lib@"
+ fi
+ done
+ done
+done
+done
+done
+done
+rm -f conftest.$ac_objext
+])
+case $Boost_lib in #(
+ no) _AC_MSG_LOG_CONFTEST
+ AC_MSG_ERROR([cannot find the flags to link with Boost $1])
+ ;;
+esac
+AC_SUBST(AS_TR_CPP([BOOST_$1_LDFLAGS]), [$Boost_lib_LDFLAGS])dnl
+AC_SUBST(AS_TR_CPP([BOOST_$1_LDPATH]), [$Boost_lib_LDPATH])dnl
+AC_SUBST([BOOST_LDPATH], [$Boost_lib_LDPATH])dnl
+AC_SUBST(AS_TR_CPP([BOOST_$1_LIBS]), [$Boost_lib_LIBS])dnl
+CPPFLAGS=$boost_save_CPPFLAGS
+AS_VAR_POPDEF([Boost_lib])dnl
+AS_VAR_POPDEF([Boost_lib_LDFLAGS])dnl
+AS_VAR_POPDEF([Boost_lib_LDPATH])dnl
+AS_VAR_POPDEF([Boost_lib_LIBS])dnl
+AC_LANG_POP([C++])dnl
+fi
+])# BOOST_FIND_LIB
+
+
+# --------------------------------------- #
+# Checks for the various Boost libraries. #
+# --------------------------------------- #
+
+# List of boost libraries: http://www.boost.org/libs/libraries.htm
+# The page http://beta.boost.org/doc/libs is useful: it gives the first release
+# version of each library (among other things).
+
+# BOOST_DEFUN(LIBRARY, CODE)
+# --------------------------
+# Define BOOST_<LIBRARY-UPPERCASE> as a macro that runs CODE.
+#
+# Use indir to avoid the warning on underquoted macro name given to AC_DEFUN.
+m4_define([BOOST_DEFUN],
+[m4_indir([AC_DEFUN],
+ m4_toupper([BOOST_$1]),
+[m4_pushdef([BOOST_Library], [$1])dnl
+$2
+m4_popdef([BOOST_Library])dnl
+])
+])
+
+# BOOST_ARRAY()
+# -------------
+# Look for Boost.Array
+BOOST_DEFUN([Array],
+[BOOST_FIND_HEADER([boost/array.hpp])])
+
+
+# BOOST_ASIO()
+# ------------
+# Look for Boost.Asio (new in Boost 1.35).
+BOOST_DEFUN([Asio],
+[AC_REQUIRE([BOOST_SYSTEM])dnl
+BOOST_FIND_HEADER([boost/asio.hpp])])
+
+
+# BOOST_BIND()
+# ------------
+# Look for Boost.Bind
+BOOST_DEFUN([Bind],
+[BOOST_FIND_HEADER([boost/bind.hpp])])
+
+
+# BOOST_CHRONO()
+# ------------------
+# Look for Boost.Chrono
+BOOST_DEFUN([Chrono],
+[# Do we have to check for Boost.System? This link-time dependency was
+# added as of 1.35.0. If we have a version <1.35, we must not attempt to
+# find Boost.System as it didn't exist by then.
+if test $boost_major_version -ge 135; then
+BOOST_SYSTEM([$1])
+fi # end of the Boost.System check.
+boost_filesystem_save_LIBS=$LIBS
+boost_filesystem_save_LDFLAGS=$LDFLAGS
+m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl
+LIBS="$LIBS $BOOST_SYSTEM_LIBS"
+LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS"
+BOOST_FIND_LIB([chrono], [$1],
+ [boost/chrono.hpp],
+ [boost::chrono::thread_clock d;])
+if test $enable_static_boost = yes && test $boost_major_version -ge 135; then
+ AC_SUBST([BOOST_FILESYSTEM_LIBS], ["$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS"])
+fi
+LIBS=$boost_filesystem_save_LIBS
+LDFLAGS=$boost_filesystem_save_LDFLAGS
+
+])# BOOST_CHRONO
+
+
+# BOOST_CONVERSION()
+# ------------------
+# Look for Boost.Conversion (cast / lexical_cast)
+BOOST_DEFUN([Conversion],
+[BOOST_FIND_HEADER([boost/cast.hpp])
+BOOST_FIND_HEADER([boost/lexical_cast.hpp])
+])# BOOST_CONVERSION
+
+
+# BOOST_CRC()
+# -----------
+# Look for Boost.CRC
+BOOST_DEFUN([CRC],
+[BOOST_FIND_HEADER([boost/crc.hpp])
+])# BOOST_CRC
+
+
+# BOOST_DATE_TIME([PREFERRED-RT-OPT])
+# -----------------------------------
+# Look for Boost.Date_Time. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Date_Time],
+[BOOST_FIND_LIB([date_time], [$1],
+ [boost/date_time/posix_time/posix_time.hpp],
+ [boost::posix_time::ptime t;])
+])# BOOST_DATE_TIME
+
+
+# BOOST_FILESYSTEM([PREFERRED-RT-OPT])
+# ------------------------------------
+# Look for Boost.Filesystem. For the documentation of PREFERRED-RT-OPT, see
+# the documentation of BOOST_FIND_LIB above.
+# Do not check for boost/filesystem.hpp because this file was introduced in
+# 1.34.
+BOOST_DEFUN([Filesystem],
+[# Do we have to check for Boost.System? This link-time dependency was
+# added as of 1.35.0. If we have a version <1.35, we must not attempt to
+# find Boost.System as it didn't exist by then.
+if test $boost_major_version -ge 135; then
+BOOST_SYSTEM([$1])
+fi # end of the Boost.System check.
+boost_filesystem_save_LIBS=$LIBS
+boost_filesystem_save_LDFLAGS=$LDFLAGS
+m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl
+LIBS="$LIBS $BOOST_SYSTEM_LIBS"
+LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS"
+BOOST_FIND_LIB([filesystem], [$1],
+ [boost/filesystem/path.hpp], [boost::filesystem::path p;])
+if test $enable_static_boost = yes && test $boost_major_version -ge 135; then
+ AC_SUBST([BOOST_FILESYSTEM_LIBS], ["$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS"])
+fi
+LIBS=$boost_filesystem_save_LIBS
+LDFLAGS=$boost_filesystem_save_LDFLAGS
+])# BOOST_FILESYSTEM
+
+
+# BOOST_FOREACH()
+# ---------------
+# Look for Boost.Foreach
+BOOST_DEFUN([Foreach],
+[BOOST_FIND_HEADER([boost/foreach.hpp])])
+
+
+# BOOST_FORMAT()
+# --------------
+# Look for Boost.Format
+# Note: we can't check for boost/format/format_fwd.hpp because the header isn't
+# standalone. It can't be compiled because it triggers the following error:
+# boost/format/detail/config_macros.hpp:88: error: 'locale' in namespace 'std'
+# does not name a type
+BOOST_DEFUN([Format],
+[BOOST_FIND_HEADER([boost/format.hpp])])
+
+
+# BOOST_FUNCTION()
+# ----------------
+# Look for Boost.Function
+BOOST_DEFUN([Function],
+[BOOST_FIND_HEADER([boost/function.hpp])])
+
+
+# BOOST_GEOMETRY()
+# ----------------
+# Look for Boost.Geometry (new since 1.47.0).
+BOOST_DEFUN([Geometry],
+[BOOST_FIND_HEADER([boost/geometry.hpp])
+])# BOOST_GEOMETRY
+
+
+# BOOST_GRAPH([PREFERRED-RT-OPT])
+# -------------------------------
+# Look for Boost.Graphs. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Graph],
+[BOOST_FIND_LIB([graph], [$1],
+ [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;])
+])# BOOST_GRAPH
+
+
+# BOOST_IOSTREAMS([PREFERRED-RT-OPT])
+# -----------------------------------
+# Look for Boost.IOStreams. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([IOStreams],
+[BOOST_FIND_LIB([iostreams], [$1],
+ [boost/iostreams/device/file_descriptor.hpp],
+ [boost::iostreams::file_descriptor fd; fd.close();])
+])# BOOST_IOSTREAMS
+
+
+# BOOST_HASH()
+# ------------
+# Look for Boost.Functional/Hash
+BOOST_DEFUN([Hash],
+[BOOST_FIND_HEADER([boost/functional/hash.hpp])])
+
+
+# BOOST_LAMBDA()
+# --------------
+# Look for Boost.Lambda
+BOOST_DEFUN([Lambda],
+[BOOST_FIND_HEADER([boost/lambda/lambda.hpp])])
+
+
+# BOOST_LOG([PREFERRED-RT-OPT])
+# -----------------------------
+# Look for Boost.Log For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Log],
+[BOOST_FIND_LIB([log], [$1],
+ [boost/log/core/core.hpp],
+ [boost::log::attribute a; a.get_value();])
+])# BOOST_LOG
+
+
+# BOOST_LOG_SETUP([PREFERRED-RT-OPT])
+# -----------------------------------
+# Look for Boost.Log For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Log_Setup],
+[AC_REQUIRE([BOOST_LOG])dnl
+BOOST_FIND_LIB([log_setup], [$1],
+ [boost/log/utility/init/from_settings.hpp],
+ [boost::log::basic_settings<char> bs; bs.empty();])
+])# BOOST_LOG_SETUP
+
+
+# BOOST_MATH()
+# ------------
+# Look for Boost.Math
+# TODO: This library isn't header-only but it comes in multiple different
+# flavors that don't play well with BOOST_FIND_LIB (e.g, libboost_math_c99,
+# libboost_math_c99f, libboost_math_c99l, libboost_math_tr1,
+# libboost_math_tr1f, libboost_math_tr1l). This macro must be fixed to do the
+# right thing anyway.
+BOOST_DEFUN([Math],
+[BOOST_FIND_HEADER([boost/math/special_functions.hpp])])
+
+
+# BOOST_MULTIARRAY()
+# ------------------
+# Look for Boost.MultiArray
+BOOST_DEFUN([MultiArray],
+[BOOST_FIND_HEADER([boost/multi_array.hpp])])
+
+
+# BOOST_NUMERIC_CONVERSION()
+# --------------------------
+# Look for Boost.NumericConversion (policy-based numeric conversion)
+BOOST_DEFUN([Numeric_Conversion],
+[BOOST_FIND_HEADER([boost/numeric/conversion/converter.hpp])
+])# BOOST_NUMERIC_CONVERSION
+
+
+# BOOST_OPTIONAL()
+# ----------------
+# Look for Boost.Optional
+BOOST_DEFUN([Optional],
+[BOOST_FIND_HEADER([boost/optional.hpp])])
+
+
+# BOOST_PREPROCESSOR()
+# --------------------
+# Look for Boost.Preprocessor
+BOOST_DEFUN([Preprocessor],
+[BOOST_FIND_HEADER([boost/preprocessor/repeat.hpp])])
+
+
+# BOOST_UNORDERED()
+# -----------------
+# Look for Boost.Unordered
+BOOST_DEFUN([Unordered],
+[BOOST_FIND_HEADER([boost/unordered_map.hpp])])
+
+
+# BOOST_UUID()
+# ------------
+# Look for Boost.Uuid
+BOOST_DEFUN([Uuid],
+[BOOST_FIND_HEADER([boost/uuid/uuid.hpp])])
+
+
+# BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT])
+# -----------------------------------------
+# Look for Boost.Program_options. For the documentation of PREFERRED-RT-OPT,
+# see the documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Program_Options],
+[BOOST_FIND_LIB([program_options], [$1],
+ [boost/program_options.hpp],
+ [boost::program_options::options_description d("test");])
+])# BOOST_PROGRAM_OPTIONS
+
+
+
+# _BOOST_PYTHON_CONFIG(VARIABLE, FLAG)
+# ------------------------------------
+# Save VARIABLE, and define it via `python-config --FLAG`.
+# Substitute BOOST_PYTHON_VARIABLE.
+m4_define([_BOOST_PYTHON_CONFIG],
+[AC_SUBST([BOOST_PYTHON_$1],
+ [`python-config --$2 2>/dev/null`])dnl
+boost_python_save_$1=$$1
+$1="$$1 $BOOST_PYTHON_$1"])
+
+
+# BOOST_PYTHON([PREFERRED-RT-OPT])
+# --------------------------------
+# Look for Boost.Python. For the documentation of PREFERRED-RT-OPT,
+# see the documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Python],
+[_BOOST_PYTHON_CONFIG([CPPFLAGS], [includes])
+_BOOST_PYTHON_CONFIG([LDFLAGS], [ldflags])
+_BOOST_PYTHON_CONFIG([LIBS], [libs])
+m4_pattern_allow([^BOOST_PYTHON_MODULE$])dnl
+BOOST_FIND_LIB([python], [$1],
+ [boost/python.hpp],
+ [], [BOOST_PYTHON_MODULE(empty) {}])
+CPPFLAGS=$boost_python_save_CPPFLAGS
+LDFLAGS=$boost_python_save_LDFLAGS
+LIBS=$boost_python_save_LIBS
+])# BOOST_PYTHON
+
+
+# BOOST_REF()
+# -----------
+# Look for Boost.Ref
+BOOST_DEFUN([Ref],
+[BOOST_FIND_HEADER([boost/ref.hpp])])
+
+
+# BOOST_REGEX([PREFERRED-RT-OPT])
+# -------------------------------
+# Look for Boost.Regex. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Regex],
+[BOOST_FIND_LIB([regex], [$1],
+ [boost/regex.hpp],
+ [boost::regex exp("*"); boost::regex_match("foo", exp);])
+])# BOOST_REGEX
+
+
+# BOOST_SERIALIZATION([PREFERRED-RT-OPT])
+# ---------------------------------------
+# Look for Boost.Serialization. For the documentation of PREFERRED-RT-OPT, see
+# the documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Serialization],
+[BOOST_FIND_LIB([serialization], [$1],
+ [boost/archive/text_oarchive.hpp],
+ [std::ostream* o = 0; // Cheap way to get an ostream...
+ boost::archive::text_oarchive t(*o);])
+])# BOOST_SERIALIZATION
+
+
+# BOOST_SIGNALS([PREFERRED-RT-OPT])
+# ---------------------------------
+# Look for Boost.Signals. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Signals],
+[BOOST_FIND_LIB([signals], [$1],
+ [boost/signal.hpp],
+ [boost::signal<void ()> s;])
+])# BOOST_SIGNALS
+
+
+# BOOST_SIGNALS2()
+# ----------------
+# Look for Boost.Signals2 (new since 1.39.0).
+BOOST_DEFUN([Signals2],
+[BOOST_FIND_HEADER([boost/signals2.hpp])
+])# BOOST_SIGNALS2
+
+
+# BOOST_SMART_PTR()
+# -----------------
+# Look for Boost.SmartPtr
+BOOST_DEFUN([Smart_Ptr],
+[BOOST_FIND_HEADER([boost/scoped_ptr.hpp])
+BOOST_FIND_HEADER([boost/shared_ptr.hpp])
+])
+
+
+# BOOST_STATICASSERT()
+# --------------------
+# Look for Boost.StaticAssert
+BOOST_DEFUN([StaticAssert],
+[BOOST_FIND_HEADER([boost/static_assert.hpp])])
+
+
+# BOOST_STRING_ALGO()
+# -------------------
+# Look for Boost.StringAlgo
+BOOST_DEFUN([String_Algo],
+[BOOST_FIND_HEADER([boost/algorithm/string.hpp])
+])
+
+
+# BOOST_SYSTEM([PREFERRED-RT-OPT])
+# --------------------------------
+# Look for Boost.System. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above. This library was introduced in Boost
+# 1.35.0.
+BOOST_DEFUN([System],
+[BOOST_FIND_LIB([system], [$1],
+ [boost/system/error_code.hpp],
+ [boost::system::error_code e; e.clear();])
+])# BOOST_SYSTEM
+
+
+# BOOST_TEST([PREFERRED-RT-OPT])
+# ------------------------------
+# Look for Boost.Test. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Test],
+[m4_pattern_allow([^BOOST_CHECK$])dnl
+BOOST_FIND_LIB([unit_test_framework], [$1],
+ [boost/test/unit_test.hpp], [BOOST_CHECK(2 == 2);],
+ [using boost::unit_test::test_suite;
+ test_suite* init_unit_test_suite(int argc, char ** argv)
+ { return NULL; }])
+])# BOOST_TEST
+
+
+# BOOST_THREADS([PREFERRED-RT-OPT])
+# ---------------------------------
+# Look for Boost.Thread. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+# FIXME: Provide an alias "BOOST_THREAD".
+BOOST_DEFUN([Threads],
+[dnl Having the pthread flag is required at least on GCC3 where
+dnl boost/thread.hpp would complain if we try to compile without
+dnl -pthread on GNU/Linux.
+AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl
+boost_threads_save_LIBS=$LIBS
+boost_threads_save_LDFLAGS=$LDFLAGS
+boost_threads_save_CPPFLAGS=$CPPFLAGS
+# Link-time dependency from thread to system was added as of 1.49.0.
+if test $boost_major_version -ge 149; then
+BOOST_SYSTEM([$1])
+fi # end of the Boost.System check.
+m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl
+LIBS="$LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag"
+LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS"
+# Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
+# boost/thread.hpp will trigger a #error if -pthread isn't used:
+# boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
+# is not turned on. Please set the correct command line options for
+# threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
+CPPFLAGS="$CPPFLAGS $boost_cv_pthread_flag"
+
+# When compiling for the Windows platform, the threads library is named
+# differently.
+case $host_os in
+ (*mingw*)
+ BOOST_FIND_LIB([thread_win32], [$1],
+ [boost/thread.hpp], [boost::thread t; boost::mutex m;])
+ BOOST_THREAD_LDFLAGS=$BOOST_THREAD_WIN32_LDFLAGS
+ BOOST_THREAD_LDPATH=$BOOST_THREAD_WIN32_LDPATH
+ BOOST_THREAD_LIBS=$BOOST_THREAD_WIN32_LIBS
+ ;;
+ (*)
+ BOOST_FIND_LIB([thread], [$1],
+ [boost/thread.hpp], [boost::thread t; boost::mutex m;])
+ ;;
+esac
+
+BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag"
+BOOST_THREAD_LDFLAGS="$BOOST_SYSTEM_LDFLAGS"
+BOOST_CPPFLAGS="$BOOST_CPPFLAGS $boost_cv_pthread_flag"
+LIBS=$boost_threads_save_LIBS
+LDFLAGS=$boost_threads_save_LDFLAGS
+CPPFLAGS=$boost_threads_save_CPPFLAGS
+])# BOOST_THREADS
+
+
+# BOOST_TOKENIZER()
+# -----------------
+# Look for Boost.Tokenizer
+BOOST_DEFUN([Tokenizer],
+[BOOST_FIND_HEADER([boost/tokenizer.hpp])])
+
+
+# BOOST_TRIBOOL()
+# ---------------
+# Look for Boost.Tribool
+BOOST_DEFUN([Tribool],
+[BOOST_FIND_HEADER([boost/logic/tribool_fwd.hpp])
+BOOST_FIND_HEADER([boost/logic/tribool.hpp])
+])
+
+
+# BOOST_TUPLE()
+# -------------
+# Look for Boost.Tuple
+BOOST_DEFUN([Tuple],
+[BOOST_FIND_HEADER([boost/tuple/tuple.hpp])])
+
+
+# BOOST_TYPETRAITS()
+# --------------------
+# Look for Boost.TypeTraits
+BOOST_DEFUN([TypeTraits],
+[BOOST_FIND_HEADER([boost/type_traits.hpp])])
+
+
+# BOOST_UTILITY()
+# ---------------
+# Look for Boost.Utility (noncopyable, result_of, base-from-member idiom,
+# etc.)
+BOOST_DEFUN([Utility],
+[BOOST_FIND_HEADER([boost/utility.hpp])])
+
+
+# BOOST_VARIANT()
+# ---------------
+# Look for Boost.Variant.
+BOOST_DEFUN([Variant],
+[BOOST_FIND_HEADER([boost/variant/variant_fwd.hpp])
+BOOST_FIND_HEADER([boost/variant.hpp])])
+
+# BOOST_POINTERCONTAINER()
+# ------------------------
+# Look for Boost.PointerContainer
+BOOST_DEFUN([Pointer_Container],
+[BOOST_FIND_HEADER([boost/ptr_container/ptr_deque.hpp])
+BOOST_FIND_HEADER([boost/ptr_container/ptr_list.hpp])
+BOOST_FIND_HEADER([boost/ptr_container/ptr_vector.hpp])
+BOOST_FIND_HEADER([boost/ptr_container/ptr_array.hpp])
+BOOST_FIND_HEADER([boost/ptr_container/ptr_set.hpp])
+BOOST_FIND_HEADER([boost/ptr_container/ptr_map.hpp])
+])# BOOST_POINTERCONTAINER
+
+# BOOST_WAVE([PREFERRED-RT-OPT])
+# ------------------------------
+# NOTE: If you intend to use Wave/Spirit with thread support, make sure you
+# call BOOST_THREADS first.
+# Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the
+# documentation of BOOST_FIND_LIB above.
+BOOST_DEFUN([Wave],
+[AC_REQUIRE([BOOST_FILESYSTEM])dnl
+AC_REQUIRE([BOOST_DATE_TIME])dnl
+boost_wave_save_LIBS=$LIBS
+boost_wave_save_LDFLAGS=$LDFLAGS
+m4_pattern_allow([^BOOST_((FILE)?SYSTEM|DATE_TIME|THREAD)_(LIBS|LDFLAGS)$])dnl
+LIBS="$LIBS $BOOST_SYSTEM_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_DATE_TIME_LIBS \
+$BOOST_THREAD_LIBS"
+LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS \
+$BOOST_DATE_TIME_LDFLAGS $BOOST_THREAD_LDFLAGS"
+BOOST_FIND_LIB([wave], [$1],
+ [boost/wave.hpp],
+ [boost::wave::token_id id; get_token_name(id);])
+LIBS=$boost_wave_save_LIBS
+LDFLAGS=$boost_wave_save_LDFLAGS
+])# BOOST_WAVE
+
+
+# BOOST_XPRESSIVE()
+# -----------------
+# Look for Boost.Xpressive (new since 1.36.0).
+BOOST_DEFUN([Xpressive],
+[BOOST_FIND_HEADER([boost/xpressive/xpressive.hpp])])
+
+
+# ----------------- #
+# Internal helpers. #
+# ----------------- #
+
+
+# _BOOST_PTHREAD_FLAG()
+# ---------------------
+# Internal helper for BOOST_THREADS. Based on ACX_PTHREAD:
+# http://autoconf-archive.cryp.to/acx_pthread.html
+AC_DEFUN([_BOOST_PTHREAD_FLAG],
+[AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_LANG_PUSH([C++])dnl
+AC_CACHE_CHECK([for the flags needed to use pthreads], [boost_cv_pthread_flag],
+[ boost_cv_pthread_flag=
+ # The ordering *is* (sometimes) important. Some notes on the
+ # individual items follow:
+ # (none): in case threads are in libc; should be tried before -Kthread and
+ # other compiler flags to prevent continual compiler warnings
+ # -lpthreads: AIX (must check this before -lpthread)
+ # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+ # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+ # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
+ # -pthreads: Solaris/GCC
+ # -mthreads: MinGW32/GCC, Lynx/GCC
+ # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+ # doesn't hurt to check since this sometimes defines pthreads too;
+ # also defines -D_REENTRANT)
+ # ... -mt is also the pthreads flag for HP/aCC
+ # -lpthread: GNU Linux, etc.
+ # --thread-safe: KAI C++
+ case $host_os in #(
+ *solaris*)
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+ boost_pthread_flags="-pthreads -lpthread -mt -pthread";; #(
+ *)
+ boost_pthread_flags="-lpthreads -Kthread -kthread -llthread -pthread \
+ -pthreads -mthreads -lpthread --thread-safe -mt";;
+ esac
+ # Generate the test file.
+ AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);])])
+ for boost_pthread_flag in '' $boost_pthread_flags; do
+ boost_pthread_ok=false
+dnl Re-use the test file already generated.
+ boost_pthreads__save_LIBS=$LIBS
+ LIBS="$LIBS $boost_pthread_flag"
+ AC_LINK_IFELSE([],
+ [if grep ".*$boost_pthread_flag" conftest.err; then
+ echo "This flag seems to have triggered warnings" >&AS_MESSAGE_LOG_FD
+ else
+ boost_pthread_ok=:; boost_cv_pthread_flag=$boost_pthread_flag
+ fi])
+ LIBS=$boost_pthreads__save_LIBS
+ $boost_pthread_ok && break
+ done
+])
+AC_LANG_POP([C++])dnl
+])# _BOOST_PTHREAD_FLAG
+
+
+# _BOOST_gcc_test(MAJOR, MINOR)
+# -----------------------------
+# Internal helper for _BOOST_FIND_COMPILER_TAG.
+m4_define([_BOOST_gcc_test],
+["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC @ gcc$1$2"])dnl
+
+
+# _BOOST_FIND_COMPILER_TAG()
+# --------------------------
+# Internal. When Boost is installed without --layout=system, each library
+# filename will hold a suffix that encodes the compiler used during the
+# build. The Boost build system seems to call this a `tag'.
+AC_DEFUN([_BOOST_FIND_COMPILER_TAG],
+[AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_CACHE_CHECK([for the toolset name used by Boost for $CXX], [boost_cv_lib_tag],
+[boost_cv_lib_tag=unknown
+if test x$boost_cv_inc_path != xno; then
+ AC_LANG_PUSH([C++])dnl
+ # The following tests are mostly inspired by boost/config/auto_link.hpp
+ # The list is sorted to most recent/common to oldest compiler (in order
+ # to increase the likelihood of finding the right compiler with the
+ # least number of compilation attempt).
+ # Beware that some tests are sensible to the order (for instance, we must
+ # look for MinGW before looking for GCC3).
+ # I used one compilation test per compiler with a #error to recognize
+ # each compiler so that it works even when cross-compiling (let me know
+ # if you know a better approach).
+ # Known missing tags (known from Boost's tools/build/v2/tools/common.jam):
+ # como, edg, kcc, bck, mp, sw, tru, xlc
+ # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines
+ # the same defines as GCC's).
+ for i in \
+ _BOOST_gcc_test(4, 8) \
+ _BOOST_gcc_test(4, 7) \
+ _BOOST_gcc_test(4, 6) \
+ _BOOST_gcc_test(4, 5) \
+ _BOOST_gcc_test(4, 4) \
+ _BOOST_gcc_test(4, 3) \
+ _BOOST_gcc_test(4, 2) \
+ _BOOST_gcc_test(4, 1) \
+ _BOOST_gcc_test(4, 0) \
+ "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \
+ && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \
+ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \
+ _BOOST_gcc_test(3, 4) \
+ _BOOST_gcc_test(3, 3) \
+ "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \
+ "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \
+ _BOOST_gcc_test(3, 2) \
+ "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \
+ _BOOST_gcc_test(3, 1) \
+ _BOOST_gcc_test(3, 0) \
+ "defined __BORLANDC__ @ bcb" \
+ "defined __ICC && (defined __unix || defined __unix__) @ il" \
+ "defined __ICL @ iw" \
+ "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \
+ _BOOST_gcc_test(2, 95) \
+ "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \
+ "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \
+ "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \
+ "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8"
+ do
+ boost_tag_test=`expr "X$i" : 'X\([[^@]]*\) @ '`
+ boost_tag=`expr "X$i" : 'X[[^@]]* @ \(.*\)'`
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if $boost_tag_test
+/* OK */
+#else
+# error $boost_tag_test
+#endif
+]])], [boost_cv_lib_tag=$boost_tag; break], [])
+ done
+AC_LANG_POP([C++])dnl
+ case $boost_cv_lib_tag in #(
+ # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed
+ # to "gcc41" for instance.
+ *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there.
+ gcc*)
+ boost_tag_x=
+ case $host_os in #(
+ darwin*)
+ if test $boost_major_version -ge 136; then
+ # The `x' added in r46793 of Boost.
+ boost_tag_x=x
+ fi;;
+ esac
+ # We can specify multiple tags in this variable because it's used by
+ # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ...
+ boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc"
+ ;; #(
+ unknown)
+ AC_MSG_WARN([[could not figure out which toolset name to use for $CXX]])
+ boost_cv_lib_tag=
+ ;;
+ esac
+fi])dnl end of AC_CACHE_CHECK
+])# _BOOST_FIND_COMPILER_TAG
+
+
+# _BOOST_GUESS_WHETHER_TO_USE_MT()
+# --------------------------------
+# Compile a small test to try to guess whether we should favor MT (Multi
+# Thread) flavors of Boost. Sets boost_guess_use_mt accordingly.
+AC_DEFUN([_BOOST_GUESS_WHETHER_TO_USE_MT],
+[# Check whether we do better use `mt' even though we weren't ask to.
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if defined _REENTRANT || defined _MT || defined __MT__
+/* use -mt */
+#else
+# error MT not needed
+#endif
+]])], [boost_guess_use_mt=:], [boost_guess_use_mt=false])
+])
+
+# _BOOST_AC_LINK_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# -------------------------------------------------------------------
+# Fork of _AC_LINK_IFELSE that preserves conftest.o across calls. Fragile,
+# will break when Autoconf changes its internals. Requires that you manually
+# rm -f conftest.$ac_objext in between to really different tests, otherwise
+# you will try to link a conftest.o left behind by a previous test.
+# Used to aggressively optimize BOOST_FIND_LIB (see the big comment in this
+# macro).
+#
+# Don't use "break" in the actions, as it would short-circuit some code
+# this macro runs after the actions.
+m4_define([_BOOST_AC_LINK_IFELSE],
+[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl
+rm -f conftest$ac_exeext
+boost_save_ac_ext=$ac_ext
+boost_use_source=:
+# If we already have a .o, re-use it. We change $ac_ext so that $ac_link
+# tries to link the existing object file instead of compiling from source.
+test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false &&
+ _AS_ECHO_LOG([re-using the existing conftest.$ac_objext])
+AS_IF([_AC_DO_STDERR($ac_link) && {
+ test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_executable_p conftest$ac_exeext
+dnl FIXME: use AS_TEST_X instead when 2.61 is widespread enough.
+ }],
+ [$2],
+ [if $boost_use_source; then
+ _AC_MSG_LOG_CONFTEST
+ fi
+ $3])
+ac_objext=$boost_save_ac_objext
+ac_ext=$boost_save_ac_ext
+dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization)
+dnl information created by the PGI compiler (conftest_ipa8_conftest.oo),
+dnl as it would interfere with the next link command.
+rm -f core conftest.err conftest_ipa8_conftest.oo \
+ conftest$ac_exeext m4_ifval([$1], [conftest.$ac_ext])[]dnl
+])# _BOOST_AC_LINK_IFELSE
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..ae311c6
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,97 @@
+# Makefile.am -- automake script for the car plugin
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
+# Copyright (C) 2013 Galois, Inc.
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+# Oregon, 97204-1622.
+
+# We're building a library that gets loaded by dlopen, not a standard .so.
+AM_LDFLAGS = \
+ -avoid-version -module -shared -export-dynamic
+
+lib_LTLIBRARIES = libv_repExtAutomobile.la
+libv_repExtAutomobile_la_SOURCES = \
+ $(srcdir)/automobile.cpp \
+ $(srcdir)/automobile.h \
+ $(srcdir)/csv.cpp \
+ $(srcdir)/csv.h \
+ $(srcdir)/csv-inl.h \
+ $(srcdir)/main.cpp \
+ $(srcdir)/main.h \
+ $(srcdir)/measurement.cpp \
+ $(srcdir)/measurement.h \
+ $(srcdir)/measurement-inl.h \
+ $(srcdir)/noise.cpp \
+ $(srcdir)/noise.h \
+ $(srcdir)/noise-inl.h \
+ $(srcdir)/vrep.cpp \
+ $(srcdir)/vrep.h \
+ $(srcdir)/vrep-inl.h \
+ $(srcdir)/vrepFfi.cpp \
+ $(srcdir)/vrepFfi.h \
+ $(srcdir)/vrepFfi-inl.h
+libv_repExtAutomobile_la_CPPFLAGS = \
+ $(BOOST_CPPFLAGS)
+libv_repExtAutomobile_la_CXXFLAGS = \
+ -Wall \
+ -Wextra \
+ -pedantic \
+ @VREP_CXXFLAGS@
+libv_repExtAutomobile_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -export-symbols-regex '^v_rep' \
+ $(BOOST_FILESYSTEM_LDFLAGS)
+libv_repExtAutomobile_la_LIBADD = \
+ $(BOOST_FILESYSTEM_LIBS)
+
+# In addition to these sources, we also need to bundle a special object built
+# from code in the V-REP distribution. Ideally, I'd just add that source file
+# to 'libv_repExtAutomobile_la_SOURCES', but it's not exactly
+# standards-compliant and generates a ton of warnings. To get around this, use
+# per-object flags emulation (see "Per-Object Flags Emulation" in the Automake
+# manual).
+libv_repExtAutomobile_la_LIBADD += libv_repLib.la
+noinst_LTLIBRARIES = libv_repLib.la
+libv_repLib_la_SOURCES = @VREP@/programming/common/v_repLib.cpp
+libv_repLib_la_CXXFLAGS = @VREP_CXXFLAGS@
+
+# Override install and uninstall targets to stick the libraries in the V-REP
+# directory.
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(VREP)'"; \
+ $(MKDIR_P) "$(VREP)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install --no-warn $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(VREP)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install --no-warn $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(VREP)"; \
+ }
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(VREP)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(VREP)/$$f"; \
+ done
diff --git a/src/automobile.cpp b/src/automobile.cpp
new file mode 100644
index 0000000..365c96b
--- /dev/null
+++ b/src/automobile.cpp
@@ -0,0 +1,403 @@
+/* automobile.cpp -- recording data about the car
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+/* This module assumes only one car is recording data at once. Thus, it follows
+ * a singleton object pattern. To keep everything a bit simpler, the state
+ * variables live in an anonymous namespace, and the functions simply mutate
+ * them as appropriate. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cassert>
+#include <cstdarg>
+
+#include <array>
+#include <fstream>
+#include <functional>
+#include <string>
+#include <vector>
+
+#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
+#include <v_repLib.h>
+
+#include "automobile.h"
+#include "noise.h"
+#include "vrepFfi.h"
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+# include <cassert>
+# include <list>
+#endif
+
+
+namespace {
+
+ // Paths to the output files
+ namespace path {
+
+ std::string dataDir = "/tmp";
+
+ const std::string groundDir = "/ground";
+ const std::string noisyDir = "/noisy";
+
+ const std::string properties = "/properties.csv";
+ const std::string sensor = "/slam_sensor.csv";
+ const std::string pose = "/slam_gps.csv";
+ const std::string control = "/slam_control.csv";
+ const std::string laser = "/slam_laser.csv";
+
+ }
+
+ // Run specifications
+ struct Properties : public csv::Datum {
+ inline Properties(float L, float h, float a, float b, float theta0)
+ : L(L), h(h), a(a), b(b), theta0(theta0) {
+ }
+ inline virtual std::string csvHeader() const;
+ virtual std::string csv() const;
+ inline virtual unsigned int nCols() const;
+ // Distance between front and rear axles
+ float L;
+ // Distance between center of rear axle and encoder on left rear wheel
+ float h;
+ // Lengthwise distance between the rear axle and the lidar
+ float a;
+ // Widthwise distance between the rear axle and the lidar
+ float b;
+ // Initial angle of the car
+ float theta0;
+ };
+
+ // Individual sample records
+ struct Sample : public csv::Datum {
+ inline explicit Sample(const Pose &);
+ inline explicit Sample(const ControlSignals &);
+ inline explicit Sample(const LidarDatum &);
+ inline virtual std::string csvHeader() const;
+ inline virtual std::string csv() const;
+ inline virtual unsigned int nCols() const;
+ float time;
+ unsigned short sensorId;
+ };
+
+
+ // Lidar specifications //
+ namespace laser {
+
+ float MAX_DISTANCE = 10.;
+ float MAX_INTENSITY = 32768.;
+
+ }
+
+
+ // Noise //
+ namespace noise {
+
+ bool requested = false;
+
+ // Dummy noise source that provides no noise
+ GaussianNoiseSource<float> none(0., 0.);
+
+ // Noise sources for the various measurements (can be set via Lua)
+ boost::optional<GaussianNoiseSource<float>> position;
+ boost::optional<GaussianNoiseSource<float>> angle;
+ boost::optional<GaussianNoiseSource<float>> speed;
+ boost::optional<GaussianNoiseSource<float>> steeringAngle;
+ boost::optional<GaussianNoiseSource<float>> distance;
+ boost::optional<GaussianNoiseSource<float>> intensity;
+
+ }
+
+
+ // Prototypes //
+
+ // Lua callbacks
+ typedef simVoid LuaFunc(SLuaCallBack *);
+ LuaFunc init;
+ LuaFunc setNoiseParameters;
+ LuaFunc savePose;
+ LuaFunc saveControls;
+ LuaFunc saveLaser;
+
+ inline void savePropertiesFile(const Properties &);
+
+ template<typename CsvDatum>
+ inline void saveDatum(const std::string &subdir,
+ const std::string &filename, const CsvDatum &);
+
+ void outputDatum(const std::string &filePath, const csv::Datum &);
+
+}
+
+
+// Registering //
+
+void registerLuaFunctions() {
+ vrep::exposeFunction<
+ std::string,
+ float,
+ float,
+ float,
+ float,
+ float,
+ float,
+ float>(
+ "simExtAutomobileInit",
+ "simExtAutomobileInit(string directoryName, number L, number h, number a, number b, number theta0, number max_distance, number max_intensity)",
+ init);
+ vrep::exposeFunction<
+ std::vector<float>, // x and y
+ std::vector<float>, // angle
+ std::vector<float>, // speed
+ std::vector<float>, // steering angle
+ std::vector<float>, // distance
+ std::vector<float>>( // intensity
+ "simExtAutomobileRequestNoise",
+ "simExtAutomobileRequestNoise(table2 xy, table2 angle, table2 speed, table2 steeringAngle, table2 distance, table2 intensity)",
+ setNoiseParameters);
+ vrep::exposeFunction<float, float, float, float>(
+ "simExtAutomobileSavePose",
+ "simExtAutomobileSavePose(number simulationTime, number x, number y, number theta)",
+ savePose);
+ vrep::exposeFunction<float, float, float>(
+ "simExtAutomobileSaveControls",
+ "simExtAutomobileSaveControls(number simulationTime, number speed, number steeringAngle)",
+ saveControls);
+ /* V-REP's depth sensor part has a maximum field of view narrower than 180
+ * degrees. To compensate, we instead use two 90-degree depth sensors and
+ * combine the results here. */
+ vrep::exposeFunction<
+ float,
+ std::vector<float>, std::vector<float>, // depths
+ std::vector<float>, std::vector<float>>( // grayscale images
+ "simExtAutomobileSaveLaserPair",
+ "simExtAutomobileSaveLaserPair(number simulationTime, table leftDepthBuffer, table rightDepthBuffer, table leftImage, table rightImage)",
+ saveLaser);
+}
+
+
+// Callbacks //
+namespace {
+
+ std::string Properties::csvHeader() const {
+# ifdef HAVE_CXX11_INITIALIZER_LISTS
+ return csv::fromContainer(
+ std::vector<std::string> {"L", "h", "a", "b", "InitialAngle"});
+# else
+ return csv::fromContainer(
+ makeList<const char *>(nCols(), "L", "h", "a", "b",
+ "InitialAngle"));
+# endif
+ }
+
+ std::string Properties::csv() const {
+# ifdef HAVE_CXX11_INITIALIZER_LISTS
+ return csv::fromContainer(
+ std::vector<float> {L, h, a, b, theta0});
+# else
+ return csv::fromContainer(
+ makeList<float>(nCols(), L, h, a, b, theta0));
+# endif
+ }
+
+ unsigned int Properties::nCols() const {
+ return 5;
+ }
+
+ Sample::Sample(const Pose &pose)
+ : time(pose.time), sensorId(1) {
+ }
+
+ Sample::Sample(const ControlSignals &signals)
+ : time(signals.time), sensorId(2) {
+ }
+
+ Sample::Sample(const LidarDatum &datum)
+ : time(datum.time), sensorId(3) {
+ }
+
+ std::string Sample::csvHeader() const {
+ return "Time,Sensor";
+ }
+
+ std::string Sample::csv() const {
+ return std::to_string(time) + "," + std::to_string(sensorId);
+ }
+
+ unsigned int Sample::nCols() const {
+ return 2;
+ }
+
+ simVoid init(SLuaCallBack *const simCall) {
+ // Clean data from previous runs.
+ boost::filesystem::remove_all(path::dataDir + path::groundDir);
+ boost::filesystem::remove_all(path::dataDir + path::noisyDir);
+ boost::filesystem::remove(path::dataDir + path::properties);
+ // Save the passed directory as the base directory for the output.
+ vrep::LuaCall call(simCall);
+ path::dataDir = call.expectAtom<std::string>();
+ // Save the passed properties in the properties file.
+ const float L = call.expectAtom<float>();
+ const float h = call.expectAtom<float>();
+ const float a = call.expectAtom<float>();
+ const float b = call.expectAtom<float>();
+ const float theta0 = call.expectAtom<float>();
+ savePropertiesFile(Properties(L, h, a, b, theta0));
+ // Save the maximum distance and intensity settings.
+ laser::MAX_DISTANCE = call.expectAtom<float>();
+ laser::MAX_INTENSITY = call.expectAtom<float>();
+ // Reset the noise settings.
+ noise::requested = false;
+ const std::array<boost::optional<GaussianNoiseSource<float>> *const, 6> sources =
+ {{&noise::position, &noise::angle, &noise::speed,
+ &noise::steeringAngle, &noise::intensity, &noise::distance}};
+ for (boost::optional<GaussianNoiseSource<float>> *const source : sources) {
+ *source = boost::none;
+ }
+ }
+
+ simVoid setNoiseParameters(SLuaCallBack *const simCall) {
+ vrep::LuaCall call(simCall);
+ const std::array<boost::optional<GaussianNoiseSource<float>> *const, 6> sources =
+ {{&noise::position, &noise::angle, &noise::speed,
+ &noise::steeringAngle, &noise::intensity, &noise::distance}};
+ for (boost::optional<GaussianNoiseSource<float>> *const source : sources) {
+ *source = gaussian(call.expectTable<float>());
+ }
+ noise::requested = true;
+ }
+
+ simVoid savePose(SLuaCallBack *const simCall) {
+ // Build the pose.
+ vrep::LuaCall call(simCall);
+ const float time = call.expectAtom<float>();
+ const float x = call.expectAtom<float>();
+ const float y = call.expectAtom<float>();
+ const float theta = call.expectAtom<float>();
+ const Pose pose(time, x, y, theta);
+ // Record it.
+ saveDatum(path::groundDir, path::pose, pose);
+ if (noise::requested) {
+ saveDatum(path::noisyDir, path::pose,
+ addNoise(pose, noise::position.get_value_or(noise::none),
+ noise::angle.get_value_or(noise::none)));
+ }
+ }
+
+ simVoid saveControls(SLuaCallBack *const simCall) {
+ // Build the control systems object.
+ vrep::LuaCall call(simCall);
+ const float time = call.expectAtom<float>();
+ const float speed = call.expectAtom<float>();
+ const float angle = call.expectAtom<float>();
+ const ControlSignals signals(time, speed, angle);
+ // Record it.
+ saveDatum(path::groundDir, path::control, signals);
+ if (noise::requested) {
+ saveDatum(path::noisyDir, path::control,
+ addNoise(signals, noise::speed.get_value_or(noise::none),
+ noise::steeringAngle.get_value_or(noise::none)));
+ }
+ }
+
+ simVoid saveLaser(SLuaCallBack *const simCall) {
+ // Get the arguments and reconstruct the full lidar measurements.
+ vrep::LuaCall call(simCall);
+ const float time = call.expectAtom<float>();
+ std::vector<float> distance = call.expectTable<float>();
+ const std::vector<float> distanceRight = call.expectTable<float>();
+ distance.insert(distance.end(),
+ distanceRight.begin(), distanceRight.end());
+ std::vector<float> image = call.expectTable<float>();
+ const std::vector<float> imageRight = call.expectTable<float>();
+ image.insert(image.end(), imageRight.begin(), imageRight.end());
+ // Process the lidar measurements.
+# ifdef HAVE_CXX11_CLOSURES
+ std::for_each(distance.begin(), distance.end(),
+ [](float &d) { d *= laser::MAX_DISTANCE; });
+ std::for_each(image.begin(), image.end(),
+ [](float &i) { i *= laser::MAX_INTENSITY; });
+# else
+ for (float &d : distance) {
+ d *= laser::MAX_DISTANCE;
+ }
+ for (float &i : image) {
+ i *= laser::MAX_INTENSITY;
+ }
+# endif
+ // Build the lidar datum and record it.
+ const LidarDatum datum(time, distance, image);
+ saveDatum(path::groundDir, path::laser, datum);
+ if (noise::requested) {
+ saveDatum(path::noisyDir, path::laser,
+ addNoise(datum, noise::distance.get_value_or(noise::none),
+ noise::intensity.get_value_or(noise::none)));
+ }
+ }
+
+ void savePropertiesFile(const Properties &properties) {
+ boost::filesystem::create_directories(path::dataDir);
+ outputDatum(path::dataDir + path::properties, properties);
+ }
+
+ template<typename CsvDatum>
+ void saveDatum(const std::string &subdir, const std::string &filename,
+ const CsvDatum &datum) {
+ const std::string logDir = path::dataDir + subdir;
+ boost::filesystem::create_directories(logDir);
+ outputDatum(logDir + filename, datum);
+ outputDatum(logDir + path::sensor, Sample(datum));
+ }
+
+ void outputDatum(const std::string &filePath, const csv::Datum &datum) {
+ const std::string header = datum.csvHeader();
+ std::fstream file(filePath,
+ std::ios::in | std::ios::out | std::ios::app);
+ // Ensure we're writing correctly-formatted data.
+ std::string firstLine;
+ std::getline(file, firstLine);
+ if (file.eof() && firstLine.empty()) {
+ // The file was empty, so write in the header.
+ file.clear();
+ file << header << std::endl;
+ } else if (firstLine != header) {
+ /* The file was nonempty, but the first line did not match the
+ * expected header. This might occur if an external program
+ * modifies the file in between our writes, but more likely, we've
+ * got a bug somewhere that is causing us to write different data
+ * sets to the same file. */
+ throw std::logic_error(
+ std::string("CSV header mismatch: expected `")
+ + header
+ + "', but got `"
+ + firstLine
+ + "'");
+ } else {
+ /* The file was nonempty, and the headers matched what we expected.
+ * We're good to go. */
+ }
+ // Write the datum.
+ file << datum.csv() << std::endl;
+ }
+
+}
diff --git a/src/automobile.h b/src/automobile.h
new file mode 100644
index 0000000..0d3d2c1
--- /dev/null
+++ b/src/automobile.h
@@ -0,0 +1,30 @@
+/* automobile.h -- recording data about the car
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_AUTOMOBILE_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_AUTOMOBILE_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+void registerLuaFunctions();
+
+#endif
diff --git a/src/csv-inl.h b/src/csv-inl.h
new file mode 100644
index 0000000..c1b7cb9
--- /dev/null
+++ b/src/csv-inl.h
@@ -0,0 +1,58 @@
+/* csv-inl.h -- CSV utilities
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_CSV_INL_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_CSV_INL_H
+
+namespace csv {
+
+ template<typename SequenceContainer>
+ std::string fromContainer(const SequenceContainer &columns) {
+ std::ostringstream line;
+ for (typename SequenceContainer::const_iterator col = columns.begin();
+ col != columns.end();
+ col++) {
+ if (col != columns.begin()) {
+ line << ",";
+ }
+ line << *col;
+ }
+ return line.str();
+ }
+
+}
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+
+ template<typename T>
+ std::list<T> makeList(typename std::list<T>::size_type size, ...) {
+ std::list<T> result;
+ va_list args;
+ va_start(args, size);
+ for (typename std::list<T>::size_type i = 0; i < size; i++) {
+ result.push_back(va_arg(args, T));
+ }
+ va_end(args);
+ return result;
+ }
+
+#endif
+
+#endif
diff --git a/src/csv.cpp b/src/csv.cpp
new file mode 100644
index 0000000..88d08b3
--- /dev/null
+++ b/src/csv.cpp
@@ -0,0 +1,48 @@
+/* csv.h -- CSV utilities
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+# include <cstdarg>
+# include <list>
+# include <sstream>
+#endif
+
+#include "csv.h"
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+
+ std::list<float> makeList(typename std::list<float>::size_type size, ...) {
+ std::list<float> result;
+ va_list args;
+ va_start(args, size);
+ for (typename std::list<double>::size_type i = 0;
+ i < static_cast<std::list<double>::size_type>(size);
+ i++) {
+ result.push_back(va_arg(args, double));
+ }
+ va_end(args);
+ return result;
+ }
+
+#endif
diff --git a/src/csv.h b/src/csv.h
new file mode 100644
index 0000000..fd46646
--- /dev/null
+++ b/src/csv.h
@@ -0,0 +1,71 @@
+/* csv.h -- CSV utilities
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_CSV_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_CSV_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string>
+#include <sstream>
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+# include <cstdarg>
+# include <list>
+#endif
+
+namespace csv {
+
+ // Interface: Any datum which can be converted to a CSV string.
+ struct Datum {
+ virtual std::string csvHeader() const = 0;
+ virtual std::string csv() const = 0;
+ virtual unsigned int nCols() const = 0;
+ };
+
+ /* Converts a sequence of objects to a CSV string. It uses stringstreams
+ * internally, so all data in the sequence will get converted to strings
+ * using operator<<; however, no escaping will occur. */
+ template<typename SequenceContainer>
+ std::string fromContainer(const SequenceContainer &);
+
+}
+
+#ifndef HAVE_CXX11_INITIALIZER_LISTS
+
+ /* Without C++11 initializer list syntax, creating containers to pass to
+ * csv::fromContainer is really ugly. This function makes it substantially
+ * nicer, at the cost of forcing you to manually specify the length of the
+ * container (an unfortunate varargs limitation). */
+ template<typename T>
+ std::list<T> makeList(typename std::list<T>::size_type, ...);
+
+ /* floats get promoted to doubles in a va_list, so they need special
+ * handling. */
+ template<>
+ std::list<float> makeList(typename std::list<float>::size_type, ...);
+
+#endif
+
+#include "csv-inl.h"
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..6deb436
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,137 @@
+/* main.cpp -- plugin entry points
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cstddef>
+
+#include <exception>
+#include <stdexcept>
+#include <string>
+
+#include <boost/filesystem.hpp>
+#include <v_repLib.h>
+
+#include "automobile.h"
+#include "main.h"
+#include "vrep.h"
+#include "vrepFfi.h"
+
+namespace {
+
+ const unsigned char PLUGIN_VERSION = 1;
+
+ // The V-REP library that will get loaded at runtime
+ const std::string VREP_LIBRARY_NAME = "libv_rep.so";
+ LIBRARY vrepLibrary;
+
+
+ // Prototypes //
+
+ /* The library we think we're loading might not actually be the right
+ * library. */
+ class BadLibraryError : public std::runtime_error {
+ public:
+ explicit inline BadLibraryError();
+ };
+
+ // We might be using a too-old V-REP.
+ class TooOldVrepError : public std::runtime_error {
+ public:
+ explicit inline TooOldVrepError(const simInt version);
+ };
+
+ /* Loads the V-REP library and ensures it has the correct set of symbols.
+ * Throws 'std::exception' if an error occurs. */
+ // This function is declared inline because it is only used once.
+ inline void loadAndValidateVrepLibrary();
+
+ /* Throws 'std::exception' if the current version of V-REP is strictly less
+ than the 'simInt' passed. */
+ // This function is declared inline because it is only used once.
+ inline void requireVrepVersion(const simInt);
+}
+
+unsigned char v_repStart(void *, int) {
+ try {
+ loadAndValidateVrepLibrary();
+ // If we needed a specific version of V-REP, we'd check it here with
+ // 'requireVrepVersion'.
+ vrep::InterfaceLockGuard lockInterface;
+ // Register functions.
+ registerLuaFunctions();
+ // Returning zero indicates a failure condition.
+ static_assert(PLUGIN_VERSION != 0, "Plugin version must be nonzero");
+ return PLUGIN_VERSION;
+ } catch (const std::exception& error) {
+ // Loading the plugin failed. Return 0 to indicate failure.
+ return 0;
+ }
+}
+
+void v_repEnd() {
+ unloadVrepLibrary(vrepLibrary);
+}
+
+void *v_repMessage(int, int *, void *, int *) {
+ return nullptr;
+}
+
+namespace {
+
+ void loadAndValidateVrepLibrary() {
+ try {
+ // Load the V-REP library out of the V-REP directory.
+ const std::string vrepLibraryPath =
+ boost::filesystem::current_path().string()
+ + "/" + VREP_LIBRARY_NAME;
+ vrepLibrary = loadVrepLibrary(vrepLibraryPath.c_str());
+ // Make sure we can actually get code out of the V-REP library.
+ if (getVrepProcAddresses(vrepLibrary) == 0) {
+ throw BadLibraryError();
+ }
+ } catch (const std::exception& e) {
+ // Problems occurred loading the library; unload it before leaving.
+ unloadVrepLibrary(vrepLibrary);
+ throw e;
+ }
+ }
+
+ void requireVrepVersion(const simInt expected) {
+ simInt actual;
+ VREP(simGetIntegerParameter(sim_intparam_program_version, &actual));
+ if (actual < expected) {
+ throw TooOldVrepError(expected);
+ }
+ }
+
+ BadLibraryError::BadLibraryError()
+ : std::runtime_error("could not find all required functions in "
+ + VREP_LIBRARY_NAME) {
+ }
+
+ TooOldVrepError::TooOldVrepError(const simInt version)
+ : std::runtime_error("plugin requires V-REP >= "
+ + std::to_string(version)) {
+ }
+
+}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000..4960210
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,44 @@
+/* main.h -- main plugin interface
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_MAIN_H_
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_MAIN_H_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* This interface is defined by V-REP itself. See
+ * <http://www.coppeliarobotics.com/helpFiles/en/plugins.htm>. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ unsigned char v_repStart(void *pointer, int integer);
+ void v_repEnd();
+ void *v_repMessage(int message, int *auxiliary_data, void *custom_data,
+ int *reply_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/measurement-inl.h b/src/measurement-inl.h
new file mode 100644
index 0000000..9762cd1
--- /dev/null
+++ b/src/measurement-inl.h
@@ -0,0 +1,62 @@
+/* measurement-inl.h -- data sets we gather
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_MEASUREMENT_INL_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_MEASUREMENT_INL_H
+
+std::string Pose::csvHeader() const {
+ return csvHeader_;
+}
+
+std::string Pose::csv() const {
+# ifdef HAVE_CXX11_INITIALIZER_LISTS
+ return csv::fromContainer(std::vector<float> {time, y, x, theta});
+# else
+ return csv::fromContainer(makeList<float>(nCols(), time, y, x, theta));
+# endif
+}
+
+unsigned int Pose::nCols() const {
+ return 4;
+}
+
+std::string ControlSignals::csvHeader() const {
+ return csvHeader_;
+}
+
+std::string ControlSignals::csv() const {
+# ifdef HAVE_CXX11_INITIALIZER_LISTS
+ return csv::fromContainer(
+ std::vector<float> {time, speed, steeringAngle});
+# else
+ return csv::fromContainer(
+ makeList<float>(nCols(), time, speed, steeringAngle));
+# endif
+}
+
+unsigned int ControlSignals::nCols() const {
+ return 3;
+}
+
+unsigned int LidarDatum::nCols() const {
+ return 1 + distance.size() + intensity.size();
+}
+
+#endif
diff --git a/src/measurement.cpp b/src/measurement.cpp
new file mode 100644
index 0000000..bcf20c3
--- /dev/null
+++ b/src/measurement.cpp
@@ -0,0 +1,68 @@
+/* measurement.cpp -- data sets we gather
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <array>
+#include <string>
+#include <vector>
+
+#include "csv.h"
+#include "measurement.h"
+
+const std::string Pose::csvHeader_ = "TimeGPS,GPSLat,GPSLon,Orientation";
+
+const std::string ControlSignals::csvHeader_ = "Time_VS,Velocity,Steering";
+
+std::string LidarDatum::csvHeader() const {
+ std::string result;
+ const std::string timeLaserHeader = "TimeLaser";
+ const std::string distanceHeader = "Laser";
+ const std::string intensityHeader = "Intensity";
+ result.reserve(timeLaserHeader.size()
+ + distance.size() * (1 + distanceHeader.size())
+ + intensity.size() * (1 + intensityHeader.size()));
+ result.append(timeLaserHeader);
+ for (std::vector<float>::size_type i = 0; i < distance.size(); i++) {
+ result.append(",");
+ result.append(distanceHeader);
+ }
+ for (std::vector<float>::size_type i = 0; i < intensity.size(); i++) {
+ result.append(",");
+ result.append(intensityHeader);
+ }
+ return result;
+}
+
+std::string LidarDatum::csv() const {
+ std::string result = std::to_string(time);
+ /* Yes, there are double braces in the initializer on the next line. See
+ * <http://stackoverflow.com/questions/11400090>. */
+ const std::array<std::vector<float>, 2> dataSets = {{distance, intensity}};
+ for (const std::vector<float> &data : dataSets) {
+ if (! data.empty()) {
+ result.append(",");
+ result.append(csv::fromContainer(data));
+ }
+ }
+ return result;
+}
diff --git a/src/measurement.h b/src/measurement.h
new file mode 100644
index 0000000..bad199c
--- /dev/null
+++ b/src/measurement.h
@@ -0,0 +1,93 @@
+/* measurement.h -- data sets we gather
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_MEASUREMENT_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_MEASUREMENT_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "csv.h"
+
+// Base class for time-series data
+struct Datum {
+ inline Datum(float time)
+ : time(time) {
+ }
+ float time;
+};
+
+
+// Datum definitions //
+
+class Pose : public Datum, public csv::Datum {
+public:
+ inline Pose(float time, float x, float y, float theta)
+ : ::Datum(time), x(x), y(y), theta(theta) {
+ }
+ float x;
+ float y;
+ float theta;
+ inline virtual std::string csvHeader() const;
+ inline virtual std::string csv() const;
+ inline virtual unsigned int nCols() const;
+
+protected:
+ static const std::string csvHeader_;
+};
+
+
+class ControlSignals : public Datum, public csv::Datum {
+public:
+ inline ControlSignals(float time, float speed, float steeringAngle)
+ : ::Datum(time), speed(speed), steeringAngle(steeringAngle) {
+ }
+ float speed;
+ float steeringAngle;
+ inline virtual std::string csvHeader() const;
+ inline virtual std::string csv() const;
+ inline virtual unsigned int nCols() const;
+
+protected:
+ static const std::string csvHeader_;
+};
+
+
+class LidarDatum : public Datum, public csv::Datum {
+public:
+ inline LidarDatum(float time, std::vector<float> distance,
+ std::vector<float> intensity)
+ : ::Datum(time), distance(distance), intensity(intensity) {
+ }
+ std::vector<float> distance;
+ std::vector<float> intensity;
+ virtual std::string csvHeader() const;
+ inline virtual std::string csv() const;
+ inline virtual unsigned int nCols() const;
+};
+
+
+#include "measurement-inl.h"
+
+#endif
diff --git a/src/noise-inl.h b/src/noise-inl.h
new file mode 100644
index 0000000..5013a3c
--- /dev/null
+++ b/src/noise-inl.h
@@ -0,0 +1,51 @@
+/* noise-inl.h -- noisy data
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_NOISE_INL_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_NOISE_INL_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+template<typename RealType>
+GaussianNoiseSource<RealType>::GaussianNoiseSource(RealType mean,
+ RealType stddev)
+ : generator(), distribution(mean, stddev) {
+ generator.seed(std::random_device()());
+}
+
+template<typename RealType>
+RealType GaussianNoiseSource<RealType>::get() {
+ return distribution(generator);
+}
+
+GaussianNoiseSource<float> gaussian(const std::vector<float> params) {
+ if (params.size() != 2) {
+ throw std::invalid_argument(std::string()
+ + "expected two-element vector of distribution parameters "
+ + "(got " + std::to_string(params.size()) + "-element "
+ + "vector instead");
+ } else {
+ return GaussianNoiseSource<float>(params[0], params[1]);
+ }
+}
+
+#endif
diff --git a/src/noise.cpp b/src/noise.cpp
new file mode 100644
index 0000000..bee0224
--- /dev/null
+++ b/src/noise.cpp
@@ -0,0 +1,73 @@
+/* noise.h -- noisy data
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CXX11_CLOSURES
+# include <algorithm>
+#endif
+
+#include "measurement.h"
+#include "noise.h"
+
+Pose addNoise(const Pose &pose,
+ GaussianNoiseSource<float> &positionNoise,
+ GaussianNoiseSource<float> &angleNoise) {
+ Pose result = pose;
+ result.x += positionNoise.get();
+ result.y += positionNoise.get();
+ result.theta += angleNoise.get();
+ return result;
+}
+
+ControlSignals addNoise(const ControlSignals &signals,
+ GaussianNoiseSource<float> &speedNoise,
+ GaussianNoiseSource<float> &steeringAngleNoise) {
+ ControlSignals result = signals;
+ result.speed += speedNoise.get();
+ result.steeringAngle += steeringAngleNoise.get();
+ return result;
+}
+
+LidarDatum addNoise(const LidarDatum &datum,
+ GaussianNoiseSource<float> &distanceNoise,
+ GaussianNoiseSource<float> &intensityNoise) {
+ LidarDatum result = datum;
+# ifdef HAVE_CXX11_CLOSURES
+ std::for_each(result.distance.begin(), result.distance.end(),
+ [&distanceNoise](float &d) {
+ d += distanceNoise.get();
+ });
+ std::for_each(result.intensity.begin(), result.intensity.end(),
+ [&intensityNoise](float &i) {
+ i += intensityNoise.get();
+ });
+# else
+ for (float &d : result.distance) {
+ d += distanceNoise.get();
+ }
+ for (float &i : result.intensity) {
+ i += intensityNoise.get();
+ }
+# endif
+ return result;
+}
diff --git a/src/noise.h b/src/noise.h
new file mode 100644
index 0000000..e0b9980
--- /dev/null
+++ b/src/noise.h
@@ -0,0 +1,72 @@
+/* noise.h -- noisy data
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_NOISE_H
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_NOISE_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <random>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "csv.h"
+#include "measurement.h"
+
+
+// Noise sources //
+
+template<typename RealType = double>
+class GaussianNoiseSource {
+public:
+ inline GaussianNoiseSource(RealType mean, RealType stddev);
+ inline RealType get();
+
+private:
+ std::mt19937 generator;
+ std::normal_distribution<RealType> distribution;
+};
+
+/* Convenience function to construct a GaussianNoiseSource<float> from a
+ * two-element float vector representing mean and standard deviation.
+ * Throws a std::invalid_argument if the vector is of the wrong
+ * length. */
+inline GaussianNoiseSource<float> gaussian(const std::vector<float>);
+
+
+// Noisy values //
+
+// Adds noise to a value.
+Pose addNoise(const Pose &, GaussianNoiseSource<float> &positionNoise,
+ GaussianNoiseSource<float> &angleNoise);
+ControlSignals addNoise(const ControlSignals &,
+ GaussianNoiseSource<float> &speedNoise,
+ GaussianNoiseSource<float> &steeringAngleNoise);
+LidarDatum addNoise(const LidarDatum &,
+ GaussianNoiseSource<float> &distanceNoise,
+ GaussianNoiseSource<float> &intensityNoise);
+
+
+#include "noise-inl.h"
+
+#endif
diff --git a/src/vrep-inl.h b/src/vrep-inl.h
new file mode 100644
index 0000000..84d8ef0
--- /dev/null
+++ b/src/vrep-inl.h
@@ -0,0 +1,118 @@
+/* vrep-inl.h -- convenience code to interface with V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_VREP_INL_H_
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_VREP_INL_H_
+
+namespace vrep {
+
+ // class InterfaceLockGuard
+
+ InterfaceLockGuard::InterfaceLockGuard() {
+ lock();
+ }
+
+ InterfaceLockGuard::InterfaceLockGuard(const InterfaceLockGuard &other) {
+ copyState(other);
+ }
+
+ InterfaceLockGuard &InterfaceLockGuard::operator=(
+ const InterfaceLockGuard &other) {
+ copyState(other);
+ return *this;
+ }
+
+ InterfaceLockGuard::InterfaceLockGuard(InterfaceLockGuard &&other) {
+ moveState(other);
+ }
+
+ InterfaceLockGuard &InterfaceLockGuard::operator=(
+ InterfaceLockGuard &&other) {
+ moveState(other);
+ return *this;
+ }
+
+ void InterfaceLockGuard::lock() {
+ VREP(simLockInterface(true));
+ isLocked = true;
+ }
+
+ void InterfaceLockGuard::unlock() {
+ VREP(simLockInterface(false));
+ isLocked = false;
+ }
+
+
+ // class Error
+
+ Error::Error(const std::string &whatArg)
+ : std::runtime_error(whatArg) {
+ }
+
+ Error::Error(const char *whatArg)
+ : Error(std::string(whatArg)) {
+ }
+
+
+ // template<typename T> class FunctionError<T>
+
+ template<typename T>
+ FunctionError<T>::FunctionError(const std::string &invocation,
+ const T result)
+ : Error("V-REP function invocation "
+ + invocation
+ + " failed, returning "
+ + std::to_string(result)) {
+ }
+
+ template<typename T>
+ FunctionError<T>::FunctionError(const char *invocation, const T result)
+ : FunctionError(std::string(invocation), result) {
+ }
+
+
+ // template<typename T> T checkFunction(T, const char[])
+
+ template<typename T>
+ T checkFunction(T result, const char invocation[]) {
+ if (isSuccess(result)) {
+ return result;
+ } else {
+ throw vrep::FunctionError<T>(invocation, result);
+ }
+ }
+
+
+ // template<typename T> bool isSuccess(const T)
+
+ template<>
+ bool isSuccess(const simInt val) {
+ return val != -1;
+ }
+
+ template<>
+ bool isSuccess(const simVoid *const val) {
+ return val != nullptr;
+ }
+
+}
+
+#endif
+
diff --git a/src/vrep.cpp b/src/vrep.cpp
new file mode 100644
index 0000000..2043b45
--- /dev/null
+++ b/src/vrep.cpp
@@ -0,0 +1,72 @@
+/* vrep.cpp -- convenience code to interface with V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdexcept>
+#include <string>
+
+#include <v_repLib.h>
+
+#include "vrep.h"
+
+namespace vrep {
+
+ InterfaceLockGuard::~InterfaceLockGuard() noexcept {
+ if (isLocked) {
+ /* Throwing an exception from a destructor is a bad, bad idea. See
+ * /More Effective C++/ #14. */
+ try {
+ unlock();
+ } catch (const Error& error) {
+ /* Unlocking failed, so we're kind of screwed at this point. We
+ * can't even display a dialog to the user noting the failure,
+ * because the interface is locked! *sigh* Just give up and do
+ * nothing. */
+ }
+ }
+ }
+
+ void InterfaceLockGuard::copyState(const InterfaceLockGuard &other) {
+ if (isLocked) {
+ unlock();
+ }
+ if (other.isLocked) {
+ lock();
+ } else {
+ isLocked = false;
+ }
+ }
+
+ void InterfaceLockGuard::moveState(InterfaceLockGuard &other) {
+ if (isLocked) {
+ unlock();
+ }
+ if (other.isLocked) {
+ lock();
+ other.unlock();
+ } else {
+ isLocked = false;
+ }
+ }
+
+}
diff --git a/src/vrep.h b/src/vrep.h
new file mode 100644
index 0000000..7a1bac0
--- /dev/null
+++ b/src/vrep.h
@@ -0,0 +1,104 @@
+/* vrep.h -- convenience code to interface with V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_VREP_H_
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_VREP_H_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cstddef>
+
+#include <stdexcept>
+#include <string>
+
+#include <v_repLib.h>
+
+/* All the convenience code lives in the 'vrep' namespace to distinguish it from
+ * the actual V-REP functions, which all are prefixed with 'sim'. */
+namespace vrep {
+
+ // A RAII wrapper for 'simLockInterface'.
+ class InterfaceLockGuard {
+ public:
+ inline InterfaceLockGuard();
+ ~InterfaceLockGuard() noexcept;
+ // Copying
+ inline InterfaceLockGuard(const InterfaceLockGuard &);
+ inline InterfaceLockGuard &operator=(const InterfaceLockGuard &);
+ // Moving
+ inline InterfaceLockGuard(InterfaceLockGuard &&);
+ inline InterfaceLockGuard &operator=(InterfaceLockGuard &&);
+
+ private:
+ inline void lock();
+ inline void unlock();
+ void copyState(const InterfaceLockGuard &);
+ void moveState(InterfaceLockGuard &);
+
+ bool isLocked;
+ };
+
+
+ // Error handling //
+
+ // The class for all errors which occur when interfacing with V-REP.
+ class Error : public std::runtime_error {
+ public:
+ explicit inline Error(const std::string &whatArg);
+ explicit inline Error(const char *whatArg);
+ };
+
+ // An error signaling a failed V-REP function invocation.
+ template<typename T>
+ class FunctionError : public Error {
+ public:
+ FunctionError(const std::string &invocation, const T result);
+ inline FunctionError(const char *invocation, const T result);
+ };
+
+/* A nice macro to convert failed V-REP function invocations to
+ * 'FunctionError's. Simply wrap your V-REP function interface--e.g.,
+ *
+ * simInt x = VREP(simGetIntegerParameter(foo, &bar));
+ *
+ * --and you'll be off to the races. 'x' will be assigned the result of the
+ * invocation if and only if the invocation succeeded; otherwise, a
+ * 'FunctionError' describing the failed invocation will be thrown.
+ *
+ * This needs to be a macro so that it can include the code of the failed
+ * invocation itself. */
+#define VREP(invocation) vrep::checkFunction((invocation), #invocation)
+
+ template<typename T>
+ T checkFunction(T result, const char invocation[]);
+
+ /* Returns 'true' iff the passed value signifies a successful V-REP function
+ * invocation. */
+ template<typename T>
+ inline bool isSuccess(const T);
+ template<> inline bool isSuccess(const simInt);
+ template<> inline bool isSuccess(const simVoid *);
+}
+
+#include "vrep-inl.h"
+
+#endif
diff --git a/src/vrepFfi-inl.h b/src/vrepFfi-inl.h
new file mode 100644
index 0000000..554d954
--- /dev/null
+++ b/src/vrepFfi-inl.h
@@ -0,0 +1,133 @@
+/* vrepFfi-inl.h -- exposing functions to V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_VREPFFI_INL_H_
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_VREPFFI_INL_H_
+
+namespace vrep {
+
+ namespace {
+
+ // Converting a variadic template type to a Lua type list //
+
+ std::forward_list<int> toLuaTypes() {
+ return std::forward_list<int>();
+ }
+
+ template<typename Car>
+ std::forward_list<int> toLuaTypes() {
+ std::forward_list<int> luaTypes = toLuaTypes();
+ luaTypes.push_front(LuaType<Car>::id);
+ return luaTypes;
+ }
+
+ template<typename Car, typename Cadr, typename ...Cddr>
+ std::forward_list<int> toLuaTypes() {
+ std::forward_list<int> luaTypes = toLuaTypes<Cadr, Cddr...>();
+ luaTypes.push_front(LuaType<Car>::id);
+ return luaTypes;
+ }
+
+ }
+
+
+ // Exposing C++ functions to Lua //
+
+ template<typename ...Args>
+ void exposeFunction(const std::string name, const std::string callTips,
+ simVoid (*const f)(SLuaCallBack *)) {
+ // Compute the Lua signature.
+ std::vector<int> luaTypes;
+ luaTypes.push_back(0);
+ for (int type : toLuaTypes<Args...>()) {
+ luaTypes.push_back(type);
+ // We just added an argument.
+ luaTypes[0]++;
+ }
+ // Register the function with Lua.
+ VREP(simRegisterCustomLuaFunction(name.c_str(), callTips.c_str(),
+ luaTypes.data(), f));
+ }
+
+
+ // Extracting Lua arguments from the callback structure //
+
+ template<typename T>
+ T LuaCall::expectAtom() {
+ ensureNextArgType(LuaType<T>::id);
+ const T result = unsafeGetAtom<T>();
+ argIdx++;
+ return result;
+ }
+
+ template<typename T>
+ std::vector<T> LuaCall::expectTable() {
+ ensureNextArgType(LuaType<std::vector<T>>::id);
+ const std::vector<T> result = unsafeGetTable<T>();
+ argIdx++;
+ return result;
+ }
+
+ template<typename T>
+ std::vector<T> LuaCall::unsafeGetTable() {
+ // Determine how long the table is.
+ size_t tableLen;
+ if (simCall->inputArgTypeAndSize[2 * argIdx] & sim_lua_arg_table) {
+ tableLen = simCall->inputArgTypeAndSize[2 * argIdx + 1];
+ } else {
+ tableLen = 1;
+ }
+ // Build the result.
+ std::vector<T> result(tableLen);
+ for (size_t i = 0; i < tableLen; i++) {
+ result[i] = unsafeGetAtom<T>();
+ }
+ return result;
+ }
+
+ template<>
+ bool LuaCall::unsafeGetAtom() {
+ return *cursorBool++;
+ }
+
+ template<>
+ int LuaCall::unsafeGetAtom() {
+ return *cursorInt++;
+ }
+
+ template<>
+ float LuaCall::unsafeGetAtom() {
+ return *cursorFloat++;
+ }
+
+
+ // Error handling //
+
+ MarshalingError::MarshalingError(const std::string &whatArg)
+ : Error(whatArg) {
+ }
+
+ MarshalingError::MarshalingError(const char *whatArg)
+ : MarshalingError(std::string(whatArg)) {
+ }
+
+}
+
+#endif
diff --git a/src/vrepFfi.cpp b/src/vrepFfi.cpp
new file mode 100644
index 0000000..4641bbf
--- /dev/null
+++ b/src/vrepFfi.cpp
@@ -0,0 +1,68 @@
+/* vrepFfi.cpp -- exposing functions to V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cstring>
+
+#include <string>
+
+#include "vrepFfi.h"
+
+namespace vrep {
+
+ // Extracting Lua arguments from the callback structure //
+
+ LuaCall::LuaCall(SLuaCallBack *simCall)
+ : simCall(simCall), argIdx(0), cursorBool(simCall->inputBool),
+ cursorInt(simCall->inputInt), cursorFloat(simCall->inputFloat),
+ cursorChar(simCall->inputChar) {
+ }
+
+ void LuaCall::ensureNextArgType(const int expected) {
+ const int nextType = simCall->inputArgTypeAndSize[2 * argIdx];
+ if (nextType != expected) {
+ throw MarshalingError("unexpected Lua argument (expected type "
+ + std::to_string(expected)
+ + ", got type "
+ + std::to_string(nextType)
+ + ")");
+ }
+ }
+
+ template<>
+ std::string LuaCall::unsafeGetAtom() {
+ // Determine how long the string is. Lua uses '@' as its sentinel.
+ size_t len;
+ simChar *sentinel = std::strchr(cursorChar, '@');
+ if (sentinel) {
+ len = sentinel - cursorChar;
+ } else {
+ len = std::strlen(cursorChar);
+ }
+ // Build the 'std::string'.
+ const std::string result = std::string(cursorChar, len);
+ cursorChar += len + (sentinel ? 1 : 0);
+ return result;
+ }
+
+}
diff --git a/src/vrepFfi.h b/src/vrepFfi.h
new file mode 100644
index 0000000..0dbab1e
--- /dev/null
+++ b/src/vrepFfi.h
@@ -0,0 +1,158 @@
+/* vrepFfi.h -- exposing functions to V-REP
+ * Copyright (C) 2013 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+ * or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+ * Oregon, 97204-1622. */
+
+#ifndef PPAML_VREP_AUTOMOBILE_PLUGIN_VREPFFI_H_
+#define PPAML_VREP_AUTOMOBILE_PLUGIN_VREPFFI_H_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <cstddef>
+#include <cstring>
+
+#include <forward_list>
+#include <string>
+#include <vector>
+
+#include <v_repLib.h>
+
+#include "vrep.h"
+
+namespace vrep {
+
+ namespace {
+
+ // C-Lua type equivalences //
+
+ template<typename T, int idVal>
+ struct LuaTypeWrapper {
+ static const int id = idVal;
+ static inline T isNextArg(const SLuaCallBack *);
+ };
+
+ template<typename T>
+ struct LuaType;
+
+ template<>
+ struct LuaType<std::nullptr_t>
+ : public LuaTypeWrapper<std::nullptr_t, sim_lua_arg_nil> {
+ };
+
+ template<>
+ struct LuaType<bool> : public LuaTypeWrapper<bool, sim_lua_arg_bool> {
+ typedef simBool LuaT;
+ };
+
+ template<>
+ struct LuaType<int> : public LuaTypeWrapper<int, sim_lua_arg_int> {
+ typedef simInt LuaT;
+ };
+
+ template<>
+ struct LuaType<float>
+ : public LuaTypeWrapper<float, sim_lua_arg_float> {
+ typedef simFloat LuaT;
+ };
+
+ template<>
+ struct LuaType<std::string>
+ : public LuaTypeWrapper<std::string, sim_lua_arg_string> {
+ typedef simChar LuaT;
+ };
+
+ template<typename U>
+ struct LuaType<std::vector<U>>
+ : public LuaTypeWrapper<std::vector<U>,
+ sim_lua_arg_table | LuaType<U>::id> {
+ typedef typename LuaType<U>::LuaT LuaT;
+ };
+
+
+ // Converting a variadic template type to a Lua type list //
+
+ std::forward_list<int> toLuaTypes();
+
+ template<typename Car>
+ std::forward_list<int> toLuaTypes();
+
+ template<typename Car, typename Cadr, typename ...Cddr>
+ std::forward_list<int> toLuaTypes();
+ }
+
+
+ // Exposing C++ functions to Lua //
+
+ template<typename ...Args>
+ void exposeFunction(const std::string name, const std::string callTips,
+ simVoid (*const f)(SLuaCallBack *));
+
+
+ // Extracting Lua arguments from the callback structure //
+
+ /* A class layered on 'SLuaCallBack' for handling calls from Lua into C++.
+ * Watch out--interacting with this class at all outside of a C++ function
+ * exposed to Lua will almost certainly cause undefined behavior! */
+ class LuaCall {
+ public:
+ LuaCall(SLuaCallBack *);
+
+ template<typename T>
+ T expectAtom();
+
+ template<typename T>
+ std::vector<T> expectTable();
+
+ private:
+ void ensureNextArgType(const int expected);
+
+ template<typename T>
+ T unsafeGetAtom();
+
+ template<typename T>
+ std::vector<T> unsafeGetTable();
+
+ SLuaCallBack *const simCall;
+ size_t argIdx;
+ simBool *cursorBool;
+ simInt *cursorInt;
+ simFloat *cursorFloat;
+ simChar *cursorChar;
+ };
+ template<> inline bool LuaCall::unsafeGetAtom();
+ template<> inline int LuaCall::unsafeGetAtom();
+ template<> inline float LuaCall::unsafeGetAtom();
+ template<> std::string LuaCall::unsafeGetAtom();
+
+
+ // Error handling //
+
+ // An error signaling a failed marshal from Lua to C++.
+ class MarshalingError : public Error {
+ public:
+ explicit inline MarshalingError(const std::string &whatArg);
+ explicit inline MarshalingError(const char *whatArg);
+ };
+
+}
+
+#include "vrepFfi-inl.h"
+
+#endif