diff --git a/.gitignore b/.gitignore
index 0810cc53..17107d8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*~
*.*~
*.*#
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 58d4f11c..613cc56f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,89 +6,15 @@ project(microstrain_3dm_gx5_45)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
- #serial
+ tf2
+ tf2_ros
+ std_msgs
+ std_srvs
+ geometry_msgs
+ sensor_msgs
+ nav_msgs
)
-## System dependencies are found with CMake's conventions
-# find_package(Boost REQUIRED COMPONENTS system)
-
-
-## Uncomment this if the package has a setup.py. This macro ensures
-## modules and global scripts declared therein get installed
-## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
-# catkin_python_setup()
-
-################################################
-## Declare ROS messages, services and actions ##
-################################################
-
-## To declare and build messages, services or actions from within this
-## package, follow these steps:
-## * Let MSG_DEP_SET be the set of packages whose message types you use in
-## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
-## * In the file package.xml:
-## * add a build_depend tag for "message_generation"
-## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
-## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
-## but can be declared for certainty nonetheless:
-## * add a run_depend tag for "message_runtime"
-## * In this file (CMakeLists.txt):
-## * add "message_generation" and every package in MSG_DEP_SET to
-## find_package(catkin REQUIRED COMPONENTS ...)
-## * add "message_runtime" and every package in MSG_DEP_SET to
-## catkin_package(CATKIN_DEPENDS ...)
-## * uncomment the add_*_files sections below as needed
-## and list every .msg/.srv/.action file to be processed
-## * uncomment the generate_messages entry below
-## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
-
-## Generate messages in the 'msg' folder
-# add_message_files(
-# FILES
-# Message1.msg
-# Message2.msg
-# )
-
-## Generate services in the 'srv' folder
-# add_service_files(
-# FILES
-# Service1.srv
-# Service2.srv
-# )
-
-## Generate actions in the 'action' folder
-# add_action_files(
-# FILES
-# Action1.action
-# Action2.action
-# )
-
-## Generate added messages and services with any dependencies listed here
-# generate_messages(
-# DEPENDENCIES
-# std_msgs # Or other packages containing msgs
-# )
-
-################################################
-## Declare ROS dynamic reconfigure parameters ##
-################################################
-
-## To declare and build dynamic reconfigure parameters within this
-## package, follow these steps:
-## * In the file package.xml:
-## * add a build_depend and a run_depend tag for "dynamic_reconfigure"
-## * In this file (CMakeLists.txt):
-## * add "dynamic_reconfigure" to
-## find_package(catkin REQUIRED COMPONENTS ...)
-## * uncomment the "generate_dynamic_reconfigure_options" section below
-## and list every .cfg file to be processed
-
-## Generate dynamic reconfigure parameters in the 'cfg' folder
-# generate_dynamic_reconfigure_options(
-# cfg/DynReconf1.cfg
-# cfg/DynReconf2.cfg
-# )
-
###################################
## catkin specific configuration ##
###################################
@@ -99,18 +25,25 @@ find_package(catkin REQUIRED COMPONENTS
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
- INCLUDE_DIRS include
- CATKIN_DEPENDS roscpp
+ INCLUDE_DIRS
+ include
+ CATKIN_DEPENDS
+ roscpp
+ cmake_modules
+ tf2
+ tf2_ros
+ std_msgs
+ std_srvs
+ geometry_msgs
+ sensor_msgs
+ nav_msgs
)
###########
## Build ##
###########
-## Specify additional locations of header files
-## Your package locations should be listed before other locations
-
-# Directories containing MIP header files
+# Directories containing MIP SDK header files
set(MIPLIBINC MIPSDK/C/Library/Include)
set(MIPLIBSRC MIPSDK/C/Library/Source)
set(MIPUTILINC MIPSDK/C/Utilities/Include)
@@ -122,8 +55,6 @@ set(MIPUTILSRC MIPSDK/C/Utilities/Source)
# set(MIPUSR "MIPSDK/C/Library/User\ Functions")
#include_directories(include ${MIPLIBINC} ${MIPUTILINC} ${MIPUSR})
include_directories(include/${PROJECT_NAME} ${MIPLIBINC} ${MIPUTILINC} ${catkin_INCLUDE_DIRS})
-# Include the ROS serial headers
-#include_directories(${serial_INCLUDE_DIRS})
set(MIPINC
${MIPLIBINC}/mip.h
@@ -153,26 +84,16 @@ set(MIPSRC
${MIPUTILSRC}/byteswap_utilities.c
)
-## Declare a C++ library
-# add_library(microstrain_3dm_gx5_45
-# src/${PROJECT_NAME}/microstrain_3dm_gx5_45.cpp
-# )
-
-## Add cmake target dependencies of the library
-## as an example, code may need to be generated before libraries
-## either from message generation or dynamic reconfigure
-# add_dependencies(microstrain_3dm_gx5_45 ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
-
-## Declare a C++ executable
-# add_executable(microstrain_3dm_gx5_45_node src/microstrain_3dm_gx5_45_node.cpp)
-add_executable(GX4-45_Test
- src/GX4-45_Test.c
+# Libraries
+add_library(microstrain_3dm_gx5_45
+ src/microstrain_3dm_gx5_45.cpp
src/mip_sdk_user_functions.c
${MIPSRC}
)
-add_library(microstrain_3dm_gx5_45
- src/microstrain_3dm_gx5_45.cpp
+# Executables
+add_executable(GX4-45_Test
+ src/GX4-45_Test.c
src/mip_sdk_user_functions.c
${MIPSRC}
)
@@ -180,28 +101,17 @@ add_executable(microstrain_3dm_gx5_45_node
src/microstrain_3dm_gx5_45_node.cpp
)
+# Linking
+target_link_libraries(GX4-45_Test rt)
target_link_libraries(microstrain_3dm_gx5_45
${catkin_LIBRARIES}
)
-
target_link_libraries(microstrain_3dm_gx5_45_node
microstrain_3dm_gx5_45
${catkin_LIBRARIES}
)
-#target_link_libraries(GX4-45_Test_node ${serial_LIBRARIES} rt pthread)
-
-#${MIPINC}
-## Add cmake target dependencies of the executable
-## same as for the library above
-# add_dependencies(microstrain_3dm_gx5_45_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
-
-## Specify libraries to link a library or executable target against
-# target_link_libraries(microstrain_3dm_gx5_45_node
-# ${catkin_LIBRARIES}
-# )
-
#############
## Install ##
#############
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..58956999
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,685 @@
+All code within the microstrain_3dm_gx5_45 package that was developed by Brian Bingham is released under the GPL license:
+
+Copyright (c) 2016, Brian Bingham
+All rights reserved.
+
+================================================================================
+
+The microstrain_3dm_gx5_45 package makes use of the MIP SDK written by Lord Microstrain Sensing Systems. The source files for the MIP SDK are included with their copyright and licnese statements.
+
+================================================================================
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ 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.
+
+
+ Copyright (C)
+
+ 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 .
+
+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:
+
+ Copyright (C)
+ 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
+.
+
+ 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
+.
diff --git a/README.md b/README.md
index 23780249..b0022810 100644
--- a/README.md
+++ b/README.md
@@ -4,4 +4,5 @@
Interface software, including ROS node, for Microstrain 3DM-GX5-45.
+
See http://wiki.ros.org/microstrain_3dm_gx5_45
diff --git a/config/custom_rosconsole.conf b/config/custom_rosconsole.conf
index 47a09375..bf0e6678 100644
--- a/config/custom_rosconsole.conf
+++ b/config/custom_rosconsole.conf
@@ -3,5 +3,5 @@
# ROSCONSOLE_CONFIG_FILE (in your environment) to point to the new file
#
log4j.logger.ros=INFO
-log4j.logger.ros.geonav_transform=DEBUG
+log4j.logger.ros.microstrain_3dm_gx5_45=DEBUG
log4j.logger.ros.roscpp.superdebug=WARN
\ No newline at end of file
diff --git a/include/microstrain_3dm_gx5_45/microstrain_3dm_gx5_45.h b/include/microstrain_3dm_gx5_45/microstrain_3dm_gx5_45.h
index 4f9057ae..865ac980 100644
--- a/include/microstrain_3dm_gx5_45/microstrain_3dm_gx5_45.h
+++ b/include/microstrain_3dm_gx5_45/microstrain_3dm_gx5_45.h
@@ -1,6 +1,27 @@
/** ROS node
- *
- */
+
+/*
+
+Copyright (c) 2017, Brian Bingham
+All rights reserved
+
+This file is part of the microstrain_3dm_gx5_45 package.
+
+microstrain_3dm_gx5_45 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.
+
+microstrain_3dm_gx5_45 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 Foobar. If not, see .
+
+*/
+
#ifndef _MICROSTRAIN_3DM_GX5_45_H
#define _MICROSTRAIN_3DM_GX5_45_H
@@ -77,8 +98,6 @@ namespace Microstrain
void print_packet_stats();
// Variables/fields
- u8 enable_data_stats_output_;
-
//The primary device interface structure
mip_interface device_interface_;
@@ -128,8 +147,12 @@ namespace Microstrain
std_msgs::Int16MultiArray nav_status_msg_;
std::string gps_frame_id_;
std::string imu_frame_id_;
- std::string nav_frame_id_;
-
+ std::string odom_frame_id_;
+ std::string odom_child_frame_id_;
+ bool publish_gps_;
+ bool publish_imu_;
+ bool publish_odom_;
+
// Update rates
int nav_rate_;
int imu_rate_;
diff --git a/launch/microstrain.launch b/launch/microstrain.launch
index a854c8fe..2243bea4 100644
--- a/launch/microstrain.launch
+++ b/launch/microstrain.launch
@@ -13,15 +13,28 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package.xml b/package.xml
index b02840da..6230ec4f 100644
--- a/package.xml
+++ b/package.xml
@@ -1,51 +1,25 @@
-
+
microstrain_3dm_gx5_45
- 0.0.0
- The microstrain_3dm_gx5_45 package
+ 0.0.1
+ The microstrain_3dm_gx5_45 package provides a driver for the LORD/Microstrain 3DM_GXx_45 GPS-aided IMU sensor.
+ Brian Bingham -->
+ Brian Bingham
+ GPL
+ http://wiki.ros.org/microstrain_3dm_gx5_45
-
-
-
- bsb
-
-
-
-
-
- TODO
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
catkin
- roscpp
- serial
- roscpp
+ roscpp
+ cmake_modules
+ tf2
+ tf2_ros
+ std_msgs
+ std_srvs
+ geometry_msgs
+ sensor_msgs
+ nav_msgs
-
diff --git a/src/microstrain_3dm_gx5_45.cpp b/src/microstrain_3dm_gx5_45.cpp
index 2aeb4886..b9d8fad5 100644
--- a/src/microstrain_3dm_gx5_45.cpp
+++ b/src/microstrain_3dm_gx5_45.cpp
@@ -1,11 +1,33 @@
+/*
+
+Copyright (c) 2017, Brian Bingham
+All rights reserved
+
+This file is part of the microstrain_3dm_gx5_45 package.
+
+microstrain_3dm_gx5_45 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.
+
+microstrain_3dm_gx5_45 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 Foobar. If not, see .
+
+*/
+
#include "microstrain_3dm_gx5_45.h"
+#include
#include
namespace Microstrain
{
Microstrain::Microstrain():
// Initialization list
- enable_data_stats_output_(0),
filter_valid_packet_count_(0),
ahrs_valid_packet_count_(0),
gps_valid_packet_count_(0),
@@ -17,7 +39,11 @@ namespace Microstrain
gps_checksum_error_packet_count_(0),
gps_frame_id_("gps_frame"),
imu_frame_id_("imu_frame"),
- nav_frame_id_("nav_frame")
+ odom_frame_id_("odom_frame"),
+ odom_child_frame_id_("odom_frame"),
+ publish_gps_(true),
+ publish_imu_(true),
+ publish_odom_(true)
{
// pass
}
@@ -27,8 +53,23 @@ namespace Microstrain
}
void Microstrain::run()
{
- // Variables
+ // Variables for device configuration, ROS parameters, etc.
u32 com_port, baudrate;
+ bool device_setup = false;
+ bool readback_settings = true;
+ bool save_settings = true;
+ bool auto_init = true;
+ u8 auto_init_u8 = 1;
+ u8 readback_auto_init = 0;
+ u8 dynamics_mode = 0;
+ u8 readback_dynamics_mode = 0;
+ int declination_source;
+ u8 declination_source_u8;
+ u8 readback_declination_source;
+ double declination;
+
+ // Variables
+ tf2::Quaternion quat;
base_device_info_field device_info;
u8 temp_string[20] = {0};
u32 bit_result;
@@ -54,12 +95,9 @@ namespace Microstrain
float hard_iron_readback[3] = {0};
float soft_iron[9] = {0};
float soft_iron_readback[9] = {0};
- u8 dynamics_mode = 0;
- u8 readback_dynamics_mode = 0;
u16 estimation_control = 0, estimation_control_readback = 0;
u8 gps_source = 0;
u8 heading_source = 0;
- u8 auto_init = 0;
float noise[3] = {0};
float readback_noise[3] = {0};
float beta[3] = {0};
@@ -76,9 +114,6 @@ namespace Microstrain
mip_filter_zero_update_command zero_update_control, zero_update_readback;
mip_filter_external_heading_with_time_command external_heading_with_time;
mip_complementary_filter_settings comp_filter_command, comp_filter_readback;
- int declination_source;
- double declination;
- u8 declination_source_command, declination_source_readback;
mip_filter_accel_magnitude_error_adaptive_measurement_command accel_magnitude_error_command, accel_magnitude_error_readback;
mip_filter_magnetometer_magnitude_error_adaptive_measurement_command mag_magnitude_error_command, mag_magnitude_error_readback;
@@ -90,14 +125,18 @@ namespace Microstrain
ros::NodeHandle private_nh("~");
// ROS Parameters
+ // Comms Parameters
std::string port;
int baud, pdyn_mode;
private_nh.param("port", port, std::string("/dev/ttyACM0"));
private_nh.param("baudrate",baud,115200);
baudrate = (u32)baud;
- private_nh.param("gps_frame_id",gps_frame_id_, std::string("world"));
- private_nh.param("imu_frame_id",gps_frame_id_, std::string("sensor"));
- private_nh.param("nav_frame_id",gps_frame_id_, std::string("world"));
+ // Configuration Parameters
+ private_nh.param("device_setup",device_setup,false);
+ private_nh.param("readback_settings",readback_settings,true);
+ private_nh.param("save_settings",save_settings,true);
+
+ private_nh.param("auto_init",auto_init,true);
private_nh.param("gps_rate",gps_rate_, 1);
private_nh.param("imu_rate",imu_rate_, 10);
private_nh.param("nav_rate",nav_rate_, 10);
@@ -111,63 +150,41 @@ namespace Microstrain
if (declination_source < 1 || declination_source > 3){
ROS_WARN("declination_source can't be %d, must be 1, 2 or 3. Setting to 2.",declination_source);
declination_source = 2;
- }
- declination_source_command=(u8)declination_source;
+ }
+ declination_source_u8 = (u8)declination_source;
+ //declination_source_command=(u8)declination_source;
private_nh.param("declination",declination,0.23);
-
- // Publishers and subscribers
- gps_pub_ = node.advertise("gps/fix",100);
- imu_pub_ = node.advertise("imu/data",100);
- nav_pub_ = node.advertise("nav/odom",100);
- nav_status_pub_ = node.advertise("nav/status",100);
+ private_nh.param("gps_frame_id",gps_frame_id_, std::string("wgs84"));
+ private_nh.param("imu_frame_id",imu_frame_id_, std::string("base_link"));
+ private_nh.param("odom_frame_id",odom_frame_id_, std::string("wgs84"));
+ private_nh.param("odom_child_frame_id",odom_child_frame_id_,
+ std::string("base_link"));
+ private_nh.param("publish_gps",publish_gps_, true);
+ private_nh.param("publish_imu",publish_imu_, true);
+ private_nh.param("publish_odom",publish_odom_, true);
+
+ // ROS publishers and subscribers
+ if (publish_gps_)
+ gps_pub_ = node.advertise("gps/fix",100);
+ if (publish_imu_)
+ imu_pub_ = node.advertise("imu/data",100);
+ if (publish_odom_)
+ {
+ nav_pub_ = node.advertise("nav/odom",100);
+ nav_status_pub_ = node.advertise("nav/status",100);
+ }
ros::ServiceServer service = node.advertiseService("reset_kf", &Microstrain::reset_callback, this);
- //Initialize the interface to the device
+
+ //Initialize the serial interface to the device
ROS_INFO("Attempting to open serial port <%s> at <%d> \n",
port.c_str(),baudrate);
if(mip_interface_init(port.c_str(), baudrate, &device_interface_, DEFAULT_PACKET_TIMEOUT_MS) != MIP_INTERFACE_OK){
- ROS_ERROR("Couldn't open port!");
+ ROS_FATAL("Couldn't open serial port! Is it plugged in?");
}
- float dT=1.0; // common sleep time after communications
- /* Setup and test Comms */
- // Put device into standard mode
- ROS_INFO("Put device into standard comms mode");
- device_descriptors_size = 128*2;
- com_mode = MIP_SDK_GX4_45_IMU_STANDARD_MODE;
- while(mip_system_com_mode(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &com_mode) != MIP_INTERFACE_OK){}
- //Verify device mode setting
- while(mip_system_com_mode(&device_interface_, MIP_FUNCTION_SELECTOR_READ, &com_mode) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- if(com_mode != MIP_SDK_GX4_45_IMU_STANDARD_MODE)
- {
- ROS_ERROR("Appears we didn't get into standard mode!");
- }
-
- // Put into idle mode
- ROS_INFO("Idling Device");
- while(mip_base_cmd_idle(&device_interface_) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
-
- // Get supported descriptors
- /*
- while(mip_base_cmd_get_device_supported_descriptors(&device_interface_, (u8*)device_descriptors, &device_descriptors_size) != MIP_INTERFACE_OK){}
-
- std::printf("\n\nSupported descriptors:\n\n");
-
- for(i=0; i< device_descriptors_size/2; i++)
- {
- std::printf("Descriptor Set: %02x, Descriptor: %02x\n", device_descriptors[i] >> 8, device_descriptors[i]&0xFF);
- Sleep(100);
- }
-
- std::printf("\n\n");
- Sleep(1500);
- */
-
-
- // Setup callbacks
+ // Setup device callbacks
if(mip_interface_add_descriptor_set_callback(&device_interface_, MIP_FILTER_DATA_SET, this, &filter_packet_callback_wrapper) != MIP_INTERFACE_OK)
{
ROS_FATAL("Can't setup filter callback!");
@@ -178,148 +195,264 @@ namespace Microstrain
ROS_FATAL("Can't setup callbacks!");
return;
}
-
if(mip_interface_add_descriptor_set_callback(&device_interface_, MIP_GPS_DATA_SET, this, &gps_packet_callback_wrapper) != MIP_INTERFACE_OK)
{
ROS_FATAL("Can't setup callbacks!");
return;
}
- // Get rates
- while(mip_3dm_cmd_get_ahrs_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
- ROS_INFO("AHRS Base Rate => %d Hz", base_rate);
- ros::Duration(dT).sleep();
- // Deterimine decimation to get close to goal rate
- u8 imu_decimation = (u8)((float)base_rate/ (float)imu_rate_);
-
- while(mip_3dm_cmd_get_gps_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
- ROS_INFO("GPS Base Rate => %d Hz", base_rate);
- u8 gps_decimation = (u8)((float)base_rate/ (float)gps_rate_);
- ros::Duration(dT).sleep();
-
- while(mip_3dm_cmd_get_filter_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
- ROS_INFO("FILTER Base Rate => %d Hz", base_rate);
- u8 nav_decimation = (u8)((float)base_rate/ (float)nav_rate_);
- ros::Duration(dT).sleep();
-
- // Set message formats
- enable_data_stats_output_ = 1;
- ROS_INFO("Setting the AHRS message format");
- data_stream_format_descriptors[0] = MIP_AHRS_DATA_ACCEL_SCALED;
- data_stream_format_descriptors[1] = MIP_AHRS_DATA_GYRO_SCALED;
- data_stream_format_descriptors[2] = MIP_AHRS_DATA_QUATERNION;
- data_stream_format_decimation[0] = imu_decimation;//0x32;
- data_stream_format_decimation[1] = imu_decimation;//0x32;
- data_stream_format_decimation[2] = imu_decimation;//0x32;
- data_stream_format_num_entries = 3;
- while(mip_3dm_cmd_ahrs_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries, data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- ROS_INFO("Poll AHRS data to verify");
- while(mip_3dm_cmd_poll_ahrs(&device_interface_, MIP_3DM_POLLING_ENABLE_ACK_NACK, data_stream_format_num_entries, data_stream_format_descriptors) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- ROS_INFO(" ");
-
-
- ROS_INFO("Setting GPS stream format");
- data_stream_format_descriptors[0] = MIP_GPS_DATA_LLH_POS;
- data_stream_format_descriptors[1] = MIP_GPS_DATA_NED_VELOCITY;
- data_stream_format_descriptors[2] = MIP_GPS_DATA_GPS_TIME;
- data_stream_format_decimation[0] = gps_decimation; //0x01; //0x04;
- data_stream_format_decimation[1] = gps_decimation; //0x01; //0x04;
- data_stream_format_decimation[2] = gps_decimation; //0x01; //0x04;
- data_stream_format_num_entries = 3;
- while(mip_3dm_cmd_gps_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries,data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
-
- ROS_INFO("Setting Filter stream format");
- data_stream_format_descriptors[0] = MIP_FILTER_DATA_LLH_POS;
- data_stream_format_descriptors[1] = MIP_FILTER_DATA_NED_VEL;
- //data_stream_format_descriptors[2] = MIP_FILTER_DATA_ATT_EULER_ANGLES;
- data_stream_format_descriptors[2] = MIP_FILTER_DATA_ATT_QUATERNION;
- data_stream_format_descriptors[3] = MIP_FILTER_DATA_POS_UNCERTAINTY;
- data_stream_format_descriptors[4] = MIP_FILTER_DATA_VEL_UNCERTAINTY;
- data_stream_format_descriptors[5] = MIP_FILTER_DATA_ATT_UNCERTAINTY_EULER;
- data_stream_format_descriptors[6] = MIP_FILTER_DATA_COMPENSATED_ANGULAR_RATE;
- data_stream_format_descriptors[7] = MIP_FILTER_DATA_FILTER_STATUS;
- data_stream_format_decimation[0] = nav_decimation; //0x32;
- data_stream_format_decimation[1] = nav_decimation; //0x32;
- data_stream_format_decimation[2] = nav_decimation; //0x32;
- data_stream_format_decimation[3] = nav_decimation; //0x32;
- data_stream_format_decimation[4] = nav_decimation; //0x32;
- data_stream_format_decimation[5] = nav_decimation; //0x32;
- data_stream_format_decimation[6] = nav_decimation; //0x32;
- data_stream_format_decimation[7] = nav_decimation; //0x32;
- data_stream_format_num_entries = 8;
- while(mip_3dm_cmd_filter_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries,data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- ROS_INFO("Poll filter data to test stream");
- while(mip_3dm_cmd_poll_filter(&device_interface_, MIP_3DM_POLLING_ENABLE_ACK_NACK, data_stream_format_num_entries, data_stream_format_descriptors) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- ROS_INFO(" ");
-
- // Set dynamics mode
- ROS_INFO("Setting dynamics mode to %d",dynamics_mode);
- while(mip_filter_vehicle_dynamics_mode(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &dynamics_mode) != MIP_INTERFACE_OK){}
- // Default mode
- /*
- ROS_INFO("Setting default dynamics mode");
- while(mip_filter_vehicle_dynamics_mode(&device_interface_, MIP_FUNCTION_SELECTOR_LOAD_DEFAULT, NULL) != MIP_INTERFACE_OK){}
+ ////////////////////////////////////////
+ // Device setup
+ float dT=1.0; // common sleep time after setup communications
+ if (device_setup)
+ {
+ // Put device into standard mode - we never really use "direct mode"
+ ROS_INFO("Putting device communications into 'standard mode'");
+ device_descriptors_size = 128*2;
+ com_mode = MIP_SDK_GX4_45_IMU_STANDARD_MODE;
+ while(mip_system_com_mode(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &com_mode) != MIP_INTERFACE_OK){}
+ //Verify device mode setting
+ while(mip_system_com_mode(&device_interface_, MIP_FUNCTION_SELECTOR_READ, &com_mode) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ if(com_mode != MIP_SDK_GX4_45_IMU_STANDARD_MODE)
+ {
+ ROS_ERROR("Appears we didn't get into standard mode!");
+ }
+
+ // Put into idle mode
+ ROS_INFO("Idling Device: Stopping data streams and/or waking from sleep");
+ while(mip_base_cmd_idle(&device_interface_) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+
+ // Get base rates
+ while(mip_3dm_cmd_get_ahrs_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
+ ROS_INFO("AHRS Base Rate => %d Hz", base_rate);
+ ros::Duration(dT).sleep();
+ // Deterimine decimation to get close to goal rate
+ u8 imu_decimation = (u8)((float)base_rate/ (float)imu_rate_);
+
+ while(mip_3dm_cmd_get_gps_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
+ ROS_INFO("GPS Base Rate => %d Hz", base_rate);
+ u8 gps_decimation = (u8)((float)base_rate/ (float)gps_rate_);
+ ros::Duration(dT).sleep();
+
+ while(mip_3dm_cmd_get_filter_base_rate(&device_interface_, &base_rate) != MIP_INTERFACE_OK){}
+ ROS_INFO("FILTER Base Rate => %d Hz", base_rate);
+ u8 nav_decimation = (u8)((float)base_rate/ (float)nav_rate_);
+ ros::Duration(dT).sleep();
+
+ ////////// AHRS Message Format
+ // Set message format
+ ROS_INFO("Setting the AHRS message format");
+ data_stream_format_descriptors[0] = MIP_AHRS_DATA_ACCEL_SCALED;
+ data_stream_format_descriptors[1] = MIP_AHRS_DATA_GYRO_SCALED;
+ data_stream_format_descriptors[2] = MIP_AHRS_DATA_QUATERNION;
+ data_stream_format_decimation[0] = imu_decimation;//0x32;
+ data_stream_format_decimation[1] = imu_decimation;//0x32;
+ data_stream_format_decimation[2] = imu_decimation;//0x32;
+ data_stream_format_num_entries = 3;
+ while(mip_3dm_cmd_ahrs_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries, data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ // Poll to verify
+ ROS_INFO("Poll AHRS data to verify");
+ while(mip_3dm_cmd_poll_ahrs(&device_interface_, MIP_3DM_POLLING_ENABLE_ACK_NACK, data_stream_format_num_entries, data_stream_format_descriptors) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ // Save
+ if (save_settings)
+ {
+ ROS_INFO("Saving AHRS data settings");
+ while(mip_3dm_cmd_ahrs_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_STORE_EEPROM, 0, NULL,NULL) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ }
+
+ ////////// GPS Message Format
+ // Set
+ ROS_INFO("Setting GPS stream format");
+ data_stream_format_descriptors[0] = MIP_GPS_DATA_LLH_POS;
+ data_stream_format_descriptors[1] = MIP_GPS_DATA_NED_VELOCITY;
+ data_stream_format_descriptors[2] = MIP_GPS_DATA_GPS_TIME;
+ data_stream_format_decimation[0] = gps_decimation; //0x01; //0x04;
+ data_stream_format_decimation[1] = gps_decimation; //0x01; //0x04;
+ data_stream_format_decimation[2] = gps_decimation; //0x01; //0x04;
+ data_stream_format_num_entries = 3;
+ while(mip_3dm_cmd_gps_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries,data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ // Save
+ if (save_settings)
+ {
+ ROS_INFO("Saving GPS data settings");
+ while(mip_3dm_cmd_gps_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_STORE_EEPROM, 0, NULL,NULL) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ }
+
+ ////////// Filter Message Format
+ // Set
+ ROS_INFO("Setting Filter stream format");
+ data_stream_format_descriptors[0] = MIP_FILTER_DATA_LLH_POS;
+ data_stream_format_descriptors[1] = MIP_FILTER_DATA_NED_VEL;
+ //data_stream_format_descriptors[2] = MIP_FILTER_DATA_ATT_EULER_ANGLES;
+ data_stream_format_descriptors[2] = MIP_FILTER_DATA_ATT_QUATERNION;
+ data_stream_format_descriptors[3] = MIP_FILTER_DATA_POS_UNCERTAINTY;
+ data_stream_format_descriptors[4] = MIP_FILTER_DATA_VEL_UNCERTAINTY;
+ data_stream_format_descriptors[5] = MIP_FILTER_DATA_ATT_UNCERTAINTY_EULER;
+ data_stream_format_descriptors[6] = MIP_FILTER_DATA_COMPENSATED_ANGULAR_RATE;
+ data_stream_format_descriptors[7] = MIP_FILTER_DATA_FILTER_STATUS;
+ data_stream_format_decimation[0] = nav_decimation; //0x32;
+ data_stream_format_decimation[1] = nav_decimation; //0x32;
+ data_stream_format_decimation[2] = nav_decimation; //0x32;
+ data_stream_format_decimation[3] = nav_decimation; //0x32;
+ data_stream_format_decimation[4] = nav_decimation; //0x32;
+ data_stream_format_decimation[5] = nav_decimation; //0x32;
+ data_stream_format_decimation[6] = nav_decimation; //0x32;
+ data_stream_format_decimation[7] = nav_decimation; //0x32;
+ data_stream_format_num_entries = 8;
+ while(mip_3dm_cmd_filter_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &data_stream_format_num_entries,data_stream_format_descriptors, data_stream_format_decimation) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ // Poll to verify
+ ROS_INFO("Poll filter data to test stream");
+ while(mip_3dm_cmd_poll_filter(&device_interface_, MIP_3DM_POLLING_ENABLE_ACK_NACK, data_stream_format_num_entries, data_stream_format_descriptors) != MIP_INTERFACE_OK){}
ros::Duration(dT).sleep();
- */
+ // Save
+ if (save_settings)
+ {
+ ROS_INFO("Saving Filter data settings");
+ while(mip_3dm_cmd_filter_message_format(&device_interface_, MIP_FUNCTION_SELECTOR_STORE_EEPROM, 0, NULL,NULL) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ }
- // Default auto-init
- ROS_INFO("Setting default auto-init");
- while(mip_filter_auto_initialization(&device_interface_, MIP_FUNCTION_SELECTOR_LOAD_DEFAULT, NULL) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
+ ////////// Dynamics Mode
+ // Set dynamics mode
+ ROS_INFO("Setting dynamics mode to %d",dynamics_mode);
+ while(mip_filter_vehicle_dynamics_mode(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &dynamics_mode) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ // Readback dynamics mode
+ if (readback_settings)
+ {
+ // Read the settings back
+ ROS_INFO("Reading back dynamics mode setting");
+ while(mip_filter_vehicle_dynamics_mode(&device_interface_,
+ MIP_FUNCTION_SELECTOR_READ,
+ &readback_dynamics_mode)
+ != MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
+ if (dynamics_mode == readback_dynamics_mode)
+ ROS_INFO("Success: Dynamics mode setting is: %d",readback_dynamics_mode);
+ else
+ ROS_ERROR("Failure: Dynamics mode set to be %d, but reads as %d",
+ dynamics_mode,readback_dynamics_mode);
+ }
+ if (save_settings)
+ {
+ ROS_INFO("Saving dynamics mode settings to EEPROM");
+ while(mip_filter_vehicle_dynamics_mode(&device_interface_,
+ MIP_FUNCTION_SELECTOR_STORE_EEPROM,
+ NULL) != MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
+ }
- // Set delination
- while(mip_filter_declination_source(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &declination_source_command) != MIP_INTERFACE_OK){}
+ ////////// Auto Initialization
+ // Set auto-initialization based on ROS parameter
+ ROS_INFO("Setting auto-initinitalization to: %d",auto_init);
+ auto_init_u8 = auto_init; // convert bool to u8
+ while(mip_filter_auto_initialization(&device_interface_,
+ MIP_FUNCTION_SELECTOR_WRITE,
+ &auto_init_u8) != MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
- //Read back the declination source
- while(mip_filter_declination_source(&device_interface_, MIP_FUNCTION_SELECTOR_READ, &declination_source_readback) != MIP_INTERFACE_OK){}
- if(declination_source_command == declination_source_readback)
+ if (readback_settings)
{
- ROS_INFO("Declination source successfully set to %d", declination_source_command);
+ // Read the settings back
+ ROS_INFO("Reading back auto-initialization value");
+ while(mip_filter_auto_initialization(&device_interface_,
+ MIP_FUNCTION_SELECTOR_READ,
+ &readback_auto_init)!= MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
+ if (auto_init == readback_auto_init)
+ ROS_INFO("Success: Auto init. setting is: %d",readback_auto_init);
+ else
+ ROS_ERROR("Failure: Auto init. setting set to be %d, but reads as %d",
+ auto_init,readback_auto_init);
}
- else
+ if (save_settings)
{
- ROS_WARN("Failed to set the declination source to %d!", i);
+ ROS_INFO("Saving auto init. settings to EEPROM");
+ while(mip_filter_auto_initialization(&device_interface_,
+ MIP_FUNCTION_SELECTOR_STORE_EEPROM,
+ NULL) != MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
}
-
- // Reset filter
- ROS_INFO("Reset filter");
- while(mip_filter_reset_filter(&device_interface_) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- // Turn off reporting packets to the screen
- enable_data_stats_output_ = 0;
+ ////////// Declination Source
+ // Set declination
+ ROS_INFO("Setting declination source to %d",declination_source_u8);
+ while(mip_filter_declination_source(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, &declination_source_u8) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ //Read back the declination source
+ ROS_INFO("Reading back declination source");
+ while(mip_filter_declination_source(&device_interface_, MIP_FUNCTION_SELECTOR_READ, &readback_declination_source) != MIP_INTERFACE_OK){}
+ if(declination_source_u8 == readback_declination_source)
+ {
+ ROS_INFO("Success: Declination source set to %d", declination_source_u8);
+ }
+ else
+ {
+ ROS_WARN("Failed to set the declination source to %d!", declination_source_u8);
+ }
+ ros::Duration(dT).sleep();
+ if (save_settings)
+ {
+ ROS_INFO("Saving declination source settings to EEPROM");
+ while(mip_filter_declination_source(&device_interface_,
+ MIP_FUNCTION_SELECTOR_STORE_EEPROM,
+ NULL) != MIP_INTERFACE_OK)
+ {}
+ ros::Duration(dT).sleep();
+ }
- // Enable Data streams
- dT = 0.25;
- ROS_INFO("Enabling AHRS stream");
- enable = 0x01;
- while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_AHRS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
- ROS_INFO("Enabling Filter stream");
- enable = 0x01;
- while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_INS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
+ // Reset filter
+ ROS_INFO("Reset filter");
+ while(mip_filter_reset_filter(&device_interface_) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+
- ROS_INFO("Enabling GPS stream");
- enable = 0x01;
- while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_GPS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
- ros::Duration(dT).sleep();
+ // Enable Data streams
+ dT = 0.25;
+ ROS_INFO("Enabling AHRS stream");
+ enable = 0x01;
+ while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_AHRS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+
+ ROS_INFO("Enabling Filter stream");
+ enable = 0x01;
+ while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_INS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+
+ ROS_INFO("Enabling GPS stream");
+ enable = 0x01;
+ while(mip_3dm_cmd_continuous_data_stream(&device_interface_, MIP_FUNCTION_SELECTOR_WRITE, MIP_3DM_GPS_DATASTREAM, &enable) != MIP_INTERFACE_OK){}
+ ros::Duration(dT).sleep();
+ ROS_INFO("End of device setup - starting streaming");
+ }
+ else
+ {
+ ROS_INFO("Skipping device setup and listing for existing streams");
+ } // end of device_setup
+
// Loop
-
ros::Rate r(1000); // Rate in Hz
while (ros::ok()){
//Update the parser (this function reads the port and parses the bytes
mip_interface_update(&device_interface_);
ros::spinOnce(); // take care of service requests.
r.sleep();
-
+
//ROS_INFO("Spinning");
} // end loop
} // End of ::run()
@@ -339,6 +472,9 @@ namespace Microstrain
u8 *field_data;
u16 field_offset = 0;
+ // If we aren't publishing, then return
+ if (!publish_odom_)
+ return;
//ROS_INFO("Filter callback");
//The packet callback can have several types, process them all
switch(callback_type)
@@ -377,7 +513,8 @@ namespace Microstrain
nav_msg_.header.seq = filter_valid_packet_count_;
nav_msg_.header.stamp = ros::Time::now();
- nav_msg_.header.frame_id = nav_frame_id_;
+ nav_msg_.header.frame_id = odom_frame_id_;
+ nav_msg_.child_frame_id = odom_child_frame_id_;
nav_msg_.pose.pose.position.y = curr_filter_pos_.latitude;
nav_msg_.pose.pose.position.x = curr_filter_pos_.longitude;
nav_msg_.pose.pose.position.z = curr_filter_pos_.ellipsoid_height;
@@ -395,9 +532,20 @@ namespace Microstrain
//For little-endian targets, byteswap the data field
mip_filter_ned_velocity_byteswap(&curr_filter_vel_);
- nav_msg_.twist.twist.linear.x = curr_filter_vel_.east;
- nav_msg_.twist.twist.linear.y = curr_filter_vel_.north;
- nav_msg_.twist.twist.linear.z = -1*curr_filter_vel_.down;
+ // rotate velocities from NED to sensor coordinates
+ tf2::Quaternion nav_quat(curr_filter_quaternion_.q[0],
+ curr_filter_quaternion_.q[1],
+ curr_filter_quaternion_.q[2],
+ curr_filter_quaternion_.q[3]);
+
+ tf2::Vector3 vel_enu(curr_filter_vel_.east,
+ curr_filter_vel_.north,
+ -1.0*curr_filter_vel_.down);
+ tf2::Vector3 vel_in_sensor_frame = tf2::quatRotate(nav_quat,vel_enu);
+
+ nav_msg_.twist.twist.linear.x = vel_in_sensor_frame[0]; //curr_filter_vel_.east;
+ nav_msg_.twist.twist.linear.y = vel_in_sensor_frame[0]; //curr_filter_vel_.north;
+ nav_msg_.twist.twist.linear.z = vel_in_sensor_frame[0]; //-1*curr_filter_vel_.down;
}break;
///
@@ -545,7 +693,9 @@ namespace Microstrain
mip_field_header *field_header;
u8 *field_data;
u16 field_offset = 0;
-
+ // If we aren't publishing, then return
+ if (!publish_imu_)
+ return;
//The packet callback can have several types, process them all
switch(callback_type)
{
@@ -683,6 +833,9 @@ namespace Microstrain
u16 field_offset = 0;
u8 msgvalid = 1; // keep track of message validity
+ // If we aren't publishing, then return
+ if (!publish_gps_)
+ return;
//The packet callback can have several types, process them all
switch(callback_type)
{
@@ -799,12 +952,9 @@ namespace Microstrain
void Microstrain::print_packet_stats()
{
- if(enable_data_stats_output_)
- {
- printf("\r%u FILTER (%u errors) %u AHRS (%u errors) %u GPS (%u errors) Packets", filter_valid_packet_count_, filter_timeout_packet_count_ + filter_checksum_error_packet_count_,
- ahrs_valid_packet_count_, ahrs_timeout_packet_count_ + ahrs_checksum_error_packet_count_,
- gps_valid_packet_count_, gps_timeout_packet_count_ + gps_checksum_error_packet_count_);
- }
+ ROS_DEBUG_THROTTLE(1.0,"%u FILTER (%u errors) %u AHRS (%u errors) %u GPS (%u errors) Packets", filter_valid_packet_count_, filter_timeout_packet_count_ + filter_checksum_error_packet_count_,
+ ahrs_valid_packet_count_, ahrs_timeout_packet_count_ + ahrs_checksum_error_packet_count_,
+ gps_valid_packet_count_, gps_timeout_packet_count_ + gps_checksum_error_packet_count_);
} // print_packet_stats
diff --git a/src/microstrain_3dm_gx5_45_node.cpp b/src/microstrain_3dm_gx5_45_node.cpp
index 629ee135..5af82b2a 100644
--- a/src/microstrain_3dm_gx5_45_node.cpp
+++ b/src/microstrain_3dm_gx5_45_node.cpp
@@ -1,3 +1,25 @@
+/*
+
+Copyright (c) 2017, Brian Bingham
+All rights reserved
+
+This file is part of the microstrain_3dm_gx5_45 package.
+
+microstrain_3dm_gx5_45 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.
+
+microstrain_3dm_gx5_45 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 Foobar. If not, see .
+
+*/
+
/**
* @file microstrain_3dm_gx5_45.cpp
* @author Brian S. Bingham
diff --git a/src/mip_sdk_user_functions.c b/src/mip_sdk_user_functions.c
index 014706d8..e3047df2 100644
--- a/src/mip_sdk_user_functions.c
+++ b/src/mip_sdk_user_functions.c
@@ -74,7 +74,7 @@ u16 mip_sdk_port_open(void **port_handle, const char *portstr, int baudrate)
// Copy portstr argument to port_name
strcat(port_name,portstr);
- printf("Attempting to open port: %s\n",port_name);
+ //printf("Attempting to open port: %s\n",port_name);
//Attempt to open the specified port
local_port_handle = open(port_name, O_RDWR | O_NOCTTY);
@@ -85,7 +85,7 @@ u16 mip_sdk_port_open(void **port_handle, const char *portstr, int baudrate)
return MIP_USER_FUNCTION_ERROR;
}
- printf("Port: %s opened successfully.\n",port_name);
+ //printf("Port: %s opened successfully.\n",port_name);
//Convert specified baud to hardware specific value
switch (baudrate)
diff --git a/wiki_src.txt b/wiki_src.txt
new file mode 100644
index 00000000..0bb71a6b
--- /dev/null
+++ b/wiki_src.txt
@@ -0,0 +1,185 @@
+
+== Overview ==
+
+Interface (driver) software, including ROS node, for Microstrain 3DM-GX5-45.
+
+The interface makes use of the MIP SDK Version 1.1 from Microstrain to communicate with the device. Includes the following applications:
+
+=== Supported Devices ===
+
+== ROS Nodes ==
+{{{
+#!clearsilver CS/NodeAPI
+node.0 {
+ name = microstrain_3dm_gx5_45
+ desc = ROS node that captures IMU/GPS data.
+ pub {
+ 0.name= gps/fix
+ 0.type= sensor_msgs/NavSatFix
+ 0.desc= See [[#gpsmsg|Navsatfix message description]] below.
+ 1.name= imu/data
+ 1.type= sensor_msgs/Imu
+ 1.desc= See [[#imumsg|Imu message description]] below
+ 2.name= nav/odom
+ 2.type= nav_msgs/Odometry
+ 2.desc= See [[#odommsg|Odometry message description]] below
+ 3.name= nav/status
+ 3.type= std_msgs/Int16MultiArray
+ 3.desc= See below [[#navstatusmsg|Nav Status message description]]
+ }
+ srv {
+ 0.name = reset_kf
+ 0.type = std_srvs/Empty
+ 0.desc = Resets the Kalman filter on the device
+ }
+ param {
+ 0.name = port
+ 0.type = string
+ 0.desc = Serial port - Linux only
+ 0.default = /dev/ttyACM0
+ 1.name = baud_rate
+ 1.type = int
+ 1.desc = Baud rate of serial connection
+ 1.default = 115200
+ 2.name= device_setup
+ 2.type= bool
+ 2.desc= If true, puts device in idle mode and configures the device.If false, skips configuration. Important: the configuration parameters below are not effective unless this flag is true.
+ 2.default= true
+ 3.name= readback_settings
+ 3.type= bool
+ 3.desc= coming soon
+ 3.default= true
+ 4.name= auto-init
+ 4.type= bool
+ 4.desc= tbd
+ 4.default= true
+ 5.name=dynamics_mode
+ 5.type=int
+ 5.desc=Vehicle dynamics mode 0x01=Portable, 0x02=Automotive, 0x03=Airborne
+ 5.default = 1
+ 6.name=declination_source
+ 6.type=int
+ 6.desc=Possible declination sources: 0x01=Node, device reports magnetic north, 0x02=Internal World Magnetic Model, 0x03=Manual (see declination parameter)
+ 6.default=2
+ 8.name=gps_frame_id
+ 8.type=string
+ 8.desc= Value for the frame_id field in the header of the NavSatFix message published on the gps/fix topic
+ 8.default=wgs84
+ 9.name=imu_frame_id
+ 9.type=string
+ 9.desc=Value of the frame_id field in the header of the Imu message publised in the imu/data topic
+ 9.default=base_link
+ 10.name=odom_frame_id
+ 10.type=string
+ 10.desc=Value of the frame_id field in the header of the Odometry message published on the nav/odom topic
+ 10.default=wgs84
+ 11.name=odom_child_frame_id
+ 11.type=string
+ 11.desc=Value of the child_frame_id field in the Odometry message published on the nav/odom topic.
+ 11.default=base_link
+ 12.name=publish_gps
+ 12.type=bool
+ 12.desc=Sets if ~gps/fix should be advertised/published or not. Note - to maximize performance you may want to only publish the Odometry messages
+ 12.default=true
+ 13.name=publish_imu
+ 13.type=bool
+ 13.desc= Sets if ~imu/data should be advertised/published or not.
+ 13.default=true
+ 14.name=publish_gps
+ 14.type=bool
+ 14.desc=Sets if ~nav/odom should be advertised/published or not.
+ 14.default=true
+ 15.name=gps_rate
+ 15.type=int
+ 15.desc=Target update (publishing) rate for gps/fix messages. See [[#rates|Update Rates]] below.
+ 15.default=1
+ 16.name=imu_rate
+ 16.type=int
+ 16.desc=Target update (publishing) rate for imu/data messages. See [[#rates|Update Rates]] below.
+ 16.default=10
+ 17.name=odom_rate
+ 17.type=int
+ 17.desc=Target update (publishing) rate for nav/odom messages. See [[#rates|Update Rates]] below.
+ 17.default=10
+ }
+}
+}}}
+
+
+<>>
+=== Update Rates ===
+
+The rates are set as a target value in Hz. The device accepts a decimation value for each output; the packet rate is base_rate/decimation, where decimation is an integer. The program calculates the decimation to get close the the desired rate, based on polling the sensor for its base rate.
+
+For the 3DM-GX4-45 and 3DM-GX5-45 devices tested the base rates were...
+
+ * GPS - base rate = 4 Hz
+ * IMU - base rate = 500 Hz
+ * Filter - base rate = 500 Hz
+
+<>
+=== Nav Sat Fix message description ==
+Position covariance is populated with diagonals based on reported horizontal and vertical accuracy. The status.status field is the LLH position data "valid flag"-1. The valid flag mapping from the 3DM protocol is
+ * 0x0001 – Latitude and Longitude Valid
+ * 0x0002 – Ellipsoid Height Valid
+ * 0x0004 – MSL Height Valid
+ * 0x0008 – Horizontal Accuracy Valid
+ * 0x0010 – Vertical Accuracy Valid
+ * E.g., if all valid, then the status.status field should be 30.
+
+<>
+=== IMU message description ===
+Coming soon
+
+<>
+=== Odometry message description ===
+ * Currently the pose.position is the longitude (x), latitude (y) and ellipsoid height (z)
+ * pose.covariance and twist.covariance include diagonal elements for position and attitude
+
+<>
+== Nav Status message description ===
+
+ * Includes three values - see communication protocol for full documentation.
+ * filter_state
+ * 0x00 – Startup
+ * 0x01 – Initialization (see status flags)
+ * 0x02 – Running, Solution Valid
+ * 0x03 – Running, Solution Error (see status flags)
+ * dynamics mode
+ * 0x01 – Portable (device default)
+ * 0x02 – Automotive
+ * 0x03 – Airborne
+ * status_flags
+ * See device documentation
+
+
+== Build Instructions ==
+
+Building from source
+{{{
+DISTRO={hydro|indigo}
+cd ~/catkin_ws
+rosdep update
+rosdep check --from-paths src/microstrain_3dm_gx5_45/ --rosdistro=$DISRO
+rosdep install --from-paths src/microstrain_3dm_gx5_45/ --ignore-src --rosdistro=$DISTRO --simulate
+rosdep install --from-paths src/microstrain_3dm_gx5_45/ --ignore-src --rosdistro=$DISTRO
+catkin_make
+source devel/setup.bash
+}}}
+
+== Dev Notes ==
+
+ The mip_sdk_user_functions are C functions that need to be called by various parts of the SDK. The main purpose of these functions is to implement the platform-specific serial (RS232) port elements. The prototype serial port open function takes the COM number as an integer input - which is clunky for Linux serial ports. Changed this to take a string defining the port (e.g., /dev/ttyS0), but this necessitated also modifying the mip_sdk_interface.[ch] files, since this is what is called by the application - changed the mip_interface_init function to accept a string argument for specifying the port.
+
+== TODO ==
+
+ * Verify order of quaternions
+
+
+== Examples ==
+
+
+
+== Launch File Examples ==
+
+Example launch files are provided with the package to illustrate setting the various parameters.