Skip to content

Commit b12c41e

Browse files
SITL: Add gausian noise and rate to VICON sim
1 parent efe6e85 commit b12c41e

File tree

3 files changed

+78
-5
lines changed

3 files changed

+78
-5
lines changed

libraries/SITL/SIM_Vicon.cpp

+54-5
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,13 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
113113
return;
114114
}
115115

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
118123
return;
119124
}
120125

@@ -136,6 +141,12 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
136141

137142
// add earth frame sensor offset and glitch to position
138143
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+
);
139150

140151
// calculate a velocity offset due to the antenna position offset and body rotation rate
141152
// note: % operator is overloaded for cross product
@@ -159,17 +170,33 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
159170
vel_corrected = vicon_yaw_rot.tofloat() * vel_corrected;
160171
}
161172

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+
162180
// add yaw error reported to vehicle
163181
yaw = wrap_PI(yaw + radians(_sitl->vicon_yaw_error.get()));
164182

165183
// 25ms to 124ms delay before sending
166184
uint32_t delay_ms = 25 + unsigned(random()) % 100;
167185
uint64_t time_send_us = now_us + delay_ms * 1000UL;
168186

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+
169196
// send vision position estimate message
170197
uint8_t msg_buf_index;
171198
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{
173200
usec: now_us + time_offset_us,
174201
x: float(pos_corrected.x),
175202
y: float(pos_corrected.y),
@@ -178,6 +205,8 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
178205
pitch: pitch,
179206
yaw: yaw
180207
};
208+
memcpy(vision_position_estimate.covariance, pose_cov, sizeof(pose_cov));
209+
181210
mavlink_msg_vision_position_estimate_encode_status(
182211
system_id,
183212
component_id,
@@ -210,12 +239,21 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
210239

211240
// send vision speed estimate
212241
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{
214250
usec: now_us + time_offset_us,
215251
x: vel_corrected.x,
216252
y: vel_corrected.y,
217253
z: vel_corrected.z
218254
};
255+
memcpy(vicon_speed_estimate.covariance, cov, sizeof(cov));
256+
219257
mavlink_msg_vision_speed_estimate_encode_status(
220258
system_id,
221259
component_id,
@@ -230,7 +268,15 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
230268
// send ODOMETRY message
231269
if (should_send(ViconTypeMask::ODOMETRY) && get_free_msg_buf_index(msg_buf_index)) {
232270
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{
234280
time_usec: now_us + time_offset_us,
235281
x: float(pos_corrected.x),
236282
y: float(pos_corrected.y),
@@ -250,6 +296,9 @@ void Vicon::update_vicon_position_estimate(const Location &loc,
250296
estimator_type: MAV_ESTIMATOR_TYPE_VIO,
251297
quality: 50, // quality hardcoded to 50%
252298
};
299+
memcpy(odometry.pose_covariance, pose_cov, sizeof(pose_cov));
300+
memcpy(odometry.velocity_covariance, vel_cov, sizeof(vel_cov));
301+
253302
mavlink_msg_odometry_encode_status(
254303
system_id,
255304
component_id,

libraries/SITL/SITL.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,27 @@ const AP_Param::GroupInfo SIM::var_info3[] = {
724724
AP_SUBGROUPINFO(volz_sim, "VOLZ_", 55, SIM, Volz),
725725
#endif
726726

727+
// @Param: VICON_P_SD
728+
// @DisplayName: SITL vicon position standard deviation for gaussian noise
729+
// @Description: SITL vicon position standard deviation for gaussian noise
730+
// @Units: m
731+
// @User: Advanced
732+
AP_GROUPINFO("VICON_P_SD", 56, SIM, vicon_pos_stddev, 0.0f),
733+
734+
// @Param: VICON_V_SD
735+
// @DisplayName: SITL vicon velocity standard deviation for gaussian noise
736+
// @Description: SITL vicon velocity standard deviation for gaussian noise
737+
// @Units: m/s
738+
// @User: Advanced
739+
AP_GROUPINFO("VICON_V_SD", 57, SIM, vicon_vel_stddev, 0.0f),
740+
741+
// @Param: VICON_RATE
742+
// @DisplayName: SITL vicon rate
743+
// @Description: SITL vicon rate
744+
// @Units: Hz
745+
// @User: Advanced
746+
AP_GROUPINFO("VICON_RATE", 58, SIM, vicon_rate_hz, 50),
747+
727748
#ifdef SFML_JOYSTICK
728749
AP_SUBGROUPEXTENSION("", 63, SIM, var_sfml_joystick),
729750
#endif // SFML_JOYSTICK

libraries/SITL/SITL.h

+3
Original file line numberDiff line numberDiff line change
@@ -538,11 +538,14 @@ class SIM {
538538

539539
// vicon parameters
540540
AP_Vector3f vicon_glitch; // glitch in meters in vicon's local NED frame
541+
AP_Float vicon_pos_stddev; // noise in meters in vicon's local NED frame
542+
AP_Float vicon_vel_stddev; // noise in m/s in vicon's local NED frame
541543
AP_Int8 vicon_fail; // trigger vicon failure
542544
AP_Int16 vicon_yaw; // vicon local yaw in degrees
543545
AP_Int16 vicon_yaw_error; // vicon yaw error in degrees (added to reported yaw sent to vehicle)
544546
AP_Int8 vicon_type_mask; // vicon message type mask (bit0:vision position estimate, bit1:vision speed estimate, bit2:vicon position estimate)
545547
AP_Vector3f vicon_vel_glitch; // velocity glitch in m/s in vicon's local frame
548+
AP_Int16 vicon_rate_hz; // vicon data rate in Hz
546549

547550
// get the rangefinder reading for the desired instance, returns -1 for no data
548551
float get_rangefinder(uint8_t instance);

0 commit comments

Comments
 (0)