mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-10 14:51:15 +08:00
drivers: initial VectorNav (VN-100, VN-200, VN-300) support
This commit is contained in:
@@ -10,6 +10,7 @@ fi
|
||||
exec find boards msg src platforms test \
|
||||
-path platforms/nuttx/NuttX -prune -o \
|
||||
-path platforms/qurt/dspal -prune -o \
|
||||
-path src/drivers/ins/vectornav/libvnc -prune -o \
|
||||
-path src/drivers/uavcan/libuavcan -prune -o \
|
||||
-path src/drivers/uavcan/uavcan_drivers/kinetis/driver/include/uavcan_kinetis -prune -o \
|
||||
-path src/drivers/cyphal/libcanard -prune -o \
|
||||
|
||||
@@ -15,7 +15,7 @@ class ModuleDocumentation(object):
|
||||
# TOC in https://github.com/PX4/PX4-user_guide/blob/main/en/SUMMARY.md
|
||||
valid_categories = ['driver', 'estimator', 'controller', 'system',
|
||||
'communication', 'command', 'template', 'simulation', 'autotune']
|
||||
valid_subcategories = ['', 'distance_sensor', 'imu', 'airspeed_sensor',
|
||||
valid_subcategories = ['', 'distance_sensor', 'imu', 'ins', 'airspeed_sensor',
|
||||
'magnetometer', 'baro', 'optical_flow', 'rpm_sensor', 'transponder']
|
||||
|
||||
max_line_length = 80 # wrap lines that are longer than this
|
||||
|
||||
@@ -6,7 +6,7 @@ CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS5"
|
||||
CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS3"
|
||||
CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1"
|
||||
CONFIG_DRIVERS_ADC_BOARD_ADC=y
|
||||
CONFIG_COMMON_BAROMETERS=y
|
||||
CONFIG_DRIVERS_BAROMETER_MS5611=y
|
||||
CONFIG_DRIVERS_BATT_SMBUS=y
|
||||
CONFIG_DRIVERS_CAMERA_CAPTURE=y
|
||||
CONFIG_DRIVERS_CAMERA_TRIGGER=y
|
||||
@@ -17,6 +17,7 @@ CONFIG_DRIVERS_GPS=y
|
||||
CONFIG_DRIVERS_HEATER=y
|
||||
CONFIG_DRIVERS_IMU_BOSCH_BMI055=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
|
||||
CONFIG_DRIVERS_INS_VECTORNAV=y
|
||||
CONFIG_COMMON_LIGHT=y
|
||||
CONFIG_COMMON_MAGNETOMETER=y
|
||||
CONFIG_COMMON_OPTICAL_FLOW=y
|
||||
|
||||
@@ -8,5 +8,5 @@ float32[4] q # Quaternion rotation from the FRD body frame to
|
||||
float32[4] delta_q_reset # Amount by which quaternion has changed during last reset
|
||||
uint8 quat_reset_counter # Quaternion reset counter
|
||||
|
||||
# TOPICS vehicle_attitude vehicle_attitude_groundtruth
|
||||
# TOPICS vehicle_attitude vehicle_attitude_groundtruth external_ins_attitude
|
||||
# TOPICS estimator_attitude
|
||||
|
||||
@@ -25,5 +25,5 @@ bool terrain_alt_valid # Terrain altitude estimate is valid
|
||||
|
||||
bool dead_reckoning # True if this position is estimated through dead-reckoning
|
||||
|
||||
# TOPICS vehicle_global_position vehicle_global_position_groundtruth
|
||||
# TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position
|
||||
# TOPICS estimator_global_position
|
||||
|
||||
@@ -72,5 +72,5 @@ float32 vz_max # maximum vertical speed - set to 0 when limiting not required
|
||||
float32 hagl_min # minimum height above ground level - set to 0 when limiting not required (meters)
|
||||
float32 hagl_max # maximum height above ground level - set to 0 when limiting not required (meters)
|
||||
|
||||
# TOPICS vehicle_local_position vehicle_local_position_groundtruth
|
||||
# TOPICS vehicle_local_position vehicle_local_position_groundtruth external_ins_local_position
|
||||
# TOPICS estimator_local_position
|
||||
|
||||
@@ -222,7 +222,11 @@
|
||||
#define DRV_POWER_DEVTYPE_INA220 0xD3
|
||||
#define DRV_POWER_DEVTYPE_INA238 0xD4
|
||||
|
||||
#define DRV_DIST_DEVTYPE_TF02PRO 0xE0
|
||||
#define DRV_DIST_DEVTYPE_TF02PRO 0xE0
|
||||
|
||||
#define DRV_INS_DEVTYPE_VN100 0xE1
|
||||
#define DRV_INS_DEVTYPE_VN200 0xE2
|
||||
#define DRV_INS_DEVTYPE_VN300 0xE3
|
||||
|
||||
#define DRV_DEVTYPE_UNUSED 0xff
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
menu "Inertial Navigation Systems (INS)"
|
||||
menuconfig COMMON_INS
|
||||
bool "All INS sensors"
|
||||
default n
|
||||
select DRIVERS_INS_VECTORNAV
|
||||
---help---
|
||||
Enable default set of INS sensors
|
||||
rsource "*/Kconfig"
|
||||
endmenu
|
||||
@@ -0,0 +1,50 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
add_subdirectory(libvnc)
|
||||
|
||||
px4_add_module(
|
||||
MODULE drivers__ins__vectornav
|
||||
MAIN vectornav
|
||||
INCLUDES
|
||||
libvnc/include
|
||||
COMPILE_FLAGS
|
||||
-Wno-error
|
||||
SRCS
|
||||
VectorNav.cpp
|
||||
VectorNav.hpp
|
||||
MODULE_CONFIG
|
||||
module.yaml
|
||||
DEPENDS
|
||||
libvnc
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
menuconfig DRIVERS_INS_VECTORNAV
|
||||
bool "vectornav"
|
||||
default n
|
||||
---help---
|
||||
Enable support for vectornav
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
*
|
||||
* Driver for the VectorNav VN-100, VN-200, VN-300 series
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <termios.h>
|
||||
|
||||
extern "C" {
|
||||
#include "vn/sensors/searcher.h"
|
||||
|
||||
#include "vn/sensors/compositedata.h"
|
||||
}
|
||||
|
||||
#include "vn/sensors.h"
|
||||
|
||||
#include <px4_platform_common/module.h>
|
||||
#include <px4_platform_common/module_params.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/drivers/accelerometer/PX4Accelerometer.hpp>
|
||||
#include <lib/drivers/gyroscope/PX4Gyroscope.hpp>
|
||||
#include <lib/drivers/magnetometer/PX4Magnetometer.hpp>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
#include <px4_platform_common/module.h>
|
||||
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
|
||||
#include <uORB/Publication.hpp>
|
||||
#include <uORB/SubscriptionInterval.hpp>
|
||||
#include <uORB/topics/parameter_update.h>
|
||||
#include <uORB/topics/sensor_baro.h>
|
||||
#include <uORB/topics/sensor_gps.h>
|
||||
#include <uORB/topics/vehicle_attitude.h>
|
||||
#include <uORB/topics/vehicle_global_position.h>
|
||||
#include <uORB/topics/vehicle_local_position.h>
|
||||
#include <uORB/topics/vehicle_odometry.h>
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
class VectorNav : public ModuleBase<VectorNav>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
VectorNav(const char *port);
|
||||
~VectorNav() override;
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int custom_command(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int print_usage(const char *reason = nullptr);
|
||||
|
||||
/** @see ModuleBase::print_status() */
|
||||
int print_status() override;
|
||||
|
||||
private:
|
||||
|
||||
bool init();
|
||||
bool configure();
|
||||
|
||||
void Run() override;
|
||||
|
||||
static void binaryAsyncMessageReceived(void *userData, VnUartPacket *packet, size_t runningIndex);
|
||||
|
||||
void sensorCallback(VnUartPacket *packet);
|
||||
|
||||
char _port[20] {};
|
||||
|
||||
bool _initialized{false};
|
||||
|
||||
bool _connected{false};
|
||||
bool _configured{false};
|
||||
|
||||
hrt_abstime _last_read{0};
|
||||
|
||||
VnSensor _vs{};
|
||||
|
||||
BinaryOutputRegister _binary_output_group_1{};
|
||||
BinaryOutputRegister _binary_output_group_2{};
|
||||
BinaryOutputRegister _binary_output_group_3{};
|
||||
|
||||
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
|
||||
|
||||
PX4Accelerometer _px4_accel{0};
|
||||
PX4Gyroscope _px4_gyro{0};
|
||||
PX4Magnetometer _px4_mag{0};
|
||||
|
||||
uORB::PublicationMulti<sensor_baro_s> _sensor_baro_pub{ORB_ID(sensor_baro)};
|
||||
uORB::PublicationMulti<sensor_gps_s> _sensor_gps_pub{ORB_ID(sensor_gps)};
|
||||
|
||||
uORB::PublicationMulti<vehicle_attitude_s> _attitude_pub{ORB_ID(external_ins_attitude)};
|
||||
uORB::PublicationMulti<vehicle_local_position_s> _local_position_pub{ORB_ID(external_ins_local_position)};
|
||||
uORB::PublicationMulti<vehicle_global_position_s> _global_position_pub{ORB_ID(external_ins_global_position)};
|
||||
|
||||
perf_counter_t _comms_errors{perf_alloc(PC_COUNT, MODULE_NAME": com_err")};
|
||||
perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")};
|
||||
|
||||
|
||||
// TODO: params for GNSS antenna offsets
|
||||
// A
|
||||
// B
|
||||
|
||||
// As mentioned previously, the VN-300 has a factory default baseline of {1, 0, 0} [m]. This vector represents
|
||||
// the position of a point on GNSS antenna B relative to the same point on GNSS antenna A in the output
|
||||
// coordinate system on the VN-300. The default output coordinate system is engraved on the top of the
|
||||
// aluminum enclosure. For the factory default case, GNSS antenna B should be positioned in front of GNSS
|
||||
// antenna A relative to the X-axis marked on the VN-300 enclosure as shown in the figure below. If a different
|
||||
// baseline length or direction required, then you will need to write the new baseline vector and the measurement
|
||||
// uncertainty to the sensor using the GNSS Compass Baseline Register.
|
||||
|
||||
// GNSS Antenna A Offset
|
||||
// Relative position of GNSS antenna. (X-axis)
|
||||
// VN_GNSS_ANTA_POS_X
|
||||
|
||||
|
||||
// Relative position of GNSS antenna. (X-axis)
|
||||
// VN_GNSS_ANTB_POS_X
|
||||
|
||||
// Uncertainty in the X-axis position measurement.
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(libvnc C)
|
||||
|
||||
include_directories(include)
|
||||
|
||||
set(SOURCES
|
||||
src/vn/xplat/criticalsection.c
|
||||
src/vn/xplat/event.c
|
||||
src/vn/xplat/serialport.c
|
||||
src/vn/xplat/thread.c
|
||||
src/vn/xplat/time.c
|
||||
src/vn/error.c
|
||||
src/vn/error_detection.c
|
||||
src/vn/util.c
|
||||
src/vn/math/matrix.c
|
||||
src/vn/math/vector.c
|
||||
src/vn/protocol/upack.c
|
||||
src/vn/protocol/upackf.c
|
||||
src/vn/protocol/spi.c
|
||||
src/vn/sensors/compositedata.c
|
||||
src/vn/sensors/searcher.c
|
||||
src/vn/sensors.c
|
||||
src/vn/sensors/ezasyncdata.c
|
||||
src/vn/conv.c
|
||||
include/vn/vectornav.h
|
||||
include/vn/bool.h
|
||||
include/vn/util/compiler.h
|
||||
include/vn/sensors/compositedata.h
|
||||
include/vn/const.h
|
||||
include/vn/conv.h
|
||||
include/vn/xplat/criticalsection.h
|
||||
include/vn/enum.h
|
||||
include/vn/error_detection.h
|
||||
include/vn/error.h
|
||||
include/vn/xplat/event.h
|
||||
include/vn/util/export.h
|
||||
include/vn/sensors/ezasyncdata.h
|
||||
include/vn/int.h
|
||||
include/vn/math/matrix.h
|
||||
include/vn/util/port.h
|
||||
include/vn/protocol/common.h
|
||||
include/vn/sensors/searcher.h
|
||||
include/vn/sensors.h
|
||||
include/vn/xplat/serialport.h
|
||||
include/vn/protocol/spi.h
|
||||
include/vn/xplat/thread.h
|
||||
include/vn/xplat/time.h
|
||||
include/vn/types.h
|
||||
include/vn/protocol/upack.h
|
||||
include/vn/protocol/upackf.h
|
||||
include/vn/util.h
|
||||
include/vn/math/vector.h
|
||||
)
|
||||
|
||||
add_library(libvnc ${SOURCES})
|
||||
add_dependencies(libvnc prebuild_targets)
|
||||
target_compile_options(libvnc
|
||||
PRIVATE
|
||||
-Wno-error
|
||||
-Wno-double-promotion
|
||||
-Wno-pointer-sign
|
||||
-Wno-cast-align
|
||||
-Wno-unused-but-set-parameter
|
||||
-Wno-sign-compare
|
||||
-Wno-bad-function-cast
|
||||
-Wno-empty-body
|
||||
-Wno-switch
|
||||
-Wno-unused-variable
|
||||
-Wno-format
|
||||
-Wno-format-security
|
||||
)
|
||||
|
||||
if("${PX4_PLATFORM}" MATCHES "nuttx")
|
||||
target_compile_definitions(libvnc PUBLIC __NUTTX__)
|
||||
endif()
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef VNBOOL_H_INCLUDED
|
||||
#define VNBOOL_H_INCLUDED
|
||||
|
||||
/** \brief Boolean definition. */
|
||||
|
||||
#include "vn/util/compiler.h"
|
||||
#include "vn/int.h"
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
|
||||
#if VN_HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#if !defined(__GNUC__)
|
||||
/* _Bool builtin type is included in GCC. */
|
||||
/* ISO C Standard: 5.2.5 An object declared as type _Bool is large
|
||||
* enough to store the values 0 and 1. */
|
||||
typedef int8_t _Bool;
|
||||
#endif
|
||||
|
||||
/* ISO C Standard: 7.16 Boolean type */
|
||||
|
||||
#if defined(__STDC__) && defined(__GNUC__)
|
||||
/* Avoid warning "ISO C90/89 does not support boolean types" */
|
||||
#define bool int8_t
|
||||
#else
|
||||
#define bool _Bool
|
||||
#endif
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef __VNCONTS_H__
|
||||
#define __VNCONTS_H__
|
||||
|
||||
/** Pi in double format. */
|
||||
#define VNC_PI_D (3.141592653589793238)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __VNCONV_H__
|
||||
#define __VNCONV_H__
|
||||
|
||||
#include "vn/math/vector.h"
|
||||
|
||||
/** Converts ECEF coordinate to LLA frame.
|
||||
* \param[in] ecef Coordinate in ECEF frame.
|
||||
* \return Coordinate converted to LLA frame. */
|
||||
vec3d ecef_to_lla_v3d(vec3d ecef);
|
||||
|
||||
/** Converts LLA coordinate to ECEF frame.
|
||||
* \param[in] lla Coordinate in LLA frame in (deg, deg, meter) units.
|
||||
* \return Coordinate converted to ECEF frame in (km, km, km) units. */
|
||||
vec3d lla_to_ecef_v3d(vec3d lla);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
#ifndef VN_ERROR_H_INCLUDED
|
||||
#define VN_ERROR_H_INCLUDED
|
||||
|
||||
#include "vn/enum.h"
|
||||
|
||||
/** \brief Unified error code system. */
|
||||
|
||||
/** \brief Converts a VnError enum into a string.
|
||||
*
|
||||
* \param[out] out The buffer to place the string in.
|
||||
* \param[in] val The VnError value to convert to string. */
|
||||
void strFromVnError(char* out, VnError val);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef VNERRDET_H_INCLUDED
|
||||
#define VNERRDET_H_INCLUDED
|
||||
|
||||
/** \brief Error-detection capabilities. */
|
||||
|
||||
#include "vn/enum.h"
|
||||
#include "vn/int.h"
|
||||
#include "vn/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Computes the 8-bit XOR checksum of the provided data.
|
||||
*
|
||||
* \param[in] data Pointer to the start of data to perform the checksum of.
|
||||
* \param[in] length The number of bytes to include in the checksum.
|
||||
* \return The computed checksum.
|
||||
*/
|
||||
uint8_t VnChecksum8_compute(char const *data, size_t length);
|
||||
|
||||
/** \brief Computes the 16-bit CRC16-CCITT of the provided data.
|
||||
*
|
||||
* \param[in] data Pointer to the start of data to perform the CRC of.
|
||||
* \param[in] length The number of bytes to include in the CRC.
|
||||
* \return The computed CRC.
|
||||
*/
|
||||
uint16_t VnCrc16_compute(char const *data, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef VNINT_H_INCLUDED
|
||||
#define VNINT_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4820)
|
||||
#pragma warning(disable : 4255)
|
||||
#endif
|
||||
|
||||
/* Visual Studio 2008 and earlier do not include the stdint.h header file. */
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
/* Just include the standard header file for integer types. */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef VN_MATRIX_H_INCLUDED
|
||||
#define VN_MATRIX_H_INCLUDED
|
||||
|
||||
#include "vn/util/compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Represents a 3x3 matrix with an underlying data type of <c>float</c>. */
|
||||
typedef union
|
||||
{
|
||||
float e[3*3]; /**< The matrix's elements in column-major ordering. */
|
||||
|
||||
/* Check if the compiler supports anonymous unions. */
|
||||
#if defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L) && defined(__GNUC__)
|
||||
|
||||
struct
|
||||
{
|
||||
float e00; /**< Element [0,0]. */
|
||||
float e10; /**< Element [1,0]. */
|
||||
float e20; /**< Element [2,0]. */
|
||||
float e01; /**< Element [0,1]. */
|
||||
float e11; /**< Element [1,1]. */
|
||||
float e21; /**< Element [2,1]. */
|
||||
float e02; /**< Element [0,2]. */
|
||||
float e12; /**< Element [1,2]. */
|
||||
float e22; /**< Element [2,2]. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} mat3f;
|
||||
|
||||
/** \brief Represents a quaternion reading with underlying data type of <c>float</c>. */
|
||||
typedef union
|
||||
{
|
||||
float c[4]; /**< Indexable. */
|
||||
|
||||
/* Check if the compiler supports anonymous unions. */
|
||||
#if defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L) && defined(__GNUC__)
|
||||
|
||||
struct
|
||||
{
|
||||
float x; /**< The x component. */
|
||||
float y; /**< The y component. */
|
||||
float z; /**< The z component. */
|
||||
float w; /**< The w component. */
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
float c0; /**< Component 0. */
|
||||
float c1; /**< Component 1. */
|
||||
float c2; /**< Component 2. */
|
||||
float c3; /**< Component 2. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} quatf;
|
||||
|
||||
/** \brief Initializes a 3x3 float matrix from an float array with matrix
|
||||
* elements in column-major ordering.
|
||||
*
|
||||
* \param[out] m 3x3 float matrix to initialize
|
||||
* \param[in] fa float array containing a 3x3 matrix in column-major order */
|
||||
void vn_m3_init_fa(mat3f* m, const float* fa);
|
||||
|
||||
/** \brief Converts a mat3f to a string.
|
||||
*
|
||||
* \param[out] out The char buffer to output the result to.
|
||||
* \param[in] m The mat3f to convert.
|
||||
*/
|
||||
void strFromMat3f(char* out, mat3f m);
|
||||
|
||||
/** \brief Negates a mat3f.
|
||||
* \param[in] m Matrix to negate.
|
||||
* \return Negated matrix. */
|
||||
mat3f vnm_negative_mat3f(mat3f m);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#ifndef VN_VECTOR_H_INCLUDED
|
||||
#define VN_VECTOR_H_INCLUDED
|
||||
|
||||
#include "vn/util/compiler.h"
|
||||
|
||||
/** \brief Various vector types and operations. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Represents a 3 component vector with an underlying data type of
|
||||
* <c>float</c>. */
|
||||
typedef union
|
||||
{
|
||||
float c[3]; /**< Indexable. */
|
||||
|
||||
/* Check if the compiler supports anonymous unions. */
|
||||
#if defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L) && defined(__GNUC__)
|
||||
|
||||
struct
|
||||
{
|
||||
float x; /**< X component. */
|
||||
float y; /**< Y component. */
|
||||
float z; /**< Z component. */
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
float c0; /**< Component 0. */
|
||||
float c1; /**< Component 1. */
|
||||
float c2; /**< Component 2. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} vec3f;
|
||||
|
||||
/** \brief Represents a 3 component vector with an underlying data type of
|
||||
* <c>double</c>. */
|
||||
typedef union
|
||||
{
|
||||
double c[3]; /**< Indexable. */
|
||||
|
||||
/* Check if the compiler supports anonymous unions. */
|
||||
#if defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L) && defined(__GNUC__)
|
||||
|
||||
struct
|
||||
{
|
||||
double x; /**< The x component. */
|
||||
double y; /**< The y component. */
|
||||
double z; /**< The z component. */
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
double c0; /**< Component 0. */
|
||||
double c1; /**< Component 1. */
|
||||
double c2; /**< Component 2. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} vec3d;
|
||||
|
||||
/** \brief Represents a 4 component vector with an underlying data type of
|
||||
* <c>float</c>. */
|
||||
typedef union
|
||||
{
|
||||
float c[4]; /**< Indexable. */
|
||||
|
||||
/* Check if the compiler supports anonymous unions. */
|
||||
#if (defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L)) && defined(__GNUC__)
|
||||
|
||||
struct
|
||||
{
|
||||
float x; /**< The x component. */
|
||||
float y; /**< The y component. */
|
||||
float z; /**< The z component. */
|
||||
float w; /**< The w component. */
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
float c0; /**< Component 0. */
|
||||
float c1; /**< Component 1. */
|
||||
float c2; /**< Component 2. */
|
||||
float c3; /**< Component 2. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} vec4f;
|
||||
|
||||
/** \brief Initializes a 3-dimensional float vector from an float array.
|
||||
*
|
||||
* \param[out] v 3-dimensional float vector to initialize
|
||||
* \param[in] fa float array a 3-componet vector */
|
||||
void vn_v3_init_fa(vec3f* v, const float* fa);
|
||||
|
||||
/** Creates a vec3d initialized with provided values.
|
||||
* \param[in] x x-component.
|
||||
* \param[in] y y-component.
|
||||
* \param[in] z z-component.
|
||||
* \return The initialized vec3d. */
|
||||
vec3d create_v3d(double x, double y, double z);
|
||||
|
||||
/** \brief Adds two vec3f together.
|
||||
*
|
||||
* \param[in] lhs The lhs vec3f.
|
||||
* \param[in] rhs The rhs vec3f.
|
||||
* \return The resulting vec3f from adding lhs and rhs together. */
|
||||
vec3f add_v3f_v3f(vec3f lhs, vec3f rhs);
|
||||
|
||||
/** \brief Adds two vec3d together.
|
||||
*
|
||||
* \param[in] lhs The lhs vec3d.
|
||||
* \param[in] rhs The rhs vec3d.
|
||||
* \return The resulting vec3d from adding lhs and rhs together. */
|
||||
vec3d add_v3d_v3d(vec3d lhs, vec3d rhs);
|
||||
|
||||
/** \brief Adds two vec4f together.
|
||||
*
|
||||
* \param[in] lhs The lhs vec4f.
|
||||
* \param[in] rhs The rhs vec4f.
|
||||
* \return The resulting vec4f from adding lhs and rhs together. */
|
||||
vec4f add_v4f_v4f(vec4f lhs, vec4f rhs);
|
||||
|
||||
/** \brief Subtracts a vec3f from another vec3f.
|
||||
*
|
||||
* \param[in] lhs The lhs vec3f.
|
||||
* \param[in] rhs The rhs vec3f.
|
||||
* \return The resulting vec3f from subtracting rhs from lhs. */
|
||||
vec3f sub_v3f_v3f(vec3f lhs, vec3f rhs);
|
||||
|
||||
/** \brief Subtracts a vec3d from another vec3d.
|
||||
*
|
||||
* \param[in] lhs The lhs vec3d.
|
||||
* \param[in] rhs The rhs vec3d.
|
||||
* \return The resulting vec3d from subtracting rhs from lhs. */
|
||||
vec3d sub_v3d_v3d(vec3d lhs, vec3d rhs);
|
||||
|
||||
/** \brief Subtracts a vec4f from another vec4f.
|
||||
*
|
||||
* \param[in] lhs The lhs vec4f.
|
||||
* \param[in] rhs The rhs vec4f.
|
||||
* \return The resulting vec4f from subtracting rhs from lhs. */
|
||||
vec4f sub_v4f_v4f(vec4f lhs, vec4f rhs);
|
||||
|
||||
/** \brief Converts a vec3f to a string.
|
||||
*
|
||||
* \param[out] out The char buffer to output the result to.
|
||||
* \param[in] v The vec3f to convert. */
|
||||
void str_vec3f(char* out, vec3f v);
|
||||
|
||||
/** \brief Converts a vec3d to a string.
|
||||
*
|
||||
* \param[out] out The char buffer to output the result to.
|
||||
* \param[in] v The vec3d to convert. */
|
||||
void str_vec3d(char* out, vec3d v);
|
||||
|
||||
/** \brief Converts a vec4f to a string.
|
||||
*
|
||||
* \param[out] out The char buffer to output the result to.
|
||||
* \param[in] v The vec4f to convert. */
|
||||
void str_vec4f(char* out, vec4f v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef _VNCOMMON_H_
|
||||
#define _VNCOMMON_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Enumeration of the available asynchronous ASCII message types. */
|
||||
typedef enum
|
||||
{
|
||||
VNOFF = 0, /**< Asynchronous output is turned off. */
|
||||
VNYPR = 1, /**< Asynchronous output type is Yaw, Pitch, Roll. */
|
||||
VNQTN = 2, /**< Asynchronous output type is Quaternion. */
|
||||
#ifdef EXTRA
|
||||
VNQTM = 3, /**< Asynchronous output type is Quaternion and Magnetic. */
|
||||
VNQTA = 4, /**< Asynchronous output type is Quaternion and Acceleration. */
|
||||
VNQTR = 5, /**< Asynchronous output type is Quaternion and Angular Rates. */
|
||||
VNQMA = 6, /**< Asynchronous output type is Quaternion, Magnetic and Acceleration. */
|
||||
VNQAR = 7, /**< Asynchronous output type is Quaternion, Acceleration and Angular Rates. */
|
||||
#endif
|
||||
VNQMR = 8, /**< Asynchronous output type is Quaternion, Magnetic, Acceleration and Angular Rates. */
|
||||
#ifdef EXTRA
|
||||
VNDCM = 9, /**< Asynchronous output type is Directional Cosine Orientation Matrix. */
|
||||
#endif
|
||||
VNMAG = 10, /**< Asynchronous output type is Magnetic Measurements. */
|
||||
VNACC = 11, /**< Asynchronous output type is Acceleration Measurements. */
|
||||
VNGYR = 12, /**< Asynchronous output type is Angular Rate Measurements. */
|
||||
VNMAR = 13, /**< Asynchronous output type is Magnetic, Acceleration, and Angular Rate Measurements. */
|
||||
VNYMR = 14, /**< Asynchronous output type is Yaw, Pitch, Roll, Magnetic, Acceleration, and Angular Rate Measurements. */
|
||||
#ifdef EXTRA
|
||||
VNYCM = 15, /**< Asynchronous output type is Yaw, Pitch, Roll, and Calibrated Measurements. */
|
||||
#endif
|
||||
VNYBA = 16, /**< Asynchronous output type is Yaw, Pitch, Roll, Body True Acceleration. */
|
||||
VNYIA = 17, /**< Asynchronous output type is Yaw, Pitch, Roll, Inertial True Acceleration. */
|
||||
#ifdef EXTRA
|
||||
VNICM = 18, /**< Asynchronous output type is Yaw, Pitch, Roll, Inertial Magnetic/Acceleration, and Angular Rate Measurements. */
|
||||
#endif
|
||||
VNIMU = 19, /**< Asynchronous output type is Calibrated Inertial Measurements. */
|
||||
VNGPS = 20, /**< Asynchronous output type is GPS LLA. */
|
||||
VNGPE = 21, /**< Asynchronous output type is GPS ECEF. */
|
||||
VNINS = 22, /**< Asynchronous output type is INS LLA solution. */
|
||||
VNINE = 23, /**< Asynchronous output type is INS ECEF solution. */
|
||||
VNISL = 28, /**< Asynchronous output type is INS LLA 2 solution. */
|
||||
VNISE = 29, /**< Asynchronous output type is INS ECEF 2 solution. */
|
||||
VNDTV = 30, /**< Asynchronous output type is Delta Theta and Delta Velocity. */
|
||||
VNRTK = 31 /**< Asynchronous output type is RTK, from the GPS processor. */
|
||||
#ifdef EXTRA
|
||||
,
|
||||
VNRAW = 252, /**< Asynchronous output type is Raw Voltage Measurements. */
|
||||
VNCMV = 253, /**< Asynchronous output type is Calibrated Measurements. */
|
||||
VNSTV = 254, /**< Asynchronous output type is Kalman Filter State Vector. */
|
||||
VNCOV = 255 /**< Asynchronous output type is Kalman Filter Covariance Matrix Diagonal. */
|
||||
#endif
|
||||
} VnAsciiAsync;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
||||
#ifndef VNUPACKF_H_INCLUDED
|
||||
#define VNUPACKF_H_INCLUDED
|
||||
|
||||
#include "vn/protocol/upack.h"
|
||||
|
||||
/*#include "vnint.h"*/
|
||||
/*#include "vnbool.h"*/
|
||||
/*#include "vntypes.h"
|
||||
#include "vnerror.h"*/
|
||||
|
||||
|
||||
#ifndef VNUART_PROTOCOL_BUFFER_SIZE
|
||||
/** Default internal buffers size for handling received UART data. */
|
||||
#define VNUART_PROTOCOL_BUFFER_SIZE 256
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Defines signature of functions that can handle callback
|
||||
* notifications of packets successfully received and validated from a
|
||||
* VectorNav sensor. */
|
||||
typedef void(*VnUartPacketFinder_PacketFoundHandler)(void *userData, VnUartPacket* packet, size_t runningIndexOfPacketStart);
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4820)
|
||||
#endif
|
||||
|
||||
/** \brief Data structure holding current parsing status of data received from
|
||||
* a VectorNav sensor.
|
||||
*
|
||||
* This structure contains a buffer which will hold bytes that are currently
|
||||
* being processed. The size of this buffer can be adjusted by defining the
|
||||
* size using the preprocesser. For example, the size can be adjusted to use
|
||||
* 1024 bytes by defining VNUART_PROTOCOL_BUFFER_SIZE=1024. */
|
||||
typedef struct
|
||||
{
|
||||
/** \brief Callback for when a packet has been found and validated. */
|
||||
VnUartPacketFinder_PacketFoundHandler packetFoundHandler;
|
||||
|
||||
/** \brief User data for callbacks on the packetFoundHandler. */
|
||||
void *packetFoundHandlerUserData;
|
||||
|
||||
/** \brief Used for correlating the position in the received raw data
|
||||
* stream where packets are found. */
|
||||
size_t runningDataIndex;
|
||||
|
||||
/** \brief Indicates if an ASCII packet is currently being built. */
|
||||
bool asciiCurrentlyBuildingPacket;
|
||||
|
||||
/** \brief Indicates a suspected start of an ASCII packet. */
|
||||
size_t asciiPossibleStartOfPacketIndex;
|
||||
|
||||
/** \brief Index of start of ASCII packet in total running index. */
|
||||
size_t asciiRunningDataIndexOfStart;
|
||||
|
||||
/** \brief Indicates if the first ending character has been found. */
|
||||
bool asciiEndChar1Found;
|
||||
|
||||
/** \brief Indicates if we are currently building a binary packet. */
|
||||
bool binaryCurrentlyBuildingBinaryPacket;
|
||||
|
||||
/** \brief Index of start of binary packet in total running index. */
|
||||
size_t binaryRunningDataIndexOfStart;
|
||||
|
||||
/** \brief Holds the size of the receive buffer. */
|
||||
size_t bufferSize;
|
||||
|
||||
/** \brief The current location to append data into the buffer. */
|
||||
size_t bufferAppendLocation;
|
||||
|
||||
/** \brief Indicates if we have found the groups present data field for a
|
||||
* binary packet we are building. */
|
||||
bool binaryGroupsPresentFound;
|
||||
|
||||
/** \brief The groups present found from a binary packet. */
|
||||
uint8_t binaryGroupsPresent;
|
||||
|
||||
/** \brief Indicates the number of bytes remaining to have all group fields
|
||||
* for a binary data packet we are processing. */
|
||||
uint8_t binaryNumOfBytesRemainingToHaveAllGroupFields;
|
||||
|
||||
/** \brief Start index of a possible binary packet. */
|
||||
size_t binaryPossibleStartIndex;
|
||||
|
||||
/** \brief Keeps track of the number of bytes remaining for a complete
|
||||
* binary packet. */
|
||||
size_t binaryNumberOfBytesRemainingForCompletePacket;
|
||||
|
||||
/** \brief The receive buffer. */
|
||||
uint8_t receiveBuffer[VNUART_PROTOCOL_BUFFER_SIZE];
|
||||
|
||||
} VnUartPacketFinder;
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Initializes the VnUartPacketFinder data structure.
|
||||
*
|
||||
* \param[in] pf VnUartPacketFinder to init. */
|
||||
void VnUartPacketFinder_initialize(VnUartPacketFinder* pf);
|
||||
|
||||
/** \brief Processes received data from the UART.
|
||||
*
|
||||
* \param[in] finder The associated VnUartPacketFinder containing the data
|
||||
* processing state.
|
||||
* \param[in] data The received data.
|
||||
* \param[in] len The number of bytes to process.
|
||||
* \param[in] bootloaderFilter Enable filtering for bootloader messages. */
|
||||
VnError VnUartPacketFinder_processData_ex(VnUartPacketFinder* finder, uint8_t* data, size_t len, bool bootloaderFilter);
|
||||
VnError VnUartPacketFinder_processData(VnUartPacketFinder* finder, uint8_t* data, size_t len);
|
||||
|
||||
|
||||
/** \brief Allows registering for notification of when valid packets are found.
|
||||
*
|
||||
* \param[in] handler The callback function for receiving notifications.
|
||||
* \param[in] userData Pointer to user supplied data which will be sent on all callback notifications.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnUartPacketFinder_registerPacketFoundHandler(VnUartPacketFinder* finder, VnUartPacketFinder_PacketFoundHandler handler, void *userData);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,245 @@
|
||||
#ifndef _VNCOMPOSITEDATA_H_
|
||||
#define _VNCOMPOSITEDATA_H_
|
||||
|
||||
#include "vn/bool.h"
|
||||
#include "vn/xplat/criticalsection.h"
|
||||
#include "vn/enum.h"
|
||||
#include "vn/int.h"
|
||||
#include "vn/math/vector.h"
|
||||
#include "vn/math/matrix.h"
|
||||
#include "vn/protocol/upack.h"
|
||||
#include "vn/math/vector.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4820)
|
||||
#endif
|
||||
|
||||
/** \brief Composite structure of all available data types from VectorNav sensors. */
|
||||
typedef struct
|
||||
{
|
||||
vec3f yawPitchRoll; /**< Yaw, pitch, roll data. */
|
||||
vec4f quaternion; /**< Quaternion data. */
|
||||
mat3f directionCosineMatrix; /**< Direction cosine matrix data. */
|
||||
vec3d positionGpsLla; /**< GPS latitude, longitude, altitude data. */
|
||||
vec3d positionGpsEcef; /**< GPS earth-centered, earth-fixed data. */
|
||||
vec3d positionEstimatedLla; /**< Estimated latitude, longitude, altitude data. */
|
||||
vec3d positionEstimatedEcef; /**< Estimated earth-centered, earth-fixed position data. */
|
||||
VelocityType velocityType; /**< Type of velocity in the struct. */
|
||||
vec3f velocityGpsNed; /**< GPS velocity NED data. */
|
||||
vec3f velocityGpsEcef; /**< GPS velocity ECEF data. */
|
||||
vec3f velocityEstimatedBody; /**< Estimated velocity body data. */
|
||||
vec3f velocityEstimatedNed; /**< Estimated velocity NED data. */
|
||||
vec3f velocityEstimatedEcef; /**< Estimated velocity ECEF data. */
|
||||
vec3f magnetic; /**< Magnetic data. */
|
||||
vec3f magneticUncompensated; /**< Magnetic uncompensated data. */
|
||||
vec3f magneticNed; /**< Magnetic NED data. */
|
||||
vec3f magneticEcef; /**< Magnetic ECEF data. */
|
||||
#ifdef EXTRA
|
||||
vec3f magneticRaw; /**< Magnetic raw data. */
|
||||
#endif
|
||||
vec3f acceleration; /**< Acceleration data. */
|
||||
vec3f accelerationUncompensated; /**< Acceleration uncompensated data. */
|
||||
vec3f accelerationNed; /**< Acceleration NED data. */
|
||||
vec3f accelerationEcef; /**< Acceleration ECEF data. */
|
||||
vec3f accelerationLinearBody; /**< Acceleration linear body data. */
|
||||
vec3f accelerationLinearNed; /**< Acceleration linear NED data. */
|
||||
vec3f accelerationLinearEcef; /**< Acceleration linear ECEF data. */
|
||||
#ifdef EXTRA
|
||||
vec3f accelerationRaw; /**< Acceleration raw data. */
|
||||
#endif
|
||||
vec3f angularRate; /**< Angular rate data. */
|
||||
vec3f angularRateUncompensated; /**< Angular rate uncompensated data. */
|
||||
#ifdef EXTRA
|
||||
vec3f angularRateRaw; /**< Angular rate raw data. */
|
||||
#endif
|
||||
float temperature; /**< Temperature data. */
|
||||
#ifdef EXTRA
|
||||
float temperatureRaw; /**< Temperature raw data. */
|
||||
#endif
|
||||
float pressure; /**< Pressure data. */
|
||||
uint64_t timeStartup; /**< Time startup data. */
|
||||
float deltaTime; /**< Delta time data. */
|
||||
vec3f deltaTheta; /**< Delta theta data. */
|
||||
vec3f deltaVelocity; /**< Delta velocity data. */
|
||||
double tow; /**< GPS time of week data. */
|
||||
uint16_t week; /**< Week data. */
|
||||
uint8_t gpsFix; /**< GPS fix data. */
|
||||
uint8_t numSats; /**< NumSats data. */
|
||||
uint64_t timeGps; /**< TimeGps data. */
|
||||
uint64_t timeGpsPps; /**< TimeGpsPps data. */
|
||||
TimeUtc timeUtc; /**< TimeUtc data. */
|
||||
uint64_t gpsTow; /**< GpsTow data. */
|
||||
vec3f attitudeUncertainty; /**< Attitude uncertainty data. */
|
||||
vec3f positionUncertaintyGpsNed; /**< GPS position uncertainty NED data. */
|
||||
vec3f positionUncertaintyGpsEcef; /**< GPS position uncertainty ECEF data. */
|
||||
float positionUncertaintyEstimated; /**< Estimated position uncertainty data. */
|
||||
float velocityUncertaintyGps; /**< GPS velocity uncertainty data. */
|
||||
float velocityUncertaintyEstimated; /**< Estimated velocity uncertainty data. */
|
||||
uint32_t timeUncertainty; /**< Time uncertainty data. */
|
||||
uint16_t vpeStatus; /**< VpeStatus data. */
|
||||
uint16_t insStatus; /**< InsStatus data. */
|
||||
uint64_t timeSyncIn; /**< TimeSyncIn data. */
|
||||
uint32_t syncInCnt; /**< SyncInCnt data. */
|
||||
uint32_t syncOutCnt; /**< SyncInCnt data. */
|
||||
uint16_t sensSat; /**< SensSat data. */
|
||||
#ifdef EXTRA
|
||||
vec3f yprRates; /**< YprRates data. */
|
||||
#endif
|
||||
vec3d positionGps2Lla; /**< GPS2 latitude, longitude, altitude data. */
|
||||
vec3d positionGps2Ecef; /**< GPS2 earth-centered, earth-fixed data. */
|
||||
vec3f velocityGps2Ned; /**< GPS2 velocity NED data. */
|
||||
vec3f velocityGps2Ecef; /**< GPS2 velocity ECEF data. */
|
||||
uint16_t weekGps2; /**< GPS2 Week data. */
|
||||
uint8_t fixGps2; /**< GPS2 fix data. */
|
||||
uint8_t numSatsGps2; /**< GPS2 NumSats data. */
|
||||
uint64_t timeGps2; /**< GPS2 TimeGps data. */
|
||||
uint64_t timeGps2Pps; /**< GPS2 TimeGpsPps data. */
|
||||
uint64_t gps2Tow; /**< GPS2 GpsTow data. */
|
||||
float velocityUncertaintyGps2; /**< GPS2velocity uncertainty data. */
|
||||
vec3f positionUncertaintyGps2Ned; /**< GPS2 position uncertainty NED data. */
|
||||
vec3f positionUncertaintyGps2Ecef; /**< GPS2 position uncertainty ECEF data. */
|
||||
uint32_t timeUncertaintyGps2; /**< GPS2 Time uncertainty data. */
|
||||
TimeInfo timeInfo;
|
||||
GpsDop dop;
|
||||
} VnCompositeData;
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Indicates if course over ground has valid data
|
||||
*
|
||||
* \param[in] compositeData The associated VnCompositeData structure.
|
||||
* \return Flag indicating if the course over ground data is available. */
|
||||
bool VnCompositeData_hasCourseOverGround(VnCompositeData* compositeData);
|
||||
|
||||
/** \brief Computers the course over ground from any velocity data available
|
||||
*
|
||||
* \param[in] compositeData The associated VnCompositeData structure.
|
||||
* \param[out] courseOverGroundOut The computered course over ground.
|
||||
* \return Flag indicating if the calculation was successful. */
|
||||
bool VnCompositeData_courseOverGround(VnCompositeData* compositeData, float* courseOverGroundOut);
|
||||
|
||||
/** \brief Indicates if speed over ground has valid data..
|
||||
*
|
||||
* \param[in] compositeData The associated VnCompositeData structure.
|
||||
* \return Flag indicating if the speed over ground data is available. */
|
||||
bool VnCompositeData_hasSpeedOverGround(VnCompositeData* compositeData);
|
||||
|
||||
/** \brief Computers the speed over ground from any velocity data available
|
||||
*
|
||||
* \param[in] compositeData The associated VnCompositeData structure.
|
||||
* \param[out] speedOverGroundOut The computered course over ground.
|
||||
* \return Flag indicating if the calculation was successful. */
|
||||
bool VnCompositeData_speedOverGround(VnCompositeData* compositeData, float* speedOverGroundOut);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_initialize(VnCompositeData* compositeData);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacket(VnCompositeData* compositeData, VnUartPacket* packet, VnCriticalSection* criticalSection);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processAsciiAsyncPacket(VnCompositeData* compositeData, VnUartPacket* packet, VnCriticalSection* criticalSection);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketCommonGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
CommonGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketTimeGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
TimeGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketImuGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
ImuGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketGpsGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
GpsGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketAttitudeGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
AttitudeGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketInsGroup(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
InsGroup groupFlags);
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* \param[in]
|
||||
* \param[out]
|
||||
* \return
|
||||
*/
|
||||
void VnCompositeData_processBinaryPacketGps2Group(
|
||||
VnCompositeData* compositeData,
|
||||
VnUartPacket* packet,
|
||||
GpsGroup groupFlags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef _VNEZASYNCDATA_H_
|
||||
#define _VNEZASYNCDATA_H_
|
||||
|
||||
#include "vn/int.h"
|
||||
#include "vn/error.h"
|
||||
#include "vn/sensors/compositedata.h"
|
||||
#include "vn/sensors.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Structure supporting easy and reliable access to asynchronous data
|
||||
* from a VectorNav sensor at the cost of a slight performance hit. */
|
||||
typedef struct
|
||||
{
|
||||
/** \brief The associated connected sensor. */
|
||||
VnSensor* sensor;
|
||||
|
||||
/** \brief Critical section for accessing the current data. */
|
||||
VnCriticalSection* curDataCS;
|
||||
|
||||
/** \brief The current data received from asynchronous data packets. */
|
||||
VnCompositeData* curData;
|
||||
|
||||
} VnEzAsyncData;
|
||||
|
||||
/** \brief Initializes and connects to a VectorNav sensor with the specified
|
||||
* connection parameters.
|
||||
*
|
||||
* \param[in] ezAsyncData The associated VnEzAsyncData structure.
|
||||
* \param]in] portName The name of the serial port to connect to.
|
||||
* \param[in] baudrate The baudrate to connect at.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEzAsyncData_initializeAndConnect(VnEzAsyncData* ezAsyncData, const char* portName, uint32_t baudrate);
|
||||
|
||||
/** \brief Disconnects from a VectorNav sensor.
|
||||
*
|
||||
* \param[in] ezAsyncData The associated VnEzAsyncData structure.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEzAsyncData_disconnectAndUninitialize(VnEzAsyncData* ezAsyncData);
|
||||
|
||||
/** \brief Returns the most recent asynchronous data the VnEzAsyncData structure
|
||||
* has processed.
|
||||
*
|
||||
* \param[in] ezAsyncData The associated VnEzAsyncData structure.
|
||||
* \return The latest data processed. */
|
||||
VnCompositeData VnEzAsyncData_currentData(VnEzAsyncData* ezAsyncData);
|
||||
|
||||
/** \brief Returns the underlying VnSensor referenced.
|
||||
*
|
||||
* \param[in] ezAsyncData The associated VnEzAsyncData structure.
|
||||
* \return The underlying VnSensor reference. */
|
||||
VnSensor* VnEzAsyncData_sensor(VnEzAsyncData* ezAsyncData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
#ifndef _SEARCHER_H_
|
||||
#define _SEARCHER_H_
|
||||
|
||||
#include "vn/bool.h"
|
||||
#include "vn/int.h"
|
||||
#include "vn/xplat/serialport.h"
|
||||
#include "vn/xplat/thread.h"
|
||||
|
||||
/* These defines are used to enable a single function name while implementing */
|
||||
/* different solutions given the OS. */
|
||||
#if defined __linux__ || defined __CYGWIN__ || defined __NUTTX__
|
||||
#define VnSearcher_findPorts VnSearcher_findPorts_LINUX
|
||||
#elif defined _WIN32
|
||||
#define VnSearcher_findPorts VnSearcher_findPorts_WIN32
|
||||
#else
|
||||
#error ERROR: System not yet supported in VnSearcher
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4820)
|
||||
#endif
|
||||
|
||||
/** \brief containing information about the port to be searched. */
|
||||
typedef struct
|
||||
{
|
||||
/** \brief Contains the name of the port. */
|
||||
char* portName;
|
||||
|
||||
/** \brief VnThread object for callback purposes. */
|
||||
VnThread thread;
|
||||
|
||||
/** \brief Baud of the attached senosr, -1 for no sensor, -2 for error. */
|
||||
int32_t baud;
|
||||
|
||||
/** \brief size of the data array */
|
||||
size_t dataSize;
|
||||
|
||||
/** \brief VnSerialPort object to handle communication to the sensor. */
|
||||
VnSerialPort* port;
|
||||
|
||||
/** \brief Array to store partial/completed communication data from the sensor. */
|
||||
char data[255];
|
||||
} VnPortInfo;
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Takes a VnPortInfo and returns the name of the port.
|
||||
* \parm[in] portInfo Pointer to a VnPortInfo struct
|
||||
* \return The name of the port
|
||||
*/
|
||||
char* VnSearcher_getPortName(VnPortInfo* portInfo);
|
||||
|
||||
/** \brief Takes a VnPortInfo and returns the baud rate or error code.
|
||||
* \parm[in] portInfo Pointer to a VnPortInfo struct
|
||||
* \return The baud rate of the port or an error code.
|
||||
* -1 indicates no sensor on the port.
|
||||
* -2 indicates an error trying to find a sensor.
|
||||
*/
|
||||
int32_t VnSearcher_getPortBaud(VnPortInfo* portInfo);
|
||||
|
||||
/** \brief Function to find the names of all of the system's serial ports.
|
||||
* \parm[out] portNames Array containing the names of all of the serial ports.
|
||||
* \parm[out] numPortsFound Number of serial ports found.
|
||||
*/
|
||||
void VnSearcher_findPorts(char*** portNames, int32_t* numPortsFound);
|
||||
|
||||
/** \brief Function to search an input port and return either the baud rate of the connected
|
||||
* sensor or an error code.
|
||||
* \parm[in] portName The system name of the port to be searched.
|
||||
* \parm[out] foundBaudrate Baud rate of the attacked sensor, -1 for no sensor, -2 for error
|
||||
*/
|
||||
void VnSearcher_findPortBaud(char* portName, int32_t* foundBaudrate);
|
||||
|
||||
/** \brief Convenience function to find all available sensors currently attached
|
||||
* to the system.
|
||||
* \parm[out] sensorsFound Pointer to an array of sensors attached to the system.
|
||||
* \parm[out] numSensors The number of sensors found.
|
||||
*/
|
||||
void VnSearcher_findAllSensors(VnPortInfo*** sensorsFound, int32_t* numSensors);
|
||||
|
||||
/** \brief Function that will search all of the input ports to see if an available sensor is attached to it.
|
||||
* NOTE: The OS will not allow the detection of sensor that is in use.
|
||||
* \parm[in] portsToCheck Array containing the names of all the ports to check.
|
||||
* \parm[in] Number of ports to check.
|
||||
* \parm[out] An array of VnPortInfo structs the same size as numPortsToCheck. The baud rate will indicate
|
||||
* if a sensor is attached. baud > 0 is the sensor baudrate, baud = -1 no sensor attached, and baud = -2
|
||||
* an error occured while detecting the sensor.
|
||||
*/
|
||||
void VnSearcher_searchInputPorts(char*** portsToCheck, int32_t numPortsToCheck, VnPortInfo*** sensorsFound);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef VN_TYPES_H_INCLUDED
|
||||
#define VN_TYPES_H_INCLUDED
|
||||
|
||||
/** \brief Standard types used through out the library. */
|
||||
#include "vn/int.h"
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__)
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Must not have C99. */
|
||||
|
||||
/** Backup definition of size_t. */
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Adding VectorNav data types */
|
||||
typedef struct
|
||||
{
|
||||
int8_t year; /** \brief Year field. */
|
||||
uint8_t month; /** \brief Month field. */
|
||||
uint8_t day; /** \brief Day field. */
|
||||
uint8_t hour; /** \brief Hour field. */
|
||||
uint8_t min; /** \brief Min field. */
|
||||
uint8_t sec; /** \brief Sec field. */
|
||||
uint16_t ms; /** \brief Ms field. */
|
||||
} TimeUtc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float gDOP; /** \brief Gdop field. */
|
||||
float pDOP; /** \brief Pdop field. */
|
||||
float tDOP; /** \brief Tdop field. */
|
||||
float vDOP; /** \brief Vdop field. */
|
||||
float hDOP; /** \brief Hdop field. */
|
||||
float nDOP; /** \brief Ndop field. */
|
||||
float eDOP; /** \brief Edop field. */
|
||||
} GpsDop;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t timeStatus; /** \brief timeStatus field. */
|
||||
int8_t leapSeconds; /** \brief leapSeconds field. */
|
||||
} TimeInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,273 @@
|
||||
#ifndef VNUTIL_H_INCLUDED
|
||||
#define VNUTIL_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "vn/int.h"
|
||||
#include "vn/bool.h"
|
||||
#include "vn/error.h"
|
||||
#include "vn/math/matrix.h"
|
||||
#include "vn/math/vector.h"
|
||||
#include "vn/util/export.h"
|
||||
#include "vn/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Defines for the specific version of the VectorNav library. */
|
||||
#define VNAPI_MAJOR 1
|
||||
#define VNAPI_MINOR 2
|
||||
#define VNAPI_PATCH 0
|
||||
#define VNAPI_REVISION 126
|
||||
|
||||
/** \brief Returns the major version of the VectorNav library.
|
||||
*
|
||||
* \return The major version. */
|
||||
int VnApi_major(void);
|
||||
|
||||
/** \brief Returns the minor version of the VectorNav library.
|
||||
*
|
||||
* \return The minor version. */
|
||||
int VnApi_minor(void);
|
||||
|
||||
/** \brief Returns the patch version of the VectorNav library.
|
||||
*
|
||||
* \return The patch version. */
|
||||
int VnApi_patch(void);
|
||||
|
||||
/** \brief Returns the revision version of the VectorNav library.
|
||||
*
|
||||
* \return The revision version. */
|
||||
int VnApi_revision(void);
|
||||
|
||||
/** \brief Returns the full version of the VectorNav library as a string.
|
||||
*
|
||||
* \param[out] out The buffer to place the string.
|
||||
* \param[in] outLength The number of characters available in the out buffer.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnApi_getVersion(char *out, size_t outLength);
|
||||
|
||||
/** \brief Converts the single hexadecimal character to a uint8_t.
|
||||
*
|
||||
* \param[in] c The hexadecimal character to convert.
|
||||
* \return The converted value.
|
||||
*/
|
||||
uint8_t VnUtil_toUint8FromHexChar(char c);
|
||||
|
||||
/** \brief Converts a 2 character hexadecimal string to a uint8_t.
|
||||
*
|
||||
* \param[in] str Pointer to 2 characters representing a hexadecimal
|
||||
* number.
|
||||
* \return The converted value.
|
||||
*/
|
||||
uint8_t VnUtil_toUint8FromHexStr(char const *str);
|
||||
|
||||
/** \brief Converts a 4 character hexadecimal string to a uint16_t.
|
||||
*
|
||||
* \param[in] str Pointer to 4 characters representing a hexadecimal
|
||||
* number.
|
||||
* \return The converted value.
|
||||
*/
|
||||
uint16_t VnUtil_toUint16FromHexStr(char const *str);
|
||||
|
||||
/** \brief Converts a uint8_t to a hexadecimal string.
|
||||
*
|
||||
* \param[in] toConvert The uint8_t to convert.
|
||||
* \param[in] output Pointer to the char array to write the converted value.
|
||||
* This will take 2 bytes for the output.
|
||||
*/
|
||||
void VnUtil_toHexStrFromUint8(uint8_t toConvert, char *output);
|
||||
|
||||
/** \brief Converts a uint16_t to a hexadecimal string.
|
||||
*
|
||||
* \param[in] toConvert The uint16_t to convert.
|
||||
* \param[in] output Pointer to the char array to write the converted value.
|
||||
* This will take 4 bytes for the output.
|
||||
*/
|
||||
void VnUtil_toHexStrFromUint16(uint16_t toConvert, char *output);
|
||||
|
||||
/** \brief Converts a uint16_t to a string.
|
||||
*
|
||||
* \param[in] toConvert The uint16_t to convert.
|
||||
* \param[in] output Pointer to the char array to write the converted value.
|
||||
* \return The number of characters that were written.
|
||||
*/
|
||||
size_t VnUtil_toStrFromUint16(uint16_t toConvert, char *output);
|
||||
|
||||
/** \brief Returns the number of bits set.
|
||||
*
|
||||
* \param[in] data The data value to count the number of bits set.
|
||||
* \return The number of bits set.
|
||||
*/
|
||||
uint8_t DllExport VnUtil_countSetBitsUint8(uint8_t data);
|
||||
|
||||
/** \brief Converts a boolean value into a string.
|
||||
*
|
||||
* \param[out] out The value converted to a string.
|
||||
* \param[in] val The value to convert.
|
||||
*/
|
||||
void strFromBool(char *out, bool val);
|
||||
|
||||
/** \defgroup byteOrderers Byte Ordering Functions
|
||||
* \brief This group of functions are useful for ordering of bytes
|
||||
* sent/received from VectorNav sensors.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
/** \brief Converts a 16-bit integer in sensor order to host order.
|
||||
*
|
||||
* \param[in] sensorOrdered The 16-bit integer in sensor order.
|
||||
* \return The value converted to host ordered. */
|
||||
uint16_t stoh16(uint16_t sensorOrdered);
|
||||
|
||||
/** \brief Converts a 32-bit integer in sensor order to host order.
|
||||
*
|
||||
* \param[in] sensorOrdered The 32-bit integer in sensor order.
|
||||
* \return The value converted to host ordered. */
|
||||
uint32_t stoh32(uint32_t sensorOrdered);
|
||||
|
||||
/** \brief Converts a 64-bit integer in sensor order to host order.
|
||||
*
|
||||
* \param[in] sensorOrdered The 64-bit integer in sensor order.
|
||||
* \return The value converted to host ordered. */
|
||||
uint64_t stoh64(uint64_t sensorOrdered);
|
||||
|
||||
/** \brief Converts a 16-bit integer in host order to sensor order.
|
||||
*
|
||||
* \param[in] hostOrdered The 16-bit integer in host order.
|
||||
* \return The value converted to sensor ordered. */
|
||||
uint16_t htos16(uint16_t hostOrdered);
|
||||
|
||||
/** \brief Converts a 32-bit integer in host order to sensor order.
|
||||
*
|
||||
* \param[in] hostOrdered The 32-bit integer in host order.
|
||||
* \return The value converted to sensor ordered. */
|
||||
uint32_t htos32(uint32_t hostOrdered);
|
||||
|
||||
/** \brief Converts a 64-bit integer in host order to sensor order.
|
||||
*
|
||||
* \param[in] hostOrdered The 64-bit integer in host order.
|
||||
* \return The value converted to sensor ordered. */
|
||||
uint64_t htos64(uint64_t hostOrdered);
|
||||
|
||||
/** \brief Converts a 4-byte float in host order to sensor order.
|
||||
*
|
||||
* \param[in] hostOrdered The 4-byte float in host order.
|
||||
* \return The value converted to sensor ordered. */
|
||||
float htosf4(float hostOrdered);
|
||||
|
||||
/** \brief Converts an 8-byte float in host order to sensor order.
|
||||
*
|
||||
* \param[in] hostOrdered The 8-byte float in host order.
|
||||
* \return The value converted to sensor ordered. */
|
||||
double htosf8(double hostOrdered);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup sensorValueExtractors Sensor Value Extractors
|
||||
* \brief This group of methods is useful for extracting data from binary
|
||||
* data received from a VectorNav sensor either from a UART binary or a
|
||||
* SPI packet. Any necessary byte ordering will be performed.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
/** \brief Extracts a uint16_t with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
uint16_t VnUtil_extractUint16(const char* pos);
|
||||
|
||||
/** \brief Extracts a uint32_t with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
uint32_t VnUtil_extractUint32(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>float</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
float VnUtil_extractFloat(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>double</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
double VnUtil_extractDouble(const char* pos);
|
||||
|
||||
/*#if THIS_SHOULD_BE_MOVED_TO_MATH_C_PACK*/
|
||||
|
||||
/** \brief Extracts a <c>vec3f</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
vec3f VnUtil_extractVec3f(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>vec4f</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
vec4f VnUtil_extractVec4f(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>vec3d</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
vec3d VnUtil_extractVec3d(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>mat3f</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
mat3f VnUtil_extractMat3f(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>GpsDop</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
GpsDop VnUtil_extractGpsDop(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>TimeUtc</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
TimeUtc VnUtil_extractTimeUtc(const char* pos);
|
||||
|
||||
/** \brief Extracts a <c>TimeInfo</c> with appropriate byte reordering from the binary
|
||||
* array received from a VectorNav sensor either from the UART binary or
|
||||
* SPI packet.
|
||||
*
|
||||
* \param[in] pos The current position to extract the value from.
|
||||
* \return The extracted value. */
|
||||
TimeInfo VnUtil_extractTimeInfo(const char* pos);
|
||||
|
||||
/*#endif*/
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _VN_UTIL_COMPILER_H
|
||||
#define _VN_UTIL_COMPILER_H
|
||||
|
||||
/* This header provides some simple checks for various features supported by the
|
||||
* current compiler. */
|
||||
|
||||
/* Determine the level of standard C support. */
|
||||
#if __STDC__
|
||||
#if defined (__STDC_VERSION__)
|
||||
#if (__STDC_VERSION__ >= 199901L)
|
||||
#define C99
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Determine if the compiler has stdbool.h. */
|
||||
#if defined(C99) || _MSC_VER >= 1800
|
||||
#define VN_HAVE_STDBOOL_H 1
|
||||
#else
|
||||
#define VN_HAVE_STDBOOL_H 0
|
||||
#endif
|
||||
|
||||
/* Determine if the secure CRT is available. */
|
||||
#if defined(_MSC_VER)
|
||||
#define VN_HAVE_SECURE_CRT 1
|
||||
#else
|
||||
#define VN_HAVE_SECURE_CRT 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Determine if the generic type math library (tgmath.h) is available. */
|
||||
#if defined(C99)
|
||||
#define VN_HAVE_GENERIC_TYPE_MATH 1
|
||||
#else
|
||||
#define VN_HAVE_GENERIC_TYPE_MATH 0
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef VNEXPORT_H_INCLUDED
|
||||
#define VNEXPORT_H_INCLUDED
|
||||
|
||||
/* Not only does this have to be windows to use __declspec */
|
||||
/* it also needs to actually be outputting a DLL */
|
||||
#if defined _WINDOWS && defined _WINDLL
|
||||
#if proglib_c_EXPORTS
|
||||
#define DllExport __declspec(dllexport)
|
||||
#else
|
||||
#define DllExport __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DllExport
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef VNPORT_H_INCLUDED
|
||||
#define VNPORT_H_INCLUDED
|
||||
|
||||
/** Basic portability measures. */
|
||||
|
||||
/** VNAPI - DLL linkage specifier. */
|
||||
#ifdef _MSC_VER
|
||||
#if VN_LINKED_AS_SHARED_LIBRARY
|
||||
#define VNAPI __declspec(dllimport)
|
||||
#elif VN_CREATE_SHARED_LIBRARY
|
||||
#define VNAPI __declspec(dllexport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef VNAPI
|
||||
#define VNAPI
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef VECTORNAV_H
|
||||
#define VECTORNAV_H
|
||||
|
||||
#include "vnbool.h"
|
||||
#include "vnenum.h"
|
||||
#include "vnutil.h"
|
||||
#include "vnupackf.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/** \file
|
||||
* {COMMON_HEADER}
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
* This header file contains structures and functions useful for critical sections.
|
||||
*/
|
||||
#ifndef _VN_CRITICALSECTION_H_
|
||||
#define _VN_CRITICALSECTION_H_
|
||||
|
||||
#include "vn/error.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Disable some warnings for Visual Studio with -Wall. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668)
|
||||
#pragma warning(disable:4820)
|
||||
#pragma warning(disable:4255)
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if _WIN32
|
||||
CRITICAL_SECTION handle;
|
||||
#elif __linux__ || __APPLE__ || __CYGWIN__ || __QNXNTO__ || __NUTTX__
|
||||
pthread_mutex_t handle;
|
||||
#else
|
||||
#error "Unknown System"
|
||||
#endif
|
||||
} VnCriticalSection;
|
||||
|
||||
/** \breif Initializes a VnCriticalSection structure.
|
||||
*
|
||||
* \param[in] criticalSection The VnCriticalSection structure to initialize.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnCriticalSection_initialize(VnCriticalSection *criticalSection);
|
||||
|
||||
/** \brief Disposes of a VnCriticalSection structure and associated resources.
|
||||
*
|
||||
* \param[in] criticalSection The associated VnCriticalSection structure.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnCriticalSection_deinitialize(VnCriticalSection *criticalSection);
|
||||
|
||||
/** \brief Attempt to enter a critical section.
|
||||
*
|
||||
* \param[in] criticalSection The associated VnCriticalSection structure.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnCriticalSection_enter(VnCriticalSection *criticalSection);
|
||||
|
||||
/** \brief Leave a critical section.
|
||||
*
|
||||
* \param[in] criticalSection The associated VnCriticalSection structure.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnCriticalSection_leave(VnCriticalSection *criticalSection);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
/** \file
|
||||
* {COMMON_HEADER}
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
* This header file contains structures and functions useful events and signals.
|
||||
*/
|
||||
#ifndef _VNEVENT_H_
|
||||
#define _VNEVENT_H_
|
||||
|
||||
#include "vn/int.h"
|
||||
#include "vn/error.h"
|
||||
#include "vn/bool.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Disable some warnings for Visual Studio with -Wall. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668)
|
||||
#pragma warning(disable:4820)
|
||||
#pragma warning(disable:4255)
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Structure representing an event. */
|
||||
typedef struct
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
#elif (defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__)
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t condition;
|
||||
bool isTriggered;
|
||||
#else
|
||||
#error "Unknown System"
|
||||
#endif
|
||||
} VnEvent;
|
||||
|
||||
/** \brief Initializes a VnEvent structure.
|
||||
*
|
||||
* \param[in] event The VnEvent structure to initialize.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEvent_initialize(VnEvent *event);
|
||||
|
||||
/** \brief Causes the calling thread to wait on an event until the event is signalled.
|
||||
*
|
||||
* If the event is signalled, the value E_SIGNALED will be returned.
|
||||
*
|
||||
* \param[in] event The associated VnEvent.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEvent_wait(VnEvent *event);
|
||||
|
||||
/** \brief Causes the calling thread to wait on an event until the event is signalled.
|
||||
*
|
||||
* If the event is signalled, the value E_SIGNALED will be returned.
|
||||
*
|
||||
* \param[in] event The associated VnEvent.
|
||||
* \param[in] timeoutUs The number of microseconds to wait before the thread stops waiting on the event. If a timeout
|
||||
* does occur, the value E_TIMEOUT will be returned.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEvent_waitUs(VnEvent *event, uint32_t timeoutUs);
|
||||
|
||||
/** \brief Causes the calling thread to wait on an event until the event is signalled.
|
||||
*
|
||||
* If the event is signalled, the value E_SIGNALED will be returned.
|
||||
*
|
||||
* \param[in] event The associated VnEvent.
|
||||
* \param[in] timeoutMs The number of milliseconds to wait before the thread stops waiting on the event. If a timeout
|
||||
* does occur, the value E_TIMEOUT will be returned.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEvent_waitMs(VnEvent *event, uint32_t timeoutMs);
|
||||
|
||||
/** \brief Signals an event.
|
||||
*
|
||||
* \param[in] event The associated event.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnEvent_signal(VnEvent *event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,149 @@
|
||||
#ifndef VN_SERIALPORT_H
|
||||
#define VN_SERIALPORT_H
|
||||
|
||||
/** Cross-platform access to serial ports. */
|
||||
|
||||
#include "vn/int.h"
|
||||
#include "vn/error.h"
|
||||
#include "vn/bool.h"
|
||||
#include "vn/xplat/thread.h"
|
||||
#include "vn/xplat/criticalsection.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
/* Disable some warnings for Visual Studio with -Wall. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668)
|
||||
#pragma warning(disable:4820)
|
||||
#pragma warning(disable:4255)
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/serial.h>
|
||||
#elif defined __APPLE__
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Type for listening to data received events from the VnSerialPort. */
|
||||
typedef void (*VnSerialPort_DataReceivedHandler)(void *userData);
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4820)
|
||||
#endif
|
||||
|
||||
/** \brief Provides access to a serial port. */
|
||||
typedef struct
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
/* Windows appears to need single-thread access to read/write API functions. */
|
||||
VnCriticalSection readWriteCS;
|
||||
#elif (defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__)
|
||||
int handle;
|
||||
#else
|
||||
#error "Unknown System"
|
||||
#endif
|
||||
|
||||
bool purgeFirstDataBytesWhenSerialPortIsFirstOpened;
|
||||
|
||||
VnSerialPort_DataReceivedHandler dataReceivedHandler;
|
||||
|
||||
void *dataReceivedHandlerUserData;
|
||||
|
||||
VnThread serialPortNotificationsThread;
|
||||
|
||||
bool continueHandlingSerialPortEvents;
|
||||
|
||||
size_t numberOfReceiveDataDroppedSections;
|
||||
|
||||
VnCriticalSection dataReceivedHandlerCriticalSection;
|
||||
|
||||
char portName[50];
|
||||
|
||||
} VnSerialPort;
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Initializes a VnSerialPort structure.
|
||||
*
|
||||
* \param[in] serialport The VnSerialPort structure to initialize.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_initialize(VnSerialPort *serialport);
|
||||
|
||||
/** \brief Opens a serial port.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort structure.
|
||||
* \param[in] portName The name of the serial port to open.
|
||||
* \param[in] baudrate The baudrate to open the serial port at.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_open(VnSerialPort *serialport, char const *portName, uint32_t baudrate);
|
||||
|
||||
/** \brief Closes the serial port.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort structure.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_close(VnSerialPort *serialport);
|
||||
|
||||
/** \brief Indicates if the serial port is open or not.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort structure.
|
||||
* \return <c>true</c> if the serial port is open; otherwise <c>false</c>. */
|
||||
bool VnSerialPort_isOpen(VnSerialPort *serialport);
|
||||
|
||||
/** \brief Reads data from a serial port.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort structure.
|
||||
* \param[in] buffer Buffer to place the read bytes.
|
||||
* \param[in] numOfBytesToRead The number of bytes to read from the serial port.
|
||||
* \param[out] numOfBytesActuallyRead The number of bytes actually read from the serial port.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_read(VnSerialPort *serialport, char *buffer, size_t numOfBytesToRead, size_t *numOfBytesActuallyRead);
|
||||
|
||||
/** \brief Writes data out of a serial port.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort.
|
||||
* \param[in] data The data to write out.
|
||||
* \param[in] numOfBytesToWrite The number of bytes to write out of the serial port.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_write(VnSerialPort *serialport, char const *data, size_t numOfBytesToWrite);
|
||||
|
||||
/** \brief Changes the baudrate the port is connected at.
|
||||
*
|
||||
* \param[in] serialport The associated VnSerialPort.
|
||||
* \param[in] baudrate The new baudrate.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_changeBaudrate(VnSerialPort *serialport, uint32_t baudrate);
|
||||
|
||||
/** \brief Allows registering for notification of data received events.
|
||||
*
|
||||
* \param[in] serialPort The associated VnSerialPort.
|
||||
* \param[in] handler The callback method to receive notifications.
|
||||
* \param[in] userData User supplied data that will be sent to the handler on callbacks.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnSerialPort_registerDataReceivedHandler(VnSerialPort *serialPort, VnSerialPort_DataReceivedHandler handler, void *userData);
|
||||
|
||||
/** \brief Allows unregistering for notification of data received events.
|
||||
*
|
||||
* \param[in] serialPort The associated VnSerialPort. */
|
||||
VnError VnSerialPort_unregisterDataReceivedHandler(VnSerialPort *serialPort);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/** \file
|
||||
* {COMMON_HEADER}
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
* This header file contains structures and functions useful working with threads.
|
||||
*/
|
||||
#ifndef _VN_THREAD_H_
|
||||
#define _VN_THREAD_H_
|
||||
|
||||
#include "vn/error.h"
|
||||
#include "vn/int.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Disable some warnings for Visual Studio with -Wall. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668)
|
||||
#pragma warning(disable:4820)
|
||||
#pragma warning(disable:4255)
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Structure for working with threads. */
|
||||
typedef struct
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
#elif defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__ || defined __NUTTX__
|
||||
pthread_t handle;
|
||||
#else
|
||||
#error "Unknown System"
|
||||
#endif
|
||||
} VnThread;
|
||||
|
||||
/** \brief Function signature for a start routine for a thread. */
|
||||
typedef void (*VnThread_StartRoutine)(void*);
|
||||
|
||||
/** \brief Starts a new thread immediately which calls the provided start routine.
|
||||
*
|
||||
* \param[in] thread Associated VnThread structure.
|
||||
* \param[in] startRoutine The routine to be called when the new thread is started.
|
||||
* \param[in] routineData Pointer to data that will be passed to the routine on the new thread.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnThread_startNew(VnThread *thread, VnThread_StartRoutine startRoutine, void* routineData);
|
||||
|
||||
/** \brief Blocks the calling thread until the referenced thread finishes.
|
||||
*
|
||||
* \param[in] thread The associated VnThread.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnThread_join(VnThread *thread);
|
||||
|
||||
/** \brief Causes the calling thread to sleep the specified number of seconds.
|
||||
*
|
||||
* \param[in] numOfSecsToSleep The number of seconds to sleep. */
|
||||
void VnThread_sleepSec(uint32_t numOfSecsToSleep);
|
||||
|
||||
/** \brief Causes the calling thread to sleep the specified number of milliseconds
|
||||
*
|
||||
* \param[in] numOfMsToSleep The number of milliseconds to sleep. */
|
||||
void VnThread_sleepMs(uint32_t numOfMsToSleep);
|
||||
|
||||
/** \brief Causes the calling thread to sleep the specified number of microseconds
|
||||
*
|
||||
* \param[in] numOfUsToSleep The number of microseconds to sleep. */
|
||||
void VnThread_sleepUs(uint32_t numOfUsToSleep);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/** \file
|
||||
* {COMMON_HEADER}
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
* This header file contains structures and functions useful timing.
|
||||
*/
|
||||
#ifndef _VNTIME_H_
|
||||
#define _VNTIME_H_
|
||||
|
||||
#include "vn/int.h"
|
||||
#include "vn/error.h"
|
||||
#include "vn/enum.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Disable some warnings for Visual Studio with -Wall. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668)
|
||||
#pragma warning(disable:4820)
|
||||
#pragma warning(disable:4255)
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Provides simple timing capabilities. */
|
||||
typedef struct
|
||||
{
|
||||
#if _WIN32
|
||||
double pcFrequency;
|
||||
__int64 counterStart;
|
||||
#elif __linux__ || __APPLE__ ||__CYGWIN__ || __QNXNTO__ || defined __NUTTX__
|
||||
double clockStart;
|
||||
#else
|
||||
#error "Unknown System"
|
||||
#endif
|
||||
} VnStopwatch;
|
||||
|
||||
/** \brief Initializes and starts a stopwatch.
|
||||
*
|
||||
* \param[in] stopwatch The VnStopwatch to initialize and start.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnStopwatch_initializeAndStart(VnStopwatch *stopwatch);
|
||||
|
||||
/** \brief Resets the stopwatch's timing.
|
||||
*
|
||||
* \param[in] stopwatch The associated VnStopwatch.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnStopwatch_reset(VnStopwatch *stopwatch);
|
||||
|
||||
/** \brief Determines the number of milliseconds elapsed since the last reset
|
||||
* of the stopwatch.
|
||||
*
|
||||
* \param[in] stopwatch The associated VnStopwatch.
|
||||
* \param[out] elapsedMs The elapsed time in milliseconds.
|
||||
* \return Any errors encountered. */
|
||||
VnError VnStopwatch_elapsedMs(VnStopwatch *stopwatch, float *elapsedMs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "vn/conv.h"
|
||||
#include <math.h>
|
||||
#include "vn/const.h"
|
||||
|
||||
#define C_E2 (0.006694379990141)
|
||||
#define C_EPSILON (0.996647189335253)
|
||||
#define C_ABAR (42.69767270717997)
|
||||
#define C_BBAR (42.84131151331357)
|
||||
#define C_A (6378.137)
|
||||
|
||||
vec3d ecef_to_lla_v3d(vec3d ecef)
|
||||
{
|
||||
double x, y, z, r, c_phi, c_phi0, s_phi,
|
||||
s_phi0, tau, lat, lon, /*alt,*/ eta, h;
|
||||
|
||||
const double Rthresh = 0.001; /* Limit on distance from pole in km to switch calculation. */
|
||||
|
||||
x = ecef.c[0];
|
||||
y = ecef.c[1];
|
||||
z = ecef.c[2];
|
||||
|
||||
r = sqrt(x*x + y*y);
|
||||
|
||||
if (r < Rthresh)
|
||||
{
|
||||
c_phi0 = 0;
|
||||
s_phi0 = (z > 0) - (z < 0); /* computes sign */
|
||||
}
|
||||
else
|
||||
{
|
||||
double tau0 = z / (C_EPSILON * r);
|
||||
c_phi0 = 1 / sqrt(1 + tau0 * tau0);
|
||||
s_phi0 = tau0 * c_phi0;
|
||||
}
|
||||
|
||||
tau = (z + C_BBAR * s_phi0 * s_phi0 * s_phi0) / (r - C_ABAR * c_phi0 * c_phi0 * c_phi0);
|
||||
lat = atan(tau);
|
||||
|
||||
if (r < Rthresh)
|
||||
{
|
||||
c_phi = 0;
|
||||
s_phi = (z > 0) - (z < 0); /* computes sign */
|
||||
}
|
||||
else
|
||||
{
|
||||
c_phi = 1 / sqrt(1 + tau * tau);
|
||||
s_phi = tau * c_phi;
|
||||
}
|
||||
|
||||
eta = sqrt(1 - C_E2 * s_phi * s_phi);
|
||||
h = r * c_phi + z * s_phi - C_A * eta;
|
||||
|
||||
lon = atan2(y, x);
|
||||
|
||||
return create_v3d(
|
||||
lat * 180 / VNC_PI_D,
|
||||
lon * 180 / VNC_PI_D,
|
||||
h * 1000
|
||||
);
|
||||
}
|
||||
|
||||
vec3d lla_to_ecef_v3d(vec3d lla)
|
||||
{
|
||||
double lat, lon, alt;
|
||||
double n, x, y, z;
|
||||
double t1; /* TEMPS */
|
||||
|
||||
lat = lla.c[0] * VNC_PI_D / 180; /* Geodetic latitude in radians. */
|
||||
lon = lla.c[1] * VNC_PI_D / 180; /* Longitude in radians. */
|
||||
alt = lla.c[2] / 1000; /* Altitude above WGS84 in km. */
|
||||
|
||||
t1 = sin(lat);
|
||||
n = C_A / sqrt(1 - C_E2 * t1 * t1);
|
||||
|
||||
t1 = alt + n;
|
||||
x = t1 * cos(lat) * cos(lon);
|
||||
y = t1 * cos(lat) * sin(lon);
|
||||
z = (t1 - C_E2 * n) * sin(lat);
|
||||
|
||||
return create_v3d(x, y, z);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
#include "vn/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void strFromVnError(char* out, VnError val)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
/* Disable warnings regarding using strcpy_s since this
|
||||
* function's signature does not provide us with information
|
||||
* about the length of 'out'. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case E_NONE:
|
||||
strcpy(out, "NONE");
|
||||
break;
|
||||
case E_UNKNOWN:
|
||||
strcpy(out, "UNKNOWN");
|
||||
break;
|
||||
case E_BUFFER_TOO_SMALL:
|
||||
strcpy(out, "BUFFER_TOO_SMALL");
|
||||
break;
|
||||
case E_INVALID_VALUE:
|
||||
strcpy(out, "INVALID_VALUE");
|
||||
break;
|
||||
case E_NOT_IMPLEMENTED:
|
||||
strcpy(out, "NOT_IMPLEMENTED");
|
||||
break;
|
||||
case E_NOT_SUPPORTED:
|
||||
strcpy(out, "NOT_SUPPORTED");
|
||||
break;
|
||||
case E_NOT_FOUND:
|
||||
strcpy(out, "NOT_FOUND");
|
||||
break;
|
||||
case E_TIMEOUT:
|
||||
strcpy(out, "TIMEOUT");
|
||||
break;
|
||||
case E_PERMISSION_DENIED:
|
||||
strcpy(out, "PERMISSION_DENIED");
|
||||
break;
|
||||
case E_INVALID_OPERATION:
|
||||
strcpy(out, "INVALID_OPERATION");
|
||||
break;
|
||||
case E_SIGNALED:
|
||||
strcpy(out, "SIGNALED");
|
||||
break;
|
||||
case E_SENSOR_HARD_FAULT:
|
||||
strcpy(out, "SENSOR_HARD_FAULT");
|
||||
break;
|
||||
case E_SENSOR_SERIAL_BUFFER_OVERFLOW:
|
||||
strcpy(out, "SENSOR_SERIAL_BUFFER_OVERFLOW");
|
||||
break;
|
||||
case E_SENSOR_INVALID_CHECKSUM:
|
||||
strcpy(out, "SENSOR_INVALID_CHECKSUM");
|
||||
break;
|
||||
case E_SENSOR_INVALID_COMMAND:
|
||||
strcpy(out, "SENSOR_INVALID_COMMAND");
|
||||
break;
|
||||
case E_SENSOR_NOT_ENOUGH_PARAMETERS:
|
||||
strcpy(out, "SENSOR_NOT_ENOUGH_PARAMETERS");
|
||||
break;
|
||||
case E_SENSOR_TOO_MANY_PARAMETERS:
|
||||
strcpy(out, "SENSOR_TOO_MANY_PARAMETERS");
|
||||
break;
|
||||
case E_SENSOR_INVALID_PARAMETER:
|
||||
strcpy(out, "SENSOR_INVALID_PARAMETER");
|
||||
break;
|
||||
case E_SENSOR_INVALID_REGISTER:
|
||||
strcpy(out, "SENSOR_INVALID_REGISTER");
|
||||
break;
|
||||
case E_SENSOR_UNAUTHORIZED_ACCESS:
|
||||
strcpy(out, "SENSOR_UNAUTHORIZED_ACCESS");
|
||||
break;
|
||||
case E_SENSOR_WATCHDOG_RESET:
|
||||
strcpy(out, "SENSOR_WATCHDOG_RESET");
|
||||
break;
|
||||
case E_SENSOR_OUTPUT_BUFFER_OVERFLOW:
|
||||
strcpy(out, "SENSOR_OUTPUT_BUFFER_OVERFLOW");
|
||||
break;
|
||||
case E_SENSOR_INSUFFICIENT_BAUD_RATE:
|
||||
strcpy(out, "SENSOR_INSUFFICIENT_BAUD_RATE");
|
||||
break;
|
||||
case E_SENSOR_ERROR_BUFFER_OVERFLOW:
|
||||
strcpy(out, "SENSOR_ERROR_BUFFER_OVERFLOW");
|
||||
break;
|
||||
case E_DATA_NOT_ELLIPTICAL:
|
||||
strcpy(out, "DATA_NOT_ELLIPTICAL");
|
||||
break;
|
||||
case E_BOOTLOADER_NONE:
|
||||
strcpy(out, "No Error: Success, send next record");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_COMMAND:
|
||||
strcpy(out, "Invalid Command: Problem with VNX record, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_RECORD_TYPE:
|
||||
strcpy(out, "Invalid Record Type: Problem with VNX record, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_BYTE_COUNT:
|
||||
strcpy(out, "Invalide Byte Count: Problem with VNX record, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_MEMORY_ADDRESS:
|
||||
strcpy(out, "Invalide Memeory Address: Problem with VNX record, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_COMM_ERROR:
|
||||
strcpy(out, "COMM Error: Checksum error, resend record");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_HEX_FILE:
|
||||
strcpy(out, "Invalid Hex File: Problem with VNX record, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_DECRYPTION_ERROR:
|
||||
strcpy(out, "Decryption Error: Invalid VNX file or record sent out of order, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_BLOCK_CRC:
|
||||
strcpy(out, "Invalide Block CRC: Data verification failed, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_PROGRAM_CRC:
|
||||
strcpy(out, "Invalide Program CRC: Problemw ith firmware on device");
|
||||
break;
|
||||
case E_BOOTLOADER_INVALID_PROGRAM_SIZE:
|
||||
strcpy(out, "Invalide Program Size: Problemw ith firmware on device");
|
||||
break;
|
||||
case E_BOOTLOADER_MAX_RETRY_COUNT:
|
||||
strcpy(out, "Max Retry Count: Too many errors, abort");
|
||||
break;
|
||||
case E_BOOTLOADER_TIMEOUT:
|
||||
strcpy(out, "Timeout: Timeout expired, reset");
|
||||
break;
|
||||
case E_BOOTLOADER_RESERVED:
|
||||
strcpy(out, "Reserved: Contact VectorNav, abort");
|
||||
break;
|
||||
default:
|
||||
strcpy(out, "UNKNOWN_VALUE");
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "vn/error_detection.h"
|
||||
|
||||
uint8_t VnChecksum8_compute(char const *data, size_t length)
|
||||
{
|
||||
uint8_t xorVal = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
xorVal ^= data[i];
|
||||
}
|
||||
|
||||
return xorVal;
|
||||
}
|
||||
|
||||
uint16_t VnCrc16_compute(char const *data, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
uint16_t crc = 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
crc = (uint16_t) (crc >> 8) | (crc << 8);
|
||||
|
||||
crc ^= (uint8_t) data[i];
|
||||
crc ^= (uint16_t) (((uint8_t) (crc & 0xFF)) >> 4);
|
||||
crc ^= (uint16_t) ((crc << 8) << 4);
|
||||
crc ^= (uint16_t) (((crc & 0xFF) << 4) << 1);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
#include "vn/math/matrix.h"
|
||||
|
||||
#include "vn/types.h"
|
||||
|
||||
void vn_m3_init_fa(mat3f* m, const float* fa)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
m->e[i] = fa[i];
|
||||
}
|
||||
|
||||
mat3f vnm_negative_mat3f(mat3f m)
|
||||
{
|
||||
mat3f r;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 3 * 3; i++)
|
||||
r.e[i] = -m.e[i];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*#include <stdio.h>*/
|
||||
|
||||
/*vec3f add_v3f_v3f(vec3f lhs, vec3f rhs)
|
||||
{
|
||||
vec3f r;
|
||||
|
||||
r.x = lhs.x + rhs.x;
|
||||
r.y = lhs.y + rhs.y;
|
||||
r.z = lhs.z + rhs.z;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3d add_v3d_v3d(vec3d lhs, vec3d rhs)
|
||||
{
|
||||
vec3d r;
|
||||
|
||||
r.x = lhs.x + rhs.x;
|
||||
r.y = lhs.y + rhs.y;
|
||||
r.z = lhs.z + rhs.z;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec4f add_v4f_v4f(vec4f lhs, vec4f rhs)
|
||||
{
|
||||
vec4f r;
|
||||
|
||||
r.x = lhs.x + rhs.x;
|
||||
r.y = lhs.y + rhs.y;
|
||||
r.z = lhs.z + rhs.z;
|
||||
r.w = lhs.w + rhs.w;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3f sub_v3f_v3f(vec3f lhs, vec3f rhs)
|
||||
{
|
||||
vec3f r;
|
||||
|
||||
r.x = lhs.x - rhs.x;
|
||||
r.y = lhs.y - rhs.y;
|
||||
r.z = lhs.z - rhs.z;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3d sub_v3d_v3d(vec3d lhs, vec3d rhs)
|
||||
{
|
||||
vec3d r;
|
||||
|
||||
r.x = lhs.x - rhs.x;
|
||||
r.y = lhs.y - rhs.y;
|
||||
r.z = lhs.z - rhs.z;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec4f sub_v4f_v4f(vec4f lhs, vec4f rhs)
|
||||
{
|
||||
vec4f r;
|
||||
|
||||
r.x = lhs.x - rhs.x;
|
||||
r.y = lhs.y - rhs.y;
|
||||
r.z = lhs.z - rhs.z;
|
||||
r.w = lhs.w - rhs.w;
|
||||
|
||||
return r;
|
||||
}*/
|
||||
|
||||
#if 0
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* Disable warnings regarding using sprintf_s since these
|
||||
* function signatures do not provide us with information
|
||||
* about the length of 'out'. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
void str_vec3f(char* out, vec3f v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f)", v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void str_vec3d(char* out, vec3d v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f)", v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void str_vec4f(char* out, vec4f v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f; %f)", v.x, v.y, v.z, v.w);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "vn/math/vector.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
vec3d create_v3d(double x, double y, double z)
|
||||
{
|
||||
vec3d v;
|
||||
|
||||
v.c[0] = x;
|
||||
v.c[1] = y;
|
||||
v.c[2] = z;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void vn_v3_init_fa(vec3f* v, const float* fa)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
v->c[i] = fa[i];
|
||||
}
|
||||
|
||||
vec3f add_v3f_v3f(vec3f lhs, vec3f rhs)
|
||||
{
|
||||
vec3f r;
|
||||
|
||||
r.c[0] = lhs.c[0] + rhs.c[0];
|
||||
r.c[1] = lhs.c[1] + rhs.c[1];
|
||||
r.c[2] = lhs.c[2] + rhs.c[2];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3d add_v3d_v3d(vec3d lhs, vec3d rhs)
|
||||
{
|
||||
vec3d r;
|
||||
|
||||
r.c[0] = lhs.c[0] + rhs.c[0];
|
||||
r.c[1] = lhs.c[1] + rhs.c[1];
|
||||
r.c[2] = lhs.c[2] + rhs.c[2];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec4f add_v4f_v4f(vec4f lhs, vec4f rhs)
|
||||
{
|
||||
vec4f r;
|
||||
|
||||
r.c[0] = lhs.c[0] + rhs.c[0];
|
||||
r.c[1] = lhs.c[1] + rhs.c[1];
|
||||
r.c[2] = lhs.c[2] + rhs.c[2];
|
||||
r.c[3] = lhs.c[3] + rhs.c[3];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3f sub_v3f_v3f(vec3f lhs, vec3f rhs)
|
||||
{
|
||||
vec3f r;
|
||||
|
||||
r.c[0] = lhs.c[0] - rhs.c[0];
|
||||
r.c[1] = lhs.c[1] - rhs.c[1];
|
||||
r.c[2] = lhs.c[2] - rhs.c[2];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec3d sub_v3d_v3d(vec3d lhs, vec3d rhs)
|
||||
{
|
||||
vec3d r;
|
||||
|
||||
r.c[0] = lhs.c[0] - rhs.c[0];
|
||||
r.c[1] = lhs.c[1] - rhs.c[1];
|
||||
r.c[2] = lhs.c[2] - rhs.c[2];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
vec4f sub_v4f_v4f(vec4f lhs, vec4f rhs)
|
||||
{
|
||||
vec4f r;
|
||||
|
||||
r.c[0] = lhs.c[0] - rhs.c[0];
|
||||
r.c[1] = lhs.c[1] - rhs.c[1];
|
||||
r.c[2] = lhs.c[2] - rhs.c[2];
|
||||
r.c[3] = lhs.c[3] - rhs.c[3];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* Disable warnings regarding using sprintf_s since these
|
||||
* function signatures do not provide us with information
|
||||
* about the length of 'out'. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
void str_vec3f(char* out, vec3f v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f)", v.c[0], v.c[1], v.c[2]);
|
||||
}
|
||||
|
||||
void str_vec3d(char* out, vec3d v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f)", v.c[0], v.c[1], v.c[2]);
|
||||
}
|
||||
|
||||
void str_vec4f(char* out, vec4f v)
|
||||
{
|
||||
sprintf(out, "(%f; %f; %f; %f)", v.c[0], v.c[1], v.c[2], v.c[3]);
|
||||
}
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,438 @@
|
||||
#include "vn/protocol/upackf.h"
|
||||
|
||||
#include <string.h>
|
||||
/*#include <stdlib.h>
|
||||
#include <stdio.h>*/
|
||||
|
||||
#include "vn/util.h"
|
||||
|
||||
/*#define MAXIMUM_REGISTER_ID 255
|
||||
#define ASCII_START_CHAR '$'
|
||||
|
||||
#define BINARY_START_CHAR 0xFA*/
|
||||
#define ASCII_END_CHAR1 '\r'
|
||||
#define ASCII_END_CHAR2 '\n'
|
||||
#define MAX_BINARY_PACKET_SIZE 600
|
||||
|
||||
/* Function declarations */
|
||||
void VnUartPacketFinder_dispatchPacket(VnUartPacketFinder* finder, VnUartPacket* packet, size_t running);
|
||||
void VnUartPacketFinder_processPacket(VnUartPacketFinder* finder, uint8_t* start, size_t len, size_t running);
|
||||
void VnUartPacketFinder_resetAllTrackingStatus(VnUartPacketFinder* finder);
|
||||
void VnUartPacketFinder_resetAsciiStatus(VnUartPacketFinder* finder);
|
||||
void VnUartPacketFinder_resetBinaryStatus(VnUartPacketFinder* finder);
|
||||
|
||||
|
||||
/** \brief Dispatch packet.
|
||||
* \param[in] running Running Index. */
|
||||
void vn_uart_packet_finder_packet_found(VnUartPacketFinder* finder, uint8_t* start, size_t len, size_t running);
|
||||
|
||||
char* vnstrtok(char* str, size_t* startIndex);
|
||||
|
||||
void VnUartPacketFinder_initialize(VnUartPacketFinder* toInitialize)
|
||||
{
|
||||
toInitialize->packetFoundHandler = NULL;
|
||||
toInitialize->packetFoundHandlerUserData = NULL;
|
||||
toInitialize->runningDataIndex = 0;
|
||||
toInitialize->asciiCurrentlyBuildingPacket = false;
|
||||
toInitialize->asciiPossibleStartOfPacketIndex = 0;
|
||||
toInitialize->asciiRunningDataIndexOfStart = 0;
|
||||
toInitialize->asciiEndChar1Found = false;
|
||||
toInitialize->binaryCurrentlyBuildingBinaryPacket = false;
|
||||
toInitialize->binaryRunningDataIndexOfStart = 0;
|
||||
toInitialize->bufferSize = VNUART_PROTOCOL_BUFFER_SIZE;
|
||||
toInitialize->binaryGroupsPresentFound = false;
|
||||
toInitialize->binaryGroupsPresent = 0;
|
||||
toInitialize->binaryNumOfBytesRemainingToHaveAllGroupFields = 0;
|
||||
toInitialize->binaryPossibleStartIndex = 0;
|
||||
toInitialize->binaryNumberOfBytesRemainingForCompletePacket = 0;
|
||||
toInitialize->bufferAppendLocation = 0;
|
||||
}
|
||||
|
||||
VnError VnUartPacketFinder_processData(VnUartPacketFinder* finder, uint8_t* data, size_t len)
|
||||
{
|
||||
return VnUartPacketFinder_processData_ex(finder, data, len, false);
|
||||
}
|
||||
|
||||
|
||||
VnError VnUartPacketFinder_processData_ex(VnUartPacketFinder* finder, uint8_t* data, size_t len, bool bootloaderFilter)
|
||||
{
|
||||
bool asciiStartFoundInProvidedBuffer = false;
|
||||
bool binaryStartFoundInProvidedDataBuffer = false;
|
||||
size_t i, dataIndexToStartCopyingFrom, binaryDataMoveOverIndexAdjustment;
|
||||
bool binaryDataToCopyOver;
|
||||
|
||||
/* Assume that since the _runningDataIndex is unsigned, any overflows
|
||||
* will naturally go to zero, which is the behavior that we want. */
|
||||
for (i = 0; i < len; i++, finder->runningDataIndex++)
|
||||
{
|
||||
bool justFinishedBinaryPacket = false;
|
||||
|
||||
if ((data[i] == VN_ASCII_START_CHAR) || (bootloaderFilter && (!finder->asciiCurrentlyBuildingPacket && data[i] == VN_BOOTLOAD_START_CHAR)))
|
||||
{
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
finder->asciiCurrentlyBuildingPacket = true;
|
||||
finder->asciiPossibleStartOfPacketIndex = i;
|
||||
finder->asciiRunningDataIndexOfStart = finder->runningDataIndex;
|
||||
|
||||
asciiStartFoundInProvidedBuffer = true;
|
||||
}
|
||||
else if (finder->asciiCurrentlyBuildingPacket && data[i] == ASCII_END_CHAR1)
|
||||
{
|
||||
finder->asciiEndChar1Found = true;
|
||||
}
|
||||
else if ((bootloaderFilter || (!bootloaderFilter && finder->asciiEndChar1Found)) && (finder->asciiCurrentlyBuildingPacket && data[i] == ASCII_END_CHAR2))
|
||||
{
|
||||
if (asciiStartFoundInProvidedBuffer)
|
||||
{
|
||||
uint8_t* startOfAsciiPacket;
|
||||
size_t packetLength;
|
||||
|
||||
/* All the packet was in this data buffer so we don't
|
||||
* need to do any copying. */
|
||||
|
||||
startOfAsciiPacket = data + finder->asciiPossibleStartOfPacketIndex;
|
||||
packetLength = i - finder->asciiPossibleStartOfPacketIndex + 1;
|
||||
|
||||
VnUartPacketFinder_processPacket(finder, startOfAsciiPacket, packetLength, finder->asciiRunningDataIndexOfStart);
|
||||
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The packet was split between the running data buffer
|
||||
* the current data buffer. We need to copy the data
|
||||
* over before further processing. */
|
||||
|
||||
if (finder->bufferAppendLocation + i < finder->bufferSize)
|
||||
{
|
||||
uint8_t* startOfAsciiPacket;
|
||||
size_t packetLength;
|
||||
|
||||
memcpy(finder->receiveBuffer + finder->bufferAppendLocation, data, i + 1);
|
||||
|
||||
startOfAsciiPacket = finder->receiveBuffer + finder->asciiPossibleStartOfPacketIndex;
|
||||
packetLength = finder->bufferAppendLocation + i + 1 - finder->asciiPossibleStartOfPacketIndex;
|
||||
|
||||
VnUartPacketFinder_processPacket(finder, startOfAsciiPacket, packetLength, finder->asciiRunningDataIndexOfStart);
|
||||
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are about to overflow our buffer. */
|
||||
VnUartPacketFinder_resetAllTrackingStatus(finder);
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
binaryStartFoundInProvidedDataBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (finder->asciiEndChar1Found)
|
||||
{
|
||||
/* Must not be a valid ASCII packet. */
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
if (!finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
|
||||
/* Update our binary packet in processing. */
|
||||
if (finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
{
|
||||
if (!finder->binaryGroupsPresentFound)
|
||||
{
|
||||
/* This byte must be the groups present. */
|
||||
finder->binaryGroupsPresentFound = true;
|
||||
finder->binaryGroupsPresent = (uint8_t) data[i];
|
||||
finder->binaryNumOfBytesRemainingToHaveAllGroupFields = (uint8_t) (2 * VnUtil_countSetBitsUint8((uint8_t) data[i]));
|
||||
}
|
||||
else if (finder->binaryNumOfBytesRemainingToHaveAllGroupFields != 0)
|
||||
{
|
||||
/* We found another byte belonging to this possible binary packet. */
|
||||
finder->binaryNumOfBytesRemainingToHaveAllGroupFields--;
|
||||
|
||||
if (finder->binaryNumOfBytesRemainingToHaveAllGroupFields == 0)
|
||||
{
|
||||
/* We have all of the group fields now. */
|
||||
|
||||
size_t remainingBytesForCompletePacket = 0;
|
||||
if (binaryStartFoundInProvidedDataBuffer)
|
||||
{
|
||||
size_t headerLength = i - finder->binaryPossibleStartIndex + 1;
|
||||
remainingBytesForCompletePacket = VnUartPacket_computeBinaryPacketLength(data + finder->binaryPossibleStartIndex) - headerLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not all of the packet's group is inside the caller's provided buffer. */
|
||||
|
||||
/* Temporarily copy the rest of the packet to the receive buffer
|
||||
* for computing the size of the packet.
|
||||
*/
|
||||
|
||||
size_t numOfBytesToCopyIntoReceiveBuffer = i + 1;
|
||||
size_t headerLength = finder->bufferAppendLocation - finder->binaryPossibleStartIndex + numOfBytesToCopyIntoReceiveBuffer;
|
||||
|
||||
if (finder->bufferAppendLocation + numOfBytesToCopyIntoReceiveBuffer < finder->bufferSize)
|
||||
{
|
||||
memcpy(
|
||||
finder->receiveBuffer + finder->bufferAppendLocation,
|
||||
data,
|
||||
numOfBytesToCopyIntoReceiveBuffer);
|
||||
|
||||
remainingBytesForCompletePacket = VnUartPacket_computeBinaryPacketLength(finder->receiveBuffer + finder->binaryPossibleStartIndex) - headerLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* About to overrun our receive buffer! */
|
||||
VnUartPacketFinder_resetAllTrackingStatus(finder);
|
||||
binaryStartFoundInProvidedDataBuffer = false;
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
{
|
||||
if (remainingBytesForCompletePacket > MAX_BINARY_PACKET_SIZE)
|
||||
{
|
||||
/* Must be a bad possible binary packet. */
|
||||
VnUartPacketFinder_resetBinaryStatus(finder);
|
||||
binaryStartFoundInProvidedDataBuffer = false;
|
||||
|
||||
if (!finder->asciiCurrentlyBuildingPacket)
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
finder->binaryNumberOfBytesRemainingForCompletePacket = remainingBytesForCompletePacket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are currently collecting data for our packet. */
|
||||
|
||||
finder->binaryNumberOfBytesRemainingForCompletePacket--;
|
||||
|
||||
if (finder->binaryNumberOfBytesRemainingForCompletePacket == 0)
|
||||
{
|
||||
/* We have a possible binary packet! */
|
||||
|
||||
if (binaryStartFoundInProvidedDataBuffer)
|
||||
{
|
||||
uint8_t* packetStart;
|
||||
size_t packetLength;
|
||||
|
||||
/* The binary packet exists completely in the user's provided buffer. */
|
||||
packetStart = data + finder->binaryPossibleStartIndex;
|
||||
packetLength = i - finder->binaryPossibleStartIndex + 1;
|
||||
|
||||
VnUartPacketFinder_processPacket(finder, packetStart, packetLength, finder->binaryRunningDataIndexOfStart);
|
||||
|
||||
justFinishedBinaryPacket = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The packet is split between our receive buffer and the user's buffer. */
|
||||
size_t numOfBytesToCopyIntoReceiveBuffer = i + 1;
|
||||
|
||||
if (finder->bufferAppendLocation + numOfBytesToCopyIntoReceiveBuffer < finder->bufferSize)
|
||||
{
|
||||
uint8_t* packetStart;
|
||||
size_t packetLength;
|
||||
|
||||
memcpy(
|
||||
finder->receiveBuffer + finder->bufferAppendLocation,
|
||||
data,
|
||||
numOfBytesToCopyIntoReceiveBuffer);
|
||||
|
||||
packetStart = finder->receiveBuffer + finder->binaryPossibleStartIndex;
|
||||
packetLength = finder->bufferAppendLocation - finder->binaryPossibleStartIndex + i + 1;
|
||||
|
||||
VnUartPacketFinder_processPacket(finder, packetStart, packetLength, finder->binaryRunningDataIndexOfStart);
|
||||
|
||||
justFinishedBinaryPacket = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* About to overrun our receive buffer! */
|
||||
VnUartPacketFinder_resetAllTrackingStatus(finder);
|
||||
binaryStartFoundInProvidedDataBuffer = false;
|
||||
asciiStartFoundInProvidedBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data[i] == VN_BINARY_START_CHAR && !justFinishedBinaryPacket)
|
||||
{
|
||||
if (!finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
{
|
||||
/* Possible start of a binary packet. */
|
||||
binaryStartFoundInProvidedDataBuffer = true;
|
||||
finder->binaryCurrentlyBuildingBinaryPacket = true;
|
||||
finder->binaryPossibleStartIndex = i;
|
||||
finder->binaryGroupsPresentFound = false;
|
||||
finder->binaryNumOfBytesRemainingToHaveAllGroupFields = 0;
|
||||
finder->binaryNumberOfBytesRemainingForCompletePacket = 0;
|
||||
finder->binaryRunningDataIndexOfStart = finder->runningDataIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform any data copying to our receive buffer. */
|
||||
|
||||
dataIndexToStartCopyingFrom = 0;
|
||||
binaryDataToCopyOver = false;
|
||||
binaryDataMoveOverIndexAdjustment = 0;
|
||||
|
||||
if (finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
{
|
||||
binaryDataToCopyOver = true;
|
||||
|
||||
if (binaryStartFoundInProvidedDataBuffer)
|
||||
{
|
||||
dataIndexToStartCopyingFrom = finder->binaryPossibleStartIndex;
|
||||
binaryDataMoveOverIndexAdjustment = dataIndexToStartCopyingFrom;
|
||||
}
|
||||
}
|
||||
|
||||
if (finder->asciiCurrentlyBuildingPacket && asciiStartFoundInProvidedBuffer)
|
||||
{
|
||||
if (finder->asciiPossibleStartOfPacketIndex < dataIndexToStartCopyingFrom)
|
||||
{
|
||||
binaryDataMoveOverIndexAdjustment -= binaryDataMoveOverIndexAdjustment - finder->asciiPossibleStartOfPacketIndex;
|
||||
dataIndexToStartCopyingFrom = finder->asciiPossibleStartOfPacketIndex;
|
||||
}
|
||||
else if (!binaryDataToCopyOver)
|
||||
{
|
||||
dataIndexToStartCopyingFrom = finder->asciiPossibleStartOfPacketIndex;
|
||||
}
|
||||
|
||||
/* Adjust our ASCII index to be based on the receive buffer. */
|
||||
finder->asciiPossibleStartOfPacketIndex = finder->bufferAppendLocation + finder->asciiPossibleStartOfPacketIndex - dataIndexToStartCopyingFrom;
|
||||
}
|
||||
|
||||
/* Adjust any binary packet indexes we are currently building. */
|
||||
if (finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
{
|
||||
if (binaryStartFoundInProvidedDataBuffer)
|
||||
{
|
||||
finder->binaryPossibleStartIndex = finder->binaryPossibleStartIndex - binaryDataMoveOverIndexAdjustment + finder->bufferAppendLocation;
|
||||
}
|
||||
}
|
||||
|
||||
if (finder->bufferAppendLocation + len - dataIndexToStartCopyingFrom < finder->bufferSize)
|
||||
{
|
||||
/* Safe to copy over the data. */
|
||||
size_t numOfBytesToCopyOver = len - dataIndexToStartCopyingFrom;
|
||||
uint8_t *copyFromStart = data + dataIndexToStartCopyingFrom;
|
||||
|
||||
memcpy(
|
||||
finder->receiveBuffer + finder->bufferAppendLocation,
|
||||
copyFromStart,
|
||||
numOfBytesToCopyOver);
|
||||
|
||||
finder->bufferAppendLocation += numOfBytesToCopyOver;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are about to overflow our buffer. */
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
VnUartPacketFinder_resetBinaryStatus(finder);
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
|
||||
return E_NONE;
|
||||
}
|
||||
|
||||
void VnUartPacketFinder_processPacket(VnUartPacketFinder* finder, uint8_t* start, size_t len, size_t running)
|
||||
{
|
||||
VnUartPacket p;
|
||||
PacketType t;
|
||||
|
||||
VnUartPacket_initialize(&p, start, len);
|
||||
|
||||
t = VnUartPacket_type(&p);
|
||||
|
||||
if (VnUartPacket_isValid(&p))
|
||||
{
|
||||
VnUartPacketFinder_dispatchPacket(finder, &p, running);
|
||||
|
||||
/* Reset tracking for both packet types since this packet was valid. */
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
VnUartPacketFinder_resetBinaryStatus(finder);
|
||||
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid packet! Reset tracking. */
|
||||
|
||||
if (t == PACKETTYPE_ASCII)
|
||||
{
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
|
||||
if (!finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
VnUartPacketFinder_resetBinaryStatus(finder);
|
||||
|
||||
if (!finder->asciiCurrentlyBuildingPacket)
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VnUartPacketFinder_resetAsciiStatus(VnUartPacketFinder* finder)
|
||||
{
|
||||
finder->asciiCurrentlyBuildingPacket = false;
|
||||
finder->asciiPossibleStartOfPacketIndex = 0;
|
||||
finder->asciiEndChar1Found = false;
|
||||
finder->asciiRunningDataIndexOfStart = 0;
|
||||
}
|
||||
|
||||
void VnUartPacketFinder_resetBinaryStatus(VnUartPacketFinder* finder)
|
||||
{
|
||||
finder->binaryCurrentlyBuildingBinaryPacket = false;
|
||||
finder->binaryGroupsPresentFound = false;
|
||||
finder->binaryGroupsPresent = 0;
|
||||
finder->binaryNumOfBytesRemainingToHaveAllGroupFields = 0;
|
||||
finder->binaryPossibleStartIndex = 0;
|
||||
finder->binaryNumberOfBytesRemainingForCompletePacket = 0;
|
||||
finder->binaryRunningDataIndexOfStart = 0;
|
||||
}
|
||||
|
||||
void VnUartPacketFinder_resetAllTrackingStatus(VnUartPacketFinder *finder)
|
||||
{
|
||||
if (finder->asciiCurrentlyBuildingPacket)
|
||||
VnUartPacketFinder_resetAsciiStatus(finder);
|
||||
|
||||
if (finder->binaryCurrentlyBuildingBinaryPacket)
|
||||
VnUartPacketFinder_resetBinaryStatus(finder);
|
||||
|
||||
finder->bufferAppendLocation = 0;
|
||||
}
|
||||
|
||||
void VnUartPacketFinder_dispatchPacket(VnUartPacketFinder* finder, VnUartPacket* packet, size_t running)
|
||||
{
|
||||
if (finder->packetFoundHandler == NULL)
|
||||
return;
|
||||
|
||||
finder->packetFoundHandler(finder->packetFoundHandlerUserData, packet, running);
|
||||
}
|
||||
|
||||
VnError VnUartPacketFinder_registerPacketFoundHandler(VnUartPacketFinder* finder, VnUartPacketFinder_PacketFoundHandler handler, void *userData)
|
||||
{
|
||||
if (finder->packetFoundHandler != NULL)
|
||||
return E_INVALID_OPERATION;
|
||||
|
||||
finder->packetFoundHandler = handler;
|
||||
finder->packetFoundHandlerUserData = userData;
|
||||
|
||||
return E_NONE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user