[docs]defsetup_messages(self):# per txself.steering_control_msg:cantools.db.Message=self.per.get_message_by_name('ACUsCTRL_ActcControl')self.service_brake_msg:cantools.db.Message=self.per.get_message_by_name('ACUsCTRL_ServiceBrake_PRESSxREQ')self.monitoring_status_msg:cantools.db.Message=self.per.get_message_by_name('ACUsMON_STATE')self.dsb_msg:cantools.db.Message=self.per.get_message_by_name('ACUsMON_RosNodes_STATE')self.ros_recording_msg:cantools.db.Message=self.per.get_message_by_name('ACUsCAN_RosbagRecording_STATUS')# log txself.dv_driving_diagnostics_1_msg:cantools.db.Message=self.log.get_message_by_name('ACU_DvDrivingDiagnostics1')self.dv_driving_diagnostics_2_msg:cantools.db.Message=self.log.get_message_by_name('ACU_DvDrivingDiagnostics2')self.dv_system_diagnostics_msg:cantools.db.Message=self.log.get_message_by_name('ACU_DvSystemDiagnostics')self.engine_control_msg:cantools.db.Message=self.log.get_message_by_name('ACUsCTRL_EngineControl')self.mission_finished_msg:cantools.db.Message=self.log.get_message_by_name('ACUsMM_MissionFinished_STATUS')
[docs]defsetup_variables(self):# per rxself.steering_wheel_angle_actual=0self.pneumatic_pressure_override_front=0self.pneumatic_pressure_override_rear=0self.hydraulic_pressure_front=0self.hydraulic_pressure_rear=0self.autonomous_mission=1# first possible state: Accelerationself.imu_accel_x=0self.imu_accel_y=0self.gyro_z=0self.sdu_state=1# openself.sdu_as_status=0# idleself.asms_status=0# blownself.as_state=1# AS offself.ebs_state=1# unavailableself.last_log_button_state=0# not pressedself.log_button_state=0# not pressed# per txself.camera_state=0self.lidar_state=0self.gps_state=0self.filtering_state=0self.slam_state=0self.control_state=0self.planning_state=0self.monitoring_state=0if('/monitoring'inrosnode.get_node_names()):self.monitoring_state=1self.local_mapping_state=0self.lidar_perception_state=0self.perception_state=0self.mission_machine_state=0self.imu_state=0self.wheelspeed_front_state=0self.wheelspeed_rear_state=0self.steering_control_engage=Falseself.steering_wheel_angle_request=0# log txself.torque_request=0self.wheel_radius=rospy.get_param('/vehicle/wheel_radius')self.gear_ratio=rospy.get_param('/vehicle/rear_gear_ratio')self.velocity_request=0self.slam_velocity=0self.torque_actual=0self.lap_count=0self.cones_all_count=0self.cones_actual_count=0self.use_velocity=True
[docs]defsetup_per_tx(self):rospy.Subscriber('/control/steering_wheel_angle/request',SteeringWheelAngle,self.steering_wheel_angle_callback)rospy.Subscriber('/mission_machine/steering_control_engage',SteeringControlEngage,self.steering_control_engange_callback)self.server_brake_pneumatic_pressure_request=0rospy.Subscriber('/control/service_brake/request',BrakePressure,self.service_brake_callback)rospy.Subscriber('/monitoring/status',MonitoringStatus,self.monitoring_status_callback)# dashboard node status callbacksself.monitoring_received_new=rospy.Time(secs=0)self.monitoring_received_old=rospy.Time(secs=0)rospy.Subscriber('/monitoring/node_states',NodeState,self.node_states_callback)#rospy.Subscriber('/monitoring/sensor_states', SensorStates, self.sensor_states_callback)rospy.Subscriber('/mission_machine/state',MissionMachineState,self.mission_machine_state_callback)self.dsb_rate=rospy.Rate(10)# 100 ms cyclic timeself.dsb_publisher=threading.Thread(target=self.send_dashboard_msg,daemon=True)self.dsb_publisher.start()self.rosbag_recording_process=Noneself.rosbag_recording_event=threading.Event()self.ros_recording_rate=rospy.Rate(10)# 100 ms cyclic timeself.ros_recording_thread=threading.Thread(target=self.send_rosbag_record_status,daemon=True)self.ros_recording_thread.start()
[docs]defsetup_log_tx(self):# torquerospy.Subscriber('/control/torque/request',Torque,self.torque_callback)# velocityrospy.Subscriber('/control/velocity/request',Velocity,self.velocity_callback)# vehicle velocity from slamrospy.Subscriber('/slam/vehicle_pose',VehiclePose,self.slam_velocity_callback)# actual torquerospy.Subscriber('/can/log/torque/actual',Torque,self.actual_torque_callback)# dv driving diagnostics 1self.dv_driving_diagnostics_1_rate=rospy.Rate(10)# 100 ms cyclic timeself.dv_driving_diagnostics_1_publisher=threading.Thread(target=self.send_dv_driving_diagnostics_1,daemon=True)self.dv_driving_diagnostics_1_publisher.start()# dv driving diagnostics 2self.dv_driving_diagnostics_2_rate=rospy.Rate(10)# 100 ms cyclic timeself.dv_driving_diagnostics_2_publisher=threading.Thread(target=self.send_dv_driving_diagnostics_2,daemon=True)self.dv_driving_diagnostics_2_publisher.start()# lap countrospy.Subscriber('/finish_line_detection/lap_count',LapCount,self.lap_count_callback)# cone countsrospy.Subscriber('/slam/cone_count',ConesCountAll,self.slam_cones_count_callback)rospy.Subscriber('/local_mapping/cone_count',ConesCountActual,self.local_mapping_cones_count_callback)# dv system diagnostics self.dv_system_diagnostics_rate=rospy.Rate(10)# 100 ms cyclic timeself.dv_system_diagnostics_publisher=threading.Thread(target=self.send_dv_system_diagnostics,daemon=True)self.dv_system_diagnostics_publisher.start()# engine control msg# switch between torque and velocity from mission machinerospy.Subscriber('/mission_machine/use_velocity',VelocityTorqueSwitch,self.velocity_torque_switch_callback)rospy.Subscriber('/mission_machine/finished',MissionFinished,self.mission_finished_callback)
[docs]defgenerate_message(self,data,frame_definition):""" Used for sending it on the can device directly. """returncan.Message(arbitration_id=frame_definition.frame_id,data=data,is_extended_id=frame_definition.is_extended_frame)
[docs]defgenerate_frame(self,data,frame_definition):""" Used for sending it on the can ros bridge. """frame=Frame()frame.header.stamp=rospy.Time.now()frame.data=dataframe.dlc=frame_definition.lengthframe.is_extended=frame_definition.is_extended_frameframe.is_error=Falseframe.is_rtr=Falseframe.id=frame_definition.frame_idreturnframe
[docs]deflog_frame_received_callback(self,received_frame:Frame):try:dbc_frame:cantools.database.can.Message=self.log.get_message_by_frame_id(frame_id=received_frame.id)exceptKeyError:# there is no CAN Frame specified within the dbc file with this id, ignore this messagereturnifdbc_frame.namenotinself.log_receiving_frame_names:# frame is not of interest for the ACU.returntry:# interprete the current frame according to the dbc fileinterpreted_signals=self.log.decode_message(received_frame.id,received_frame.data,decode_choices=False)exceptException:rospy.loginfo(f'Cannot interprete log can message with id={received_frame.id} and data={received_frame.data}')returnifdbc_frame.name=='RES_Status':res_message=ResStatus()res_message.header.stamp=received_frame.header.stampres_message.switch=interpreted_signals.get('RES_Switch_STATUS')res_message.button=interpreted_signals.get('RES_Button_STATUS')res_message.emergency_button=interpreted_signals.get('RES_EmergencyButton0_STATUS')self.res_pub.publish(res_message)elifdbc_frame.name=='VCUsINVx_Diagnostics':wheelspeed_msg=Wheelspeed()wheelspeed_msg.header.stamp=received_frame.header.stampwheelspeed_msg.left=interpreted_signals.get('VCUsINVL_EngineRL_SPEED')wheelspeed_msg.right=interpreted_signals.get('VCUsINVR_EngineRR_SPEED')self.wheelspeed_rear_pub.publish(wheelspeed_msg)torque_msg=Torque()torque_msg.header.stamp=received_frame.header.stamptorque_msg.torque=interpreted_signals.get('VCUsINV_ActualTorque_CURR')/0.64# 0.64 is the scaling factor between torque and currentself.torque_pub.publish(torque_msg)
[docs]defper_frame_received_callback(self,received_frame):try:dbc_frame:cantools.database.can.Message=self.per.get_message_by_frame_id(frame_id=received_frame.id)exceptKeyError:# there is no CAN Frame specified within the dbc file with this id, ignore this messagereturnifdbc_frame.namenotinself.per_receiving_frame_names:# frame is not of interest for the ACU.returntry:# interprete the current frame according to the dbc fileinterpreted_signals=self.per.decode_message(received_frame.id,received_frame.data,decode_choices=False)exceptException:rospy.loginfo(f'Cannot interprete can message with id={received_frame.id} and data={received_frame.data}')return# switch case which message got received and publish the according data on the according ros topicifdbc_frame.name=='ACTC_Measurements':steering_wheel_angle_msg=SteeringWheelAngle()steering_wheel_angle_msg.header.stamp=received_frame.header.stampself.steering_wheel_angle_actual=interpreted_signals.get('ACTC_SteeringWheel_ANGLExACT')steering_wheel_angle_msg.angle=self.steering_wheel_angle_actualself.steering_wheel_angle_pub.publish(steering_wheel_angle_msg)elifdbc_frame.name=='ASBCsSENS_PneumaticFrontxACT':pneumatic_pressure_front_msg=PneumaticPressure()pneumatic_pressure_front_msg.header.stamp=received_frame.header.stamppneumatic_pressure_front_msg.pneumatic_pressure=interpreted_signals.get('ASBCsSENS_Front_Pressure_PRESS')pneumatic_pressure_front_msg.SB_pressure=interpreted_signals.get('ASBCsSENS_Front_SB_PRESS')pneumatic_pressure_front_msg.tank_pressure=interpreted_signals.get('ASBCsSENS_Front_Tank_PRESS')self.pneumatic_pressure_override_front=interpreted_signals.get('ASBCsSENS_Front_Override_PRESS')pneumatic_pressure_front_msg.override_pressure=self.pneumatic_pressure_override_frontself.pneumatic_pressure_front_pub.publish(pneumatic_pressure_front_msg)elifdbc_frame.name=='ASBCsSENS_PneumaticRearxACT':pneumatic_pressure_rear_msg=PneumaticPressure()pneumatic_pressure_rear_msg.header.stamp=received_frame.header.stamppneumatic_pressure_rear_msg.pneumatic_pressure=interpreted_signals.get('ASBCsSENS_Rear_Pressure_PRESS')pneumatic_pressure_rear_msg.SB_pressure=interpreted_signals.get('ASBCsSENS_Rear_SB_PRESS')pneumatic_pressure_rear_msg.tank_pressure=interpreted_signals.get('ASBCsSENS_Rear_Tank_PRESS')self.pneumatic_pressure_override_rear=interpreted_signals.get('ASBCsSENS_Rear_Override_PRESS')pneumatic_pressure_rear_msg.override_pressure=self.pneumatic_pressure_override_rearself.pneumatic_pressure_rear_pub.publish(pneumatic_pressure_rear_msg)elifdbc_frame.name=='ASBCsCUS_CheckupSequence_STATE':# rospy.loginfo(f'Received CUS state {interpreted_signals.get("ASBCsCUS_Cus_STATE")}')checkup_sequence_msg=CheckupSequenceState()checkup_sequence_msg.header.stamp=received_frame.header.stampcheckup_sequence_msg.state=interpreted_signals.get('ASBCsCUS_Cus_STATE')self.checkup_sequence_pub.publish(checkup_sequence_msg)elifdbc_frame.name=='BPCF_PRESS':brake_pressure_front_msg=BrakePressure()brake_pressure_front_msg.header.stamp=received_frame.header.stampself.hydraulic_pressure_front=interpreted_signals.get('BPCF_BrakeSystemF_PRESS')brake_pressure_front_msg.pressure=self.hydraulic_pressure_frontself.hydraulic_pressure_front_pub.publish(brake_pressure_front_msg)elifdbc_frame.name=='BPCR_PRESS':brake_pressure_rear_msg=BrakePressure()brake_pressure_rear_msg.header.stamp=received_frame.header.stampself.hydraulic_pressure_rear=interpreted_signals.get('BPCR_BrakeSystemR_PRESS')brake_pressure_rear_msg.pressure=self.hydraulic_pressure_rearself.hydraulic_pressure_rear_pub.publish(brake_pressure_rear_msg)elifdbc_frame.name=='DSB_AutonomousMission_STATExSET':autonomous_mission_msg=AutonomousMission()autonomous_mission_msg.header.stamp=received_frame.header.stampself.autonomous_mission=interpreted_signals.get('DSB_AutonomousMission_STATExSET')autonomous_mission_msg.mission=self.autonomous_missionself.autonomous_mission_pub.publish(autonomous_mission_msg)elifdbc_frame.name=='IMU_ACCEL':imu_acceleration_msg=ImuAcceleration()imu_acceleration_msg.header.stamp=received_frame.header.stampself.imu_accel_x=interpreted_signals.get('IMU_X_ACCEL')imu_acceleration_msg.x=self.imu_accel_xself.imu_accel_y=interpreted_signals.get('IMU_Y_ACCEL')imu_acceleration_msg.y=self.imu_accel_yimu_acceleration_msg.z=interpreted_signals.get('IMU_Z_ACCEL')self.imu_accel_pub.publish(imu_acceleration_msg)elifdbc_frame.name=='IMU_ANGLERATE':imu_gyro_msg=ImuGyro()imu_gyro_msg.header.stamp=received_frame.header.stampimu_gyro_msg.roll=interpreted_signals.get('IMU_X_ANGLERATE')imu_gyro_msg.pitch=interpreted_signals.get('IMU_Y_ANGLERATE')self.gyro_z=interpreted_signals.get('IMU_Z_ANGLERATE')imu_gyro_msg.yaw=self.gyro_zself.imu_gyro_pub.publish(imu_gyro_msg)elifdbc_frame.name=='SDU':sdu_msg=ShutdownUnitState()sdu_msg.header.stamp=received_frame.header.stampsdu_msg.state=interpreted_signals.get('SDU_StateMachine_STATE')sdu_msg.as_status=interpreted_signals.get('SDU_SdcAs_STATUS')self.sdu_pub.publish(sdu_msg)elifdbc_frame.name=='SUP_Fuse_STATUS':asms_msg=FuseStatus()asms_msg.header.stamp=received_frame.header.stampself.asms_status=interpreted_signals.get('SUP_AsmsFuse_STATUS')asms_msg.intact=self.asms_statusself.asms_pub.publish(asms_msg)elifdbc_frame.name=='VCU_Statemachine_STATE':as_state_msg=AutonomousSystemState()as_state_msg.header.stamp=received_frame.header.stampself.as_state=interpreted_signals.get('VCUsSM_AutonomousSystem_STATE')as_state_msg.as_state=self.as_stateself.ebs_state=interpreted_signals.get('VCUsSM_Ebs_STATE')as_state_msg.ebs_state=self.ebs_stateself.autonomous_driving_pub.publish(as_state_msg)elifdbc_frame.name=='WB_WheelF_SPEED':wheelspeed_msg=Wheelspeed()wheelspeed_msg.header.stamp=received_frame.header.stampwheelspeed_msg.left=interpreted_signals.get('WB_WheelFL_SPEED')wheelspeed_msg.right=interpreted_signals.get('WB_WheelFR_SPEED')self.wheelspeed_pub.publish(wheelspeed_msg)elifdbc_frame.name=='DSB_Buttons_STATE':self.handle_log_button_state(interpreted_signals.get('DSB_LogButton_STATE'))
[docs]defsend_dv_driving_diagnostics_1(self):rospy.loginfo('[CAN Node] Start publishing dv driving dynamics 1 to the data logger.')whilenotrospy.is_shutdown():data=self.dv_driving_diagnostics_1_msg.encode({'ACUsCTRL_Ackermann_ANGLExREQ':max(-128,min(self.steering_wheel_angle_request,127)),'ACUsACTC_Ackermann_ANGLExACT':max(-128,min(self.steering_wheel_angle_actual,127)),'ACUsLOG_Vehicle_VELOxREQ':max(0,min(255,self.velocity_request*3.6)),'ACUsSLAM_Vehicle_VELOxACT':max(0,min(255,self.slam_velocity*3.6)),'ACUsLOG_Engine_TORQUExREQ':max(0,min(self.torque_request*100/240,100)),'ACUsVCU_Engine_TORQUExACT':max(0,min(self.torque_actual*100/240,100)),'ACUsCTRL_HydrBrake_PRESSxREQ':max(0,min(100,self.server_brake_pneumatic_pressure_request*100/12)),'ACUsASBC_HydrBrake_PRESSxACT':max(0,min(100,(self.pneumatic_pressure_override_front*100/12+ \
self.pneumatic_pressure_override_rear*100/12)/2))},strict=False)self.log_bus.send(self.generate_message(data=data,frame_definition=self.dv_driving_diagnostics_1_msg))self.dv_driving_diagnostics_1_rate.sleep()
[docs]defsend_dv_driving_diagnostics_2(self):rospy.loginfo('[CAN Node] Start publishing dv driving dynamics 2 to the data logger.')whilenotrospy.is_shutdown():data=self.dv_driving_diagnostics_2_msg.encode({'ACUsIMU_Z_ANGLERATE':max(-256,min(self.gyro_z,255)),'ACUsIMU_X_ACCEL':max(-64,min(self.imu_accel_x,63)),'ACUsIMU_Y_ACCEL':max(-64,min(self.imu_accel_y,63))})self.log_bus.send(self.generate_message(data=data,frame_definition=self.dv_driving_diagnostics_2_msg))self.dv_driving_diagnostics_2_rate.sleep()
[docs]defsend_dv_system_diagnostics(self):rospy.loginfo('[CAN Node] Start publishing dv system diagnostics to the data logger.')whilenotrospy.is_shutdown():# set service brake state based on 2020 rules and AS stateifself.as_state==AutonomousSystemStateEnum.DRIVING.value:service_brake_state=ServiceBrakeStateEnum.AVAILABLE.valueelifself.as_state==AutonomousSystemStateEnum.READY.valueorself.as_state==AutonomousSystemStateEnum.FINISHED.value:service_brake_state=ServiceBrakeStateEnum.ENGAGED.valueelse:service_brake_state=ServiceBrakeStateEnum.DISENGAGED.valuedata=self.dv_system_diagnostics_msg.encode({'ACUsVCU_AutonomousSystem_STATE':max(1,min(self.as_state,5)),'ACUsLOG_Ebs_STATE':max(1,min(self.ebs_state,3)),'ACUsDSB_AutonomousMission_STATE':max(1,min(self.autonomous_mission,6)),'ACUsMM_ActcControlEngage_STATUS':max(0,min(self.steering_control_engage,1)),'ACUsLOG_ServiceBrake_STATE':max(1,min(service_brake_state,3)),'ACUsFLD_Lap_COUNT':max(0,min(self.lap_count,255)),'ACUsLM_ActualCones_COUNT':max(0,min(self.cones_actual_count,255)),'ACUsSLAM_AllCones_COUNT':max(0,min(self.cones_all_count,131071))})self.log_bus.send(self.generate_message(data=data,frame_definition=self.dv_system_diagnostics_msg))self.dv_system_diagnostics_rate.sleep()