···2020#include "math/m_mathinclude.h"
2121#include "math/m_api.h"
2222#include "math/m_vec2.h"
2323+#include "math/m_predict.h"
23242425#include "util/u_var.h"
2526#include "util/u_misc.h"
···140141 }
141142142143 switch (buffer[0]) {
143143- case WMR_MS_HOLOLENS_MSG_SENSORS:
144144+ case WMR_MS_HOLOLENS_MSG_SENSORS: {
145145+ // Get the timing as close to reading the packet as possible.
146146+ uint64_t now_ns = os_monotonic_get_ns();
147147+144148 hololens_sensors_decode_packet(wh, &wh->packet, buffer, size);
145149146150 for (int i = 0; i < 4; i++) {
···148152 vec3_from_hololens_accel(wh->packet.accel, i, &wh->raw_accel);
149153150154 os_mutex_lock(&wh->fusion.mutex);
155155+ wh->fusion.last_imu_timestamp_ns = now_ns;
156156+ wh->fusion.last_angular_velocity = wh->raw_gyro;
151157 m_imu_3dof_update( //
152158 &wh->fusion.i3dof, //
153159 wh->packet.gyro_timestamp[i] * WMR_MS_HOLOLENS_NS_PER_TICK, //
···156162 os_mutex_unlock(&wh->fusion.mutex);
157163 }
158164 break;
165165+ }
159166 case WMR_MS_HOLOLENS_MSG_UNKNOWN_05:
160167 case WMR_MS_HOLOLENS_MSG_UNKNOWN_06:
161168 case WMR_MS_HOLOLENS_MSG_UNKNOWN_0E: //
···370377 return;
371378 }
372379373373- // Clear relation.
374374- U_ZERO(out_relation);
380380+ // Variables needed for prediction.
381381+ uint64_t last_imu_timestamp_ns = 0;
382382+ struct xrt_space_relation relation = {0};
383383+ relation.relation_flags = (enum xrt_space_relation_flags)( //
384384+ XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT | //
385385+ XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | //
386386+ XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT);
375387388388+ // Get data while holding the lock.
376389 os_mutex_lock(&wh->fusion.mutex);
377377- out_relation->pose.orientation = wh->fusion.i3dof.rot;
390390+ relation.pose.orientation = wh->fusion.i3dof.rot;
391391+ relation.angular_velocity = wh->fusion.last_angular_velocity;
392392+ last_imu_timestamp_ns = wh->fusion.last_imu_timestamp_ns;
378393 os_mutex_unlock(&wh->fusion.mutex);
379394380380- out_relation->relation_flags = (enum xrt_space_relation_flags)( //
381381- XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | //
382382- XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT);
395395+ // No prediction needed.
396396+ if (at_timestamp_ns < last_imu_timestamp_ns) {
397397+ *out_relation = relation;
398398+ return;
399399+ }
400400+401401+ uint64_t prediction_ns = at_timestamp_ns - last_imu_timestamp_ns;
402402+ double prediction_s = time_ns_to_s(prediction_ns);
403403+404404+ m_predict_relation(&relation, prediction_s, out_relation);
383405}
384406385407static void
+6
src/xrt/drivers/wmr/wmr_hmd.h
···79798080 //! Main fusion calculator.
8181 struct m_imu_3dof i3dof;
8282+8383+ //! The last angular velocity from the IMU, for prediction.
8484+ struct xrt_vec3 last_angular_velocity;
8585+8686+ //! When did we get the last IMU sample, in CPU time.
8787+ uint64_t last_imu_timestamp_ns;
8288 } fusion;
83898490 struct