37 from dbw_fca_msgs.msg
import BrakeCmd, BrakeReport, BrakeInfoReport
38 from dbw_fca_msgs.msg
import ThrottleCmd, ThrottleReport, ThrottleInfoReport
39 from dbw_fca_msgs.msg
import Gear, GearCmd, GearReport
40 from dbw_fca_msgs.msg
import SteeringCmd, SteeringReport
42 parser = argparse.ArgumentParser(description=
'Log Pacfica performance data')
43 parser.add_argument(
'--steer', action=
'store_true', default=
False, help=
'Enable steering tests')
44 parser.add_argument(
'--brake', action=
'store_true', default=
False, help=
'Enable brake tests')
45 parser.add_argument(
'--lever', action=
'store_true', default=
False, help=
'Enable lever tests')
46 parser.add_argument(
'--gas', action=
'store_true', default=
False, help=
'Enable gas tests')
47 parser.add_argument(
'--quick', action=
'store_true', default=
False, help=
'Do a couple of quick tests')
48 parser.add_argument(
'--all', action=
'store_true', default=
False, help=
'Enable all tests (default)')
49 tests, _ = parser.parse_known_args()
50 if (tests.steer
or tests.brake
or tests.lever
or tests.gas):
56 tests.steer = tests.brake = tests.lever = tests.gas =
True 57 tests.strict_MM =
False 94 brake_duty = [ 0.150, 0.166, 0.168, 0.200, 0.225, 0.250, 0.300, 0.350, 0.400, 0.434, 0.566, 0.600]
95 brake_Nm = [ 0.000, 0.000, 4.000, 56.00, 194.0, 456.0, 1312, 2352, 3716, 4740, 6888, 6888]
97 throttle_pct = [ 0.000, 0.000, 0.001, 0.500, 0.998, 1.000, 1.000]
98 throttle_duty = [ 0.000, 0.080, 0.114, 0.497, 0.890, 0.892, 1.000]
103 command_resolution_s = 0.04
104 initial_check_wait_s = 1.0
105 first_cmd_hold_s = 5.0
111 if dont_check:
return 113 if not self.
all_ready([
'SteeringReport',
'GearReport']):
116 steering_report = self.
get_msg(
'SteeringReport')
117 if steering_report.speed > 0.0:
118 rospy.logerr(
'Speed check failed. Vehicle is moving.')
121 gear_report = self.
get_msg(
'GearReport')
123 if self.
name() !=
"LeverTest":
124 if not gear_report.state.gear == gear_report.state.PARK:
125 rospy.logerr(
'Gear check failed. Vehicle not in park.')
137 start_ct = -int(math.ceil(first_cmd_hold_s/command_resolution_s))
149 def __init__(self, description, sequence, units="percent", num_reps=1, period_s=1):
151 self.
repeats = int(math.ceil(period_s/command_resolution_s))
158 test_counts[self.
name()] += 1
160 test_counts[self.
name()] = 1
164 return self.__class__.__name__
177 self.
repeat_ct = -int((initial_check_wait_s + first_cmd_hold_s)/command_resolution_s)
184 rospy.loginfo(
'Saving csv file')
185 self.csv_file.close()
189 _, msg = self.
msgs[msg_name]
194 ready, msg = self.
msgs[msg_name]
196 self.
msgs[msg_name] = (
False, msg)
198 rospy.logerr(
"%s is not a valid message name" % msg_name)
200 for msg_name, _
in self.msgs.items():
205 ready, _ = self.
msgs[msg_name]
207 rospy.logwarn(
'no new %s messages' % msg_name)
213 for name
in msg_names:
219 return (rospy.get_rostime() - self.
start_time).to_sec() - initial_check_wait_s - first_cmd_hold_s + 0.02
231 csv_writer.writerow([
'Elapsed Time (s)',
'Brake Cmd (%)',
'Measured (%)',
'Pressure (bar)',
'User Input'])
235 rospy.loginfo(
"Setting brake to %f" % brake_val)
240 msg.pedal_cmd_type = BrakeCmd.CMD_PERCENT
243 elif self.
units ==
"torque":
244 msg.pedal_cmd_type = BrakeCmd.CMD_TORQUE_RQ
248 raise Exception(
"units %s unsupported for BrakeTest" % self.
units)
249 brake_pub.publish(msg)
257 if dont_check:
return 259 if not self.
all_ready([
'BrakeReport',
'BrakeInfoReport']):
269 if type(msg).__name__ ==
'BrakeReport':
270 if self.
units ==
'percent':
271 self.csv_writer.writerow([
"{:10.06f}".format(self.
elapsed_time_s()),
273 "{:7.03f}".format(msg.pedal_cmd),
274 "{:7.03f}".format(msg.pedal_input),
275 "{:7.03f}".format(msg.pedal_output),
276 "{:d}".format(msg.user_input)])
277 elif self.
units ==
'torque':
278 self.csv_writer.writerow([
"{:10.06f}".format(self.
elapsed_time_s()),
279 "{:7.03f}".format(msg.pedal_cmd),
280 "{:7.03f}".format(msg.pedal_input),
281 "{:7.03f}".format(msg.pedal_output),
294 csv_writer.writerow([
'Elapsed Time (s)',
'Steering Cmd Sent (Degrees)',
'Steering Cmd Reported (Degrees)',
'Measured (Degrees)'])
296 def pub(self, steering_val):
298 rospy.loginfo(
"Setting steering to %f" % steering_val)
303 elif self.
units ==
"degrees":
306 raise Exception(
"units %s unsupported for SteeringTest" % self.
units)
308 steering_pub.publish(msg)
315 if dont_check:
return 317 if not self.
all_ready([
'SteeringReport']):
327 if type(msg).__name__ ==
'SteeringReport':
328 self.csv_writer.writerow([
"{:10.06f}".format(self.
elapsed_time_s()),
330 "{: 6.1f}".format(math.degrees(msg.steering_wheel_cmd)),
331 "{: 6.1f}".format(math.degrees(msg.steering_wheel_angle))])
333 lock2lock_degrees = math.degrees(SteeringCmd().ANGLE_MAX*2.0)
344 csv_writer.writerow([
'Elapsed Time (s)',
'Throttle Cmd (%)',
'Measured (%)'])
346 def pub(self, throttle_val):
348 rospy.loginfo(
"Setting throttle to %f" % throttle_val)
350 if throttle_val >= 0:
352 msg.pedal_cmd_type = ThrottleCmd.CMD_PERCENT
357 raise Exception(
"units %s unsupported for ThrottleTest" % self.
units)
358 throttle_pub.publish(msg)
366 if dont_check:
return 368 if not self.
all_ready([
'ThrottleReport',
'ThrottleInfoReport']):
378 if type(msg).__name__ ==
'ThrottleInfoReport':
379 self.csv_writer.writerow([
"{:10.06f}".format(self.
elapsed_time_s()),
381 "{:5.01f}".format(msg.throttle_pc)])
395 csv_writer.writerow([
'Elapsed Time (s)',
'Lever Cmd Requested',
'Lever Cmd Reported',
'Lever Position Reported'])
399 rospy.loginfo(
"Setting gear to %s" % gear)
403 msg.cmd.gear = Gear().PARK
405 msg.cmd.gear = Gear().REVERSE 407 msg.cmd.gear = Gear().DRIVE
409 msg.cmd.gear = Gear().NEUTRAL
411 raise Exception(
"Gear %s is not supported" % gear)
414 raise Exception(
"units %s unsupported for LeverTest" % self.
units)
415 gear_pub.publish(msg)
419 bmsg.pedal_cmd_type = BrakeCmd.CMD_PERCENT
421 brake_pub.publish(bmsg)
428 if dont_check:
return 435 if gear_num == Gear().PARK:
437 elif gear_num == Gear().REVERSE:
439 elif gear_num == Gear().DRIVE:
441 elif gear_num == Gear().NEUTRAL:
443 elif gear_num == Gear().LOW:
452 if type(msg).__name__ ==
'GearReport':
453 self.csv_writer.writerow([
"{:.06f}".format(self.
elapsed_time_s()),
457 rospy.loginfo(
"Resetting gear to %s before starting test" % gear)
458 times = int(5/command_resolution_s)
459 r = rospy.Rate(1/command_resolution_s)
460 for i
in range(0, times):
463 msg.cmd.gear = Gear().PARK
465 msg.cmd.gear = Gear().REVERSE 467 msg.cmd.gear = Gear().DRIVE
469 msg.cmd.gear = Gear().NEUTRAL
471 raise Exception(
"Gear %s is not supported" % gear)
472 gear_pub.publish(msg)
476 bmsg.pedal_cmd_type = BrakeCmd.CMD_PERCENT
478 brake_pub.publish(bmsg)
483 perf_tests.append(
BrakeTest(
"Square wave", [ 0, 10, 0, 10, 0, 10, 0, 10, 0, 10], period_s=1, num_reps=4))
484 perf_tests.append(
BrakeTest(
"Square wave", [ 0, 50, 0, 50, 0, 50, 0, 50], period_s=1, num_reps=4))
485 if not tests.strict_MM:
486 perf_tests.append(
BrakeTest(
"Square wave", [ 0, 100, 0, 100, 0, 100, 0, 100, 0, 100, 0, 100, 0, 100, 0, 100], period_s=1, num_reps=4))
487 perf_tests.append(
BrakeTest(
"Square wave", [ 0, 100, 100, 100, 100, 100, 100, 100, 100], period_s=1, num_reps=4))
489 perf_tests.append(
BrakeTest(
"Increasing impulse wave",
490 [ 20, 0, 20.5, 0, 21, 0, 21.5, 0, 22, 0, 22.5, 0, 23, 0, 23.5, 0, 24, 0, 24.5, 0, 25],
491 period_s=5, num_reps=4))
492 perf_tests.append(
BrakeTest(
"Square wave",
493 [0, 10, 0, 15, 0, 20, 0, 25, 0, 30, 0, 35, 0, 40, 0, 45, 0, 50,
494 0, 55, 0, 60, 0, 65, 0, 70, 0, 75, 0, 80, 0, 85, 0, 90, 0, 95, 0, 100],
495 period_s=10, num_reps=4))
496 perf_tests.append(
BrakeTest(
"Square Wave", [ 0, 10, 15, 20, 25, 30, 35, 40, 45, 50,
497 55, 60, 65, 70, 75, 80, 85, 90, 95, 100],
498 period_s=10, num_reps=4))
499 perf_tests.append(
BrakeTest(
"Increasing Wave",
500 [ 20, 21, 20, 21.5, 20, 22, 20, 22.5, 20, 23, 20, 23.5, 20, 24, 20, 24.5, 20, 25, 20, 25.5,
501 20, 26, 20, 26.5, 20, 27, 20, 27.5, 20, 28, 20, 28.5, 20, 29, 20, 29.5, 20, 30],
502 period_s=10, num_reps=4))
505 [0, SteeringTest.lock2lock_degrees / 4, 0, SteeringTest.lock2lock_degrees / 4, 0, SteeringTest.lock2lock_degrees / 4, 0, SteeringTest.lock2lock_degrees / 4, 0],
506 period_s=2, units=
"degrees", num_reps=5))
508 [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
509 period_s=2, num_reps=2))
511 [0, 10, 0, 20, 0, 30, 0, 40, 0, 50, 0, 60, 0, 70, 0, 80, 0, 90, 0, 100, 0],
512 period_s=2, num_reps=2))
516 perf_tests.append(
SteeringTest(
"Increasing impulsive wave",
517 [0, 0.5, 0, -0.5, 0, 1, 0, -1, 0, 1.5, 0, -1.5, 0, 2, 0, -2, 0, 2.5, 0, -2.5],
518 units=
"degrees", period_s=2, num_reps=2))
521 perf_tests.append(
ThrottleTest(
"Step test", [ 0, 25 ], num_reps=4))
522 perf_tests.append(
ThrottleTest(
"Step test", [ 0, 50 ], num_reps=4))
523 perf_tests.append(
ThrottleTest(
"Step test", [ 0, 75 ], num_reps=4))
524 perf_tests.append(
ThrottleTest(
"Step test", [ 0, 100 ], num_reps=4))
527 perf_tests.append(
LeverTest(
"Transition", [
'P',
'N'], num_reps=2, units=
"gear"))
528 perf_tests.append(
LeverTest(
"Transition", [
'P',
'D'], num_reps=2, units=
"gear"))
529 perf_tests.append(
LeverTest(
"Transition", [
'P',
'R'], num_reps=2, units="gear")) 530 perf_tests.append(LeverTest("Transition", [
'N',
'D'], num_reps=2, units=
"gear"))
531 perf_tests.append(
LeverTest(
"Transition", [
'N',
'R'], num_reps=2, units="gear")) 532 perf_tests.append(LeverTest("Transition", [
'N',
'P'], num_reps=2, units=
"gear"))
533 perf_tests.append(
LeverTest(
"Transition", [
'D',
'N'], num_reps=2, units=
"gear"))
534 perf_tests.append(
LeverTest(
"Transition", [
'D',
'P'], num_reps=2, units=
"gear"))
535 perf_tests.append(
LeverTest(
"Transition", [
'D',
'R'], num_reps=2, units="gear")) 536 perf_tests.append(LeverTest("Transition", [
'R', 'D'], num_reps=2, units="gear"))
537 perf_tests.append(
LeverTest(
"Transition", [
'R', 'P'], num_reps=2, units="gear"))
538 perf_tests.append(
LeverTest(
"Transition", [
'R', 'N'], num_reps=2, units="gear"))
541 perf_tests.append(
LeverTest(
"Transition", [
'P'], num_reps=2, units=
"gear"))
545 rospy.init_node(
'test_runner')
553 self.
msgs[
'BrakeReport'] = (
False, BrakeReport() )
554 self.
msgs[
'BrakeInfoReport'] = (
False, BrakeInfoReport() )
555 self.
msgs[
'GearReport'] = (
False, GearReport() )
556 self.
msgs[
'SteeringReport'] = (
False, SteeringReport() )
557 self.
msgs[
'ThrottleReport'] = (
False, ThrottleReport() )
558 self.
msgs[
'ThrottleInfoReport'] = (
False, ThrottleInfoReport() )
563 self.csv_writer.writerow([
'Brake (%)',
'Measured (%)',
'Pressure (bar)'])
568 global brake_pub, gear_pub, steering_pub, throttle_pub
569 brake_pub = rospy.Publisher(
'/vehicle/brake_cmd', BrakeCmd, queue_size=1)
570 gear_pub = rospy.Publisher(
'/vehicle/gear_cmd', GearCmd, queue_size=1)
571 steering_pub = rospy.Publisher(
'/vehicle/steering_cmd', SteeringCmd, queue_size=1)
572 throttle_pub = rospy.Publisher(
'/vehicle/throttle_cmd', ThrottleCmd, queue_size=1)
574 rospy.Subscriber(
'/vehicle/brake_report', BrakeReport, self.
recv_msg)
575 rospy.Subscriber(
'/vehicle/brake_info_report', BrakeInfoReport, self.
recv_msg)
576 rospy.Subscriber(
'/vehicle/throttle_report', ThrottleReport, self.
recv_msg)
577 rospy.Subscriber(
'/vehicle/throttle_info_report', ThrottleInfoReport, self.
recv_msg)
578 rospy.Subscriber(
'/vehicle/gear_report', GearReport, self.
recv_msg)
579 rospy.Subscriber(
'/vehicle/steering_report', SteeringReport, self.
recv_msg)
581 rospy.Timer(rospy.Duration(command_resolution_s), self.
timer_process)
584 if not self.
current_test is None and not self.current_test.done:
585 self.current_test.tick(event)
589 self.
msgs[type(msg).__name__] = (
True, msg)
590 if not self.
current_test is None and not self.current_test.done:
591 self.current_test.recv_msg(msg)
594 rospy.sleep(rospy.Duration(5))
595 if rospy.is_shutdown():
596 rospy.loginfo(
"Stopping test")
598 for test
in perf_tests:
599 if test.__class__.__name__ ==
"LeverTest":
601 test.start(self.
msgs)
603 while not rospy.is_shutdown()
and not test.done:
604 rospy.sleep(rospy.Duration(0.01))
605 if rospy.is_shutdown():
608 if __name__ ==
'__main__':
612 except rospy.ROSInterruptException:
613 rospy.loginfo(
"Stopping test")