/******************************************************************************* * Copyright (c) 2021 Nerian Vision GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *******************************************************************************/ #ifndef VISIONTRANSFER_SENSORDATA_H #define VISIONTRANSFER_SENSORDATA_H #define _USE_MATH_DEFINES #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif namespace visiontransfer { /** * \brief Base class for sensor records with timestamp and status (reliability) fields */ class SensorRecord { protected: int timestampSec; int timestampUSec; unsigned char status; public: SensorRecord(int timestampSec, int timestampUSec, unsigned char status): timestampSec(timestampSec), timestampUSec(timestampUSec), status(status) {} /** * Returns the sensor-reported timestamp for the reading */ void getTimestamp(int& s, int& us) const { s = timestampSec; us = timestampUSec; } /** * Returns the current sensor calibration status (range 0..3) * 0: Sensor unreliable; 1: Accuracy low; 2: ~ medium; 3: ~ high */ unsigned char getStatus() const { return status; } }; /** * \brief Encapsulate a scalar sensor measurement, containing the value, as well as timestamp and status fields */ class TimestampedScalar: public SensorRecord { public: double value() const { return valueIntl; } TimestampedScalar(int timestampSec, int timestampUSec, unsigned char status, double value): SensorRecord(timestampSec, timestampUSec, status), valueIntl(value) {} TimestampedScalar(): SensorRecord(0, 0, 0), valueIntl(0) { } private: double valueIntl; }; /** * \brief Encapsulate a 3D sensor report, containing X, Y, Z, as well as timestamp and status fields */ class TimestampedVector: public SensorRecord { public: double x() const { return xIntl; } double y() const { return yIntl; } double z() const { return zIntl; } TimestampedVector(int timestampSec, int timestampUSec, unsigned char status, double x, double y, double z): SensorRecord(timestampSec, timestampUSec, status), xIntl(x), yIntl(y), zIntl(z) {} TimestampedVector(): SensorRecord(0, 0, 0), xIntl(0), yIntl(0), zIntl(0) { } private: double xIntl, yIntl, zIntl; }; /** * \brief Encapsulate a 4D (quaternion) sensor report, containing X, Y, Z, W, as well as timestamp and status fields and measurement accuracy * * Component r is the real part of the quaternion, also called w (ijkr corresponds to xyzw). */ class TimestampedQuaternion: public SensorRecord { public: double x() const { return xIntl; } double y() const { return yIntl; } double z() const { return zIntl; } double w() const { return wIntl; } /** * Convert the quaternion to device roll, pitch, and yaw (radians) */ void getRollPitchYaw(double& roll, double& pitch, double& yaw) { // roll double sinr_cosp = 2 * (wIntl * xIntl + -zIntl * yIntl); double cosr_cosp = 1 - 2 * (xIntl * xIntl + -zIntl * -zIntl); roll = std::atan2(sinr_cosp, cosr_cosp); // pitch double sinp = 2 * (wIntl * -zIntl - yIntl * xIntl); pitch = (std::abs(sinp) >= 1) ? ((sinp<0)?-(M_PI/2):(M_PI/2)) : std::asin(sinp); // yaw double siny_cosp = 2 * (wIntl * yIntl + xIntl * -zIntl); double cosy_cosp = 1 - 2 * (-zIntl * -zIntl + yIntl * yIntl); yaw = std::atan2(siny_cosp, cosy_cosp); } /** * Returns the internal device-reported angular accuracy (radians) */ double accuracy() const { return accuracyIntl; } TimestampedQuaternion(int timestampSec, int timestampUSec, unsigned char status, double x, double y, double z, double w, double accuracy): SensorRecord(timestampSec, timestampUSec, status), xIntl(x), yIntl(y), zIntl(z), wIntl(w), accuracyIntl(accuracy) {} TimestampedQuaternion(): SensorRecord(0, 0, 0), xIntl(0), yIntl(0), zIntl(0), wIntl(0), accuracyIntl(0) { } private: double xIntl, yIntl, zIntl, wIntl; double accuracyIntl; }; } // namespace #endif