24#include "flexkalman/AbsoluteOrientationMeasurement.h"
25#include "flexkalman/FlexibleKalmanFilter.h"
26#include "flexkalman/FlexibleUnscentedCorrect.h"
27#include "flexkalman/PoseSeparatelyDampedConstantVelocity.h"
28#include "flexkalman/PoseState.h"
31namespace xrt::auxiliary::tracking {
38 using State = flexkalman::pose_externalized_rotation::State;
39 using ProcessModel = flexkalman::PoseSeparatelyDampedConstantVelocityProcessModel<State>;
46 class PSMVFusion :
public PSMVFusionInterface
49 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
52 clear_position_tracked_flag()
override;
57 const struct xrt_vec3 *orientation_variance_optional)
override;
61 const struct xrt_vec3 *variance_optional,
62 const struct xrt_vec3 *lever_arm_optional,
63 float residual_limit)
override;
72 reset_filter_and_imu();
75 ProcessModel process_model;
81 TrackingInfo orientation_state;
82 TrackingInfo position_state;
88 PSMVFusion::clear_position_tracked_flag()
90 position_state.tracked =
false;
94 PSMVFusion::reset_filter()
96 filter_state = State{};
98 position_state = TrackingInfo{};
101 PSMVFusion::reset_filter_and_imu()
104 orientation_state = TrackingInfo{};
105 imu = SimpleIMUFusion{};
111 const struct xrt_vec3 *orientation_variance_optional)
114 Eigen::Vector3d variance = Eigen::Vector3d::Constant(0.01);
115 if (orientation_variance_optional) {
116 variance =
map_vec3(*orientation_variance_optional).cast<
double>();
124 if (filter_time_ns != 0 && filter_time_ns != timestamp_ns) {
127 flexkalman::predict(filter_state, process_model, dt);
129 filter_time_ns = timestamp_ns;
130 auto meas = flexkalman::AbsoluteOrientationMeasurement{
132 Eigen::Quaterniond(Eigen::AngleAxisd(EIGEN_PI, Eigen::Vector3d::UnitY())) * imu.
getQuat(),
134 if (flexkalman::correctUnscented(filter_state, meas)) {
135 orientation_state.tracked =
true;
136 orientation_state.valid =
true;
139 "Got non-finite something when filtering IMU - "
140 "resetting filter and IMU fusion!");
141 reset_filter_and_imu();
144 constexpr double max_rad_per_sec = 20 * double(EIGEN_PI) * 2;
145 if (filter_state.angularVelocity().squaredNorm() > max_rad_per_sec * max_rad_per_sec) {
147 "Got excessive angular velocity when filtering "
148 "IMU - resetting filter and IMU fusion!");
149 reset_filter_and_imu();
154 PSMVFusion::process_3d_vision_data(
timepoint_ns timestamp_ns,
156 const struct xrt_vec3 *variance_optional,
157 const struct xrt_vec3 *lever_arm_optional,
158 float residual_limit)
161 Eigen::Vector3d variance{1.e-4, 1.e-4, 4.e-4};
162 if (variance_optional) {
163 variance =
map_vec3(*variance_optional).cast<
double>();
165 Eigen::Vector3d lever_arm{0, 0.09, 0};
166 if (lever_arm_optional) {
167 lever_arm =
map_vec3(*lever_arm_optional).cast<
double>();
170 lever_arm, variance};
171 double resid = measurement.getResidual(filter_state).norm();
173 if (resid > residual_limit) {
176 "measurement residual is %f, resetting "
182 if (flexkalman::correctUnscented(filter_state, measurement)) {
184 position_state.valid =
true;
185 position_state.tracked =
true;
188 "Got non-finite something when filtering "
189 "tracker - resetting filter!");
197 if (out_relation == NULL) {
202 out_relation->pose.orientation.w = 1;
203 if (!tracked || filter_time_ns == 0) {
207 auto predicted_state = flexkalman::getPrediction(filter_state, process_model, dt);
209 map_vec3(out_relation->pose.position) = predicted_state.position().cast<
float>();
210 map_quat(out_relation->pose.orientation) = predicted_state.getQuaternion().cast<
float>();
211 map_vec3(out_relation->linear_velocity) = predicted_state.velocity().cast<
float>();
212 map_vec3(out_relation->angular_velocity) = predicted_state.angularVelocity().cast<
float>();
215 if (position_state.valid) {
216 flags |= XRT_SPACE_RELATION_POSITION_VALID_BIT;
217 flags |= XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT;
218 if (position_state.tracked) {
219 flags |= XRT_SPACE_RELATION_POSITION_TRACKED_BIT;
222 if (orientation_state.valid) {
223 flags |= XRT_SPACE_RELATION_ORIENTATION_VALID_BIT;
224 flags |= XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT;
225 if (orientation_state.tracked) {
226 flags |= XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT;
234std::unique_ptr<PSMVFusionInterface>
235PSMVFusionInterface::create()
237 auto ret = std::make_unique<PSMVFusion>();
For PS Move-like things, where there's a directly-computed absolute position that is not at the track...
Definition t_fusion.hpp:181
A simple IMU fusion class.
Definition t_imu_fusion.hpp:42
bool handleAccel(Eigen::Vector3d const &accel, timepoint_ns timestamp)
Process an accelerometer report.
Definition t_imu_fusion.hpp:256
void postCorrect()
Normalize internal state.
Definition t_imu_fusion.hpp:158
bool handleGyro(Eigen::Vector3d const &gyro, timepoint_ns timestamp)
Process a gyroscope report.
Definition t_imu_fusion.hpp:221
Eigen::Quaterniond getQuat() const
Get the current state orientation.
Definition t_imu_fusion.hpp:68
#define U_LOG_E(...)
Log a message at U_LOGGING_ERROR level, conditional on the global log level.
Definition u_logging.h:442
#define U_LOG_W(...)
Log a message at U_LOGGING_WARN level, conditional on the global log level.
Definition u_logging.h:439
int64_t timepoint_ns
Integer timestamp type.
Definition u_time.h:77
static double time_ns_to_s(time_duration_ns ns)
Convert nanoseconds duration to double seconds.
Definition u_time.h:97
#define U_ZERO(PTR)
Zeroes the correct amount of memory based on the type pointed-to by the argument.
Definition u_misc.h:68
xrt_space_relation_flags
Flags of which components of a xrt_space_relation is valid.
Definition xrt_defines.h:642
C interface to math library.
Interoperability helpers connecting internal math types and Eigen.
C++-only functionality in the Math helper library.
Definition m_documentation.hpp:15
static Eigen::Map< const Eigen::Vector3f > position(const struct xrt_pose &pose)
Return a Eigen type wrapping a pose's position (const).
Definition m_eigen_interop.hpp:217
static Eigen::Map< const Eigen::Quaternionf > map_quat(const struct xrt_quat &q)
Wrap an internal quaternion struct in an Eigen type, const overload.
Definition m_eigen_interop.hpp:31
static Eigen::Map< const Eigen::Vector3f > map_vec3(const struct xrt_vec3 &v)
Wrap an internal 3D vector struct in an Eigen type, const overload.
Definition m_eigen_interop.hpp:57
Definition m_space.cpp:87
A relation with two spaces, includes velocity and acceleration.
Definition xrt_defines.h:670
IMU Sample.
Definition xrt_tracking.h:121
A 3 element vector with single floats.
Definition xrt_defines.h:289
C++ sensor fusion/filtering code that uses flexkalman.
C++ sensor fusion/filtering code that uses flexkalman.