This library provides message definitions and support functionality for interacting with Point One FusionEngine in real time, as well as processing recorded output data. Both C++ and Python are supported.
Click here to download the latest FusionEngine protocol specification PDF: Point One FusionEngine Message Specification
See http://docs.pointonenav.com/fusion-engine/ for the latest C++ API documentation.
This library is released under the MIT license agreement. We welcome code and documentation contributions from users. See Contributing for instructions on how to report issues and develop, test, and submit code changes.
If you encounter an issue, please submit a ticket. If you need support with Point One FusionEngine or a Point One device (Atlas, Quectel LG69T, etc.), please contact [email protected].
- C++11 or later
- CMake 3.x or Bazel 3.x
- GCC, Clang, or Microsoft Visual Studio
- Python 3.8 or later
- Doxygen version 1.8.18
- Versions 1.8.19 and 1.8.20 have a known issue with
enum
documentation and do not currently work
- Versions 1.8.19 and 1.8.20 have a known issue with
<root>
- Top-level Bazel and CMake build files (C++)examples/
- C++ example applicationspython/
- Python source filesbin/
- Analysis and processing toolsexamples/
- Python example applicationsfusion_engine_client
- Top Python package directorymessages
- Python message definitionsparsers
- Message encoding and decoding support
src/
- C++ source filespoint_one/
fusion_engine/
messages/
- C++ message definitions
The examples/
directory contains example applications demonstrating how to use this library. They are:
external_cmake_project
- Download a copy of the FusionEngine Client library from the public repository and import it into a CMake project usingFetchContent
.generate_data
- Generate a binary file containing a fixed set of messages.lband_decode
- Example of decoding RTCM corrections from a recorded file containing LBandFrameMessage.message_decode
- Parse and print the contents of messages contained in a binary file using theFusionEngineFramer
class.raw_message_decode
- Parse and print the contents of messages directly from a binary file without a helper class.request_version
- Simulate sending a request for a version info message, and waiting for a response.tcp_client
- Connect to a device over TCP and display the received FusionEngine messages.udp_client
- Connect to a device over UDP and display the received FusionEngine messages.
To include this library as part of your CMake project, we recommend using the CMake FetchContent
feature as shown
below, rather than compiling and installing the library manually as in the sections above:
# Download the specified version of the FusionEngine client library and make it
# available.
include(FetchContent)
FetchContent_Declare(
fusion_engine_client
# Recommended:
URL https://github.com/PointOneNav/fusion-engine-client/archive/refs/tags/v1.22.3.zip
URL_HASH MD5=cfe1de319725822a1b825cd3421fb6b1
# Alternatively:
# GIT_REPOSITORY https://github.com/PointOneNav/fusion-engine-client.git
# GIT_TAG v1.22.3
)
set(P1_FE_BUILD_EXAMPLES OFF CACHE INTERNAL "")
FetchContent_MakeAvailable(fusion_engine_client)
# Define your application and add a dependency for the FusionEngine client
# library.
add_executable(example_app main.cc)
target_link_libraries(example_app PUBLIC fusion_engine_client)
Note that we strongly recommend using a specific version of the library in your code by specifying a release zip file or
a git tag (e.g., GIT_TAG vA.B.C
), and updating that as new versions are released. That way, you can be sure that your
code is always built with a known version of fusion-engine-client. If you prefer, however, you can tell CMake to track
the latest changes by using GIT_TAG master
instead.
See examples/external_cmake_project/CMakeLists.txt for more details.
Use the following steps to compile and install this library using CMake:
mkdir build
cd build
cmake ..
make
sudo make install
This will generate libfusion_engine_client.so
, and install the library and header files on your system. By default,
this will also build the example applications. You can disable the example applications by
specifying cmake -DP1_FE_BUILD_EXAMPLES=OFF ..
.
Use the following steps to compile and install this library using CMake and MSBuild:
mkdir output
cd output
cmake ..
MSBuild p1_fusion_engine_client.sln
Note: For Windows, we name the build directory
output
. Windows is not case-sensitive, andbuild
conflicts with the BazelBUILD
file.
By default, the compiled example applications will be located in build/examples/
and can be run from there:
./build/examples/message_decode/message_decode
To use this library in an existing Bazel project, add the following to your project's WORKSPACE
file:
git_repository(
name = "fusion_engine_client",
remote = "[email protected]:PointOneNav/fusion_engine_client.git",
tag = "v1.22.3",
)
Note that we strongly recommend using a specific version of the library in your code by specifying a git tag (e.g.,
tag = "v1.22.3"
), and updating that as new versions are released. That way, you can be sure that your code is always
built with a known version of fusion-engine-client. If you prefer, however, you can tell Bazel to track the latest
changes by using branch = "master"
instead.
After declaring the repository in your WORKSPACE
file, you can add the following dependency to any cc_library()
or
cc_binary()
definitions in your project's BAZEL
files:
cc_library(
name = "my_library",
deps = [
"@fusion_engine_client",
],
)
If desired, you can add a dependency for only part of the library. For example, to depend on only the core message
definitions and support code, set your deps
entry to @fusion_engine_client//:core
.
In general, it is strongly recommended that you let Bazel import and compile the library using git_repository()
as
shown above. If you would like to compile the library manually, however, you can run the following command:
bazel build -c opt //:libfusion_engine_client.so
The generated file will be located at bazel-bin/libfusion_engine_client.so
.
Note: The
/examples
directory has been structured like a stand-alone Bazel project to illustrate how to integrate this library into your own project. Thebazel-bin/
directory below refers to<root>/examples/bazel-bin/
.
To build all example applications, navigate to the examples/
directory and run the following:
bazel build -c opt //:*
Alternatively, you can build individual applications as follows:
bazel build -c opt //message_decode
The generated applications will be located in bazel-bin/
. For example:
bazel-bin/message_decode/message_decode message_decode/example_data.p1log
You can also use the bazel run
command to build and run an application in one step:
bazel run -c opt //message_decode -- message_decode/example_data.p1log
See Point One FusionEngine Python Client for complete details and usage examples.
- Install Python 3.8 (or later) and pip.
- Install the
fusione-engine-client
module, including all analysis and data processing tools:python3 -m pip install fusion-engine-client[all]
- Note: If you wish to only install data parsing support, and do not want to install plotting and other requirements
used by the analysis tools in
bin/
, you may omit[all]
and runpython3 -m pip install fusion-engine-client
- Note: If you wish to only install data parsing support, and do not want to install plotting and other requirements
used by the analysis tools in
- Run any of the applications in
bin/
. For example, to plot results from a*.p1log
file from a Point One device:p1_display /path/to/log/file_or_directory
- Install Python 3.8 (or later) and pip.
- Clone a copy of this repository:
git clone https://github.com/PointOneNav/fusion-engine-client.git
- Install the Python requirements:
python3 -m pip install -r requirements.txt
- Run any of the applications in
bin/
or the example code inexamples/
. For example, to plot results from a*.p1log
file from a Point One device:python3 bin/p1_display /path/to/log/file_or_directory
The documentation for the latest release is generated automatically and hosted at
http://docs.pointonenav.com/fusion-engine/. If you would like to build documentation locally, simply run doxygen
from
the repository root directory. The generated output will be located in docs/html/
. To view it, open
docs/html/index.html
in a web browser.
The canonical definitions for the FusionEngine messages are their C++ struct definitions. These definitions are given the attributes:
packed
- This attribute sets that no implicit padding should be inserted between members of the struct. For example:Without thestruct Foo { uint8_t a; uint64_t b; };
packed
attribute, the size ofFoo
could be 12 or 16 bytes with 3 or 7 bytes of padding inserted between the membersa
andb
. Withpacked
, the two member variables will be back-to-back in memory.aligned(4)
- This attribute ensures that the the size of the struct will be padded at the end to be a multiple of 4 bytes. It also makes the default alignment of the struct in memory 4 bytes as well.
In addition to these struct attributes, the struct definitions manually enforce 4 byte alignment for floating point values (i.e., float
and double
).
Generally, functions in this library assume that serialized data is little-endian.
No special detection of conversion is done to enforce this, so external handling would be needed to use this library with a big-endian system.
All FusionEngine messages contain a MessageHeader
followed by the payload of the specific message. To decode an
incoming message you must:
- Deserialize the header.
- Validate the message by checking the CRC (optional).
- Deserialize the payload indicated by the
message_type
field in the header.
For example:
#include <point_one/fusion_engine/messages/core.h>
using namespace point_one::fusion_engine::messages;
void DeserializeMessage(const uint8_t* buffer) {
const MessageHeader& header = *reinterpret_cast<const MessageHeader*>(buffer);
if (header.message_type == MessageType::POSE) {
const PoseMessage& contents =
*reinterpret_cast<const PoseMessage*>(buffer + sizeof(MessageHeader));
...
}
}
See the message_decode
example for more details.
The platform body axes are defined as +x forward, +y left, and +z up. A positive yaw is a left turn, positive pitch
points the nose of the vehicle down, and positive roll is a roll toward the right. Yaw is measured from east in a
counter-clockwise direction. For example, north is +90 degrees (i.e., heading = 90.0 - yaw
).