@@ -113,8 +113,13 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
113
113
return ;
114
114
}
115
115
116
- if (now_us - last_observation_usec < 20000 ) {
117
- // create observations at 20ms intervals (matches EKF max rate)
116
+ if (_sitl->vicon_rate_hz == 0 ) {
117
+ return ;
118
+ }
119
+ const uint64_t vicon_interval_us = 1000000UL / _sitl->vicon_rate_hz ; // Interval in microseconds based on rate
120
+ if (now_us - last_observation_usec < vicon_interval_us) {
121
+ // create observations at rate specified by vicon_rate_hz
122
+ // by default runs at 50Hz
118
123
return ;
119
124
}
120
125
@@ -136,6 +141,12 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
136
141
137
142
// add earth frame sensor offset and glitch to position
138
143
Vector3d pos_corrected = position + (pos_offset_ef + _sitl->vicon_glitch .get ()).todouble ();
144
+ // add some gaussian noise to the position
145
+ pos_corrected += Vector3d (
146
+ Aircraft::rand_normal (0 , _sitl->vicon_pos_stddev ),
147
+ Aircraft::rand_normal (0 , _sitl->vicon_pos_stddev ),
148
+ Aircraft::rand_normal (0 , _sitl->vicon_pos_stddev )
149
+ );
139
150
140
151
// calculate a velocity offset due to the antenna position offset and body rotation rate
141
152
// note: % operator is overloaded for cross product
@@ -159,17 +170,33 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
159
170
vel_corrected = vicon_yaw_rot.tofloat () * vel_corrected;
160
171
}
161
172
173
+ // add some gaussian noise to the velocity
174
+ vel_corrected += Vector3f (
175
+ Aircraft::rand_normal (0 , _sitl->vicon_vel_stddev ),
176
+ Aircraft::rand_normal (0 , _sitl->vicon_vel_stddev ),
177
+ Aircraft::rand_normal (0 , _sitl->vicon_vel_stddev )
178
+ );
179
+
162
180
// add yaw error reported to vehicle
163
181
yaw = wrap_PI (yaw + radians (_sitl->vicon_yaw_error .get ()));
164
182
165
183
// 25ms to 124ms delay before sending
166
184
uint32_t delay_ms = 25 + unsigned (random ()) % 100 ;
167
185
uint64_t time_send_us = now_us + delay_ms * 1000UL ;
168
186
187
+
188
+ float pose_cov[21 ];
189
+ memset (pose_cov, 0 , sizeof (pose_cov));
190
+ // Set variances (diagonal elements), assume no cross-correlation. TODO: figure out attitude variances
191
+ const float pos_variance = _sitl->vicon_pos_stddev *_sitl->vicon_pos_stddev ;
192
+ pose_cov[0 ] = pos_variance; // x
193
+ pose_cov[6 ] = pos_variance; // y
194
+ pose_cov[11 ] = pos_variance; // z
195
+
169
196
// send vision position estimate message
170
197
uint8_t msg_buf_index;
171
198
if (should_send (ViconTypeMask::VISION_POSITION_ESTIMATE) && get_free_msg_buf_index (msg_buf_index)) {
172
- const mavlink_vision_position_estimate_t vision_position_estimate{
199
+ mavlink_vision_position_estimate_t vision_position_estimate{
173
200
usec: now_us + time_offset_us,
174
201
x: float (pos_corrected.x ),
175
202
y: float (pos_corrected.y ),
@@ -178,6 +205,8 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
178
205
pitch: pitch,
179
206
yaw: yaw
180
207
};
208
+ memcpy (vision_position_estimate.covariance , pose_cov, sizeof (pose_cov));
209
+
181
210
mavlink_msg_vision_position_estimate_encode_status (
182
211
system_id,
183
212
component_id,
@@ -210,12 +239,21 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
210
239
211
240
// send vision speed estimate
212
241
if (should_send (ViconTypeMask::VISION_SPEED_ESTIMATE) && get_free_msg_buf_index (msg_buf_index)) {
213
- const mavlink_vision_speed_estimate_t vicon_speed_estimate{
242
+ float cov[9 ];
243
+ memset (cov, 0 , sizeof (cov));
244
+ // Set variances (diagonal elements), assume no cross-correlation
245
+ const float vel_variance = _sitl->vicon_vel_stddev *_sitl->vicon_vel_stddev ;
246
+ cov[0 ] = vel_variance; // x
247
+ cov[4 ] = vel_variance; // y
248
+ cov[8 ] = vel_variance; // z
249
+ mavlink_vision_speed_estimate_t vicon_speed_estimate{
214
250
usec: now_us + time_offset_us,
215
251
x: vel_corrected.x ,
216
252
y: vel_corrected.y ,
217
253
z: vel_corrected.z
218
254
};
255
+ memcpy (vicon_speed_estimate.covariance , cov, sizeof (cov));
256
+
219
257
mavlink_msg_vision_speed_estimate_encode_status (
220
258
system_id,
221
259
component_id,
@@ -230,7 +268,15 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
230
268
// send ODOMETRY message
231
269
if (should_send (ViconTypeMask::ODOMETRY) && get_free_msg_buf_index (msg_buf_index)) {
232
270
const Vector3f vel_corrected_frd = attitude.inverse () * vel_corrected;
233
- const mavlink_odometry_t odometry{
271
+ float vel_cov[21 ];
272
+ memset (vel_cov, 0 , sizeof (vel_cov));
273
+ // Set variances (diagonal elements), assume no cross-correlation. TODO: figure out angular velocity variances
274
+ const float vel_variance = _sitl->vicon_vel_stddev *_sitl->vicon_vel_stddev ;
275
+ vel_cov[0 ] = vel_variance; // x
276
+ vel_cov[6 ] = vel_variance; // y
277
+ vel_cov[11 ] = vel_variance; // z
278
+
279
+ mavlink_odometry_t odometry{
234
280
time_usec: now_us + time_offset_us,
235
281
x: float (pos_corrected.x ),
236
282
y: float (pos_corrected.y ),
@@ -250,6 +296,9 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
250
296
estimator_type: MAV_ESTIMATOR_TYPE_VIO,
251
297
quality: 50 , // quality hardcoded to 50%
252
298
};
299
+ memcpy (odometry.pose_covariance , pose_cov, sizeof (pose_cov));
300
+ memcpy (odometry.velocity_covariance , vel_cov, sizeof (vel_cov));
301
+
253
302
mavlink_msg_odometry_encode_status (
254
303
system_id,
255
304
component_id,
0 commit comments