@@ -163,6 +163,64 @@ TEST_F(TestPoseInstabilityDetector, output_warn_when_twist_is_too_small) // NOL
163
163
EXPECT_TRUE (diagnostic_status.level == diagnostic_msgs::msg::DiagnosticStatus::WARN);
164
164
}
165
165
166
+ TEST_F (TestPoseInstabilityDetector, does_not_crash_even_if_abnormal_odometry_data_comes) // NOLINT
167
+ {
168
+ // [Condition] There is no twist_msg between the two target odometry_msgs.
169
+ // Normally this doesn't seem to happen.
170
+ // As far as I can think, this happens when the odometry msg stops (so the next timer callback
171
+ // will refer to the same odometry msg, and the timestamp difference will be calculated as 0)
172
+ // This test case shows that an error occurs when two odometry msgs come in close succession and
173
+ // there is no other odometry msg.
174
+ // Referring again, this doesn't normally seem to happen in usual operation.
175
+
176
+ builtin_interfaces::msg::Time timestamp{};
177
+
178
+ // send the twist message1
179
+ timestamp.sec = 0 ;
180
+ timestamp.nanosec = 0 ;
181
+ helper_->send_twist_message (timestamp, 0.2 , 0.0 , 0.0 );
182
+
183
+ // send the first odometry message after the first twist message
184
+ timestamp.sec = 0 ;
185
+ timestamp.nanosec = 5e8 + 1 ;
186
+ helper_->send_odometry_message (timestamp, 10.0 , 0.0 , 0.0 );
187
+
188
+ // process the above message (by timer_callback)
189
+ helper_->received_diagnostic_array_flag = false ;
190
+ while (!helper_->received_diagnostic_array_flag ) {
191
+ executor_.spin_some ();
192
+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
193
+ }
194
+
195
+ // send the second odometry message before the second twist message
196
+ timestamp.sec = 0 ;
197
+ timestamp.nanosec = 5e8 + 1e7 ;
198
+ helper_->send_odometry_message (timestamp, 12.0 , 0.0 , 0.0 );
199
+
200
+ // send the twist message2
201
+ timestamp.sec = 1 ;
202
+ timestamp.nanosec = 0 ;
203
+ helper_->send_twist_message (timestamp, 0.2 , 0.0 , 0.0 );
204
+
205
+ // process the above messages (by timer_callback)
206
+ helper_->received_diagnostic_array_flag = false ;
207
+ while (!helper_->received_diagnostic_array_flag ) {
208
+ executor_.spin_some ();
209
+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
210
+ }
211
+
212
+ // provoke timer callback again
213
+ helper_->received_diagnostic_array_flag = false ;
214
+ while (!helper_->received_diagnostic_array_flag ) {
215
+ executor_.spin_some ();
216
+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
217
+ }
218
+
219
+ // This test is OK if pose_instability_detector does not crash. The diagnostics status is not
220
+ // checked.
221
+ SUCCEED ();
222
+ }
223
+
166
224
int main (int argc, char ** argv)
167
225
{
168
226
rclcpp::init (argc, argv);
0 commit comments