// // Dispatch_plc 调度plc模块, 主要是负责对接plc的通信数据缓存,以及调度主流程 // 本地缓存DB块的的数据, 内部线程负责下发任务指令和验收任务指令. // #ifndef NNXX_TESTS_DISPATCH_PLC_H #define NNXX_TESTS_DISPATCH_PLC_H #include "../error_code/error_code.h" #include #include #include #include "../tool/thread_condition.h" #include "../tool/common_data.h" #include "../tool/time_tool.h" #include "../task/task_base.h" //#include "../message/dispatch_message.pb.h" #include "../message/message.pb.h" #include "../dispatch/dispatch_communication.h" #include "../tool/string_convert.h" //调度plc class Dispatch_plc { //设备底层通信延时5000ms #define COMMUNICATION_OVER_TIME_MS 5000 //调度指令超时时间 3600000 ms = 60 min #define DISPATCH_PROCESS_TIMEOUT_MS 3600000 //调度指令超时时间 衰减值 在原有的基础上减少10秒 #define DISPATCH_PROCESS_ATTENUATION_TIMEOUT_MS 10000 public: //调度plc状态 enum Dispatch_plc_status { DISPATCH_PLC_UNKNOW = 0, //未知 DISPATCH_PLC_READY = 1, //准备,待机 DISPATCH_PLC_BUSY = 2, //工作正忙, 暂时不用 DISPATCH_PLC_DISCONNECT = 3, //断连 DISPATCH_PLC_REQUEST = 4, //给plc发送请求 DISPATCH_PLC_WORKING = 5, //plc工作中 DISPATCH_PLC_RESPONSE = 6, //给主控答复 DISPATCH_PLC_FAULT = 100, //故障 }; //指令完成状态, 设备答复指令, 返回任务完成的情况 enum Response_status { RESPONS_WORKING = 0, //任务进行中 RESPONS_OVER = 1, //任务完成 RESPONS_ERROR = 2, //错误 RESPONS_REALLOCATE_MIN_SHORT_CAR = 11, //重新分配小车 RESPONS_REALLOCATE_MID_SHORT_CAR = 12, //重新分配中车 RESPONS_REALLOCATE_BIG_SHORT_CAR = 13, //重新分配大车 RESPONS_REALLOCATE_HUGE_SHORT_CAR = 14, //重新分配fault RESPONS_REALLOCATE_FAULT_SHORT_CAR = 15, //重新分配fault RESPONS_REALLOCATE_MIN_LONG_CAR = 21, //重新分配小车 RESPONS_REALLOCATE_MID_LONG_CAR = 22, //重新分配中车 RESPONS_REALLOCATE_BIG_LONG_CAR = 23, //重新分配大车 RESPONS_REALLOCATE_HUGE_LONG_CAR = 24, //重新分配fault RESPONS_REALLOCATE_FAULT_LONG_CAR = 25, //重新分配fault RESPONS_MINOR_ERROR = 100, //一般故障, 可恢复 RESPONS_CRITICAL_ERROR = 101, //致命故障,不可恢复 }; public: Dispatch_plc(); Dispatch_plc(const Dispatch_plc& other)= default; Dispatch_plc& operator =(const Dispatch_plc& other)= default; ~Dispatch_plc(); public://API functions //调度plc 初始化 Error_manager dispatch_plc_init(int plc_id); //调度plc 反初始化 Error_manager dispatch_plc_uninit(); //调度plc 执行请求 // Error_manager execute_for_dispatch_request_msg(message::Dispatch_request_msg &dispatch_request_msg); //新版调度plc 执行请求 存车 Error_manager execute_for_dispatch_request_msg(park_table &park_table_msg, Common_data::Dispatch_process_type dispatch_process_type, Common_data::Car_type car_type); //新版调度plc 执行请求 取车 Error_manager execute_for_dispatch_request_msg(pick_table &pick_table_msg, Common_data::Dispatch_process_type dispatch_process_type, Common_data::Car_type car_type); public://get or set member variable Dispatch_plc::Dispatch_plc_status get_dispatch_plc_status(); // message::Dispatch_request_msg get_dispatch_request_msg(); Error_manager get_result(); float get_response_working_total_time(); float get_response_working_remaining_time(); void clear_request_msg(); //控制外门, 调度发给plc的状态, //door_index 0~1是入口外门, 2~3是出口外门 //door_mode 0是无效, 1是开门, 2是关门 Error_manager control_ouside_door(int door_index, int door_mode); //获取plc搬运器的状态 0=故障 1=存车 2=取车 3=空闲 4=维护 int get_plc_carrier_status(); protected://member functions //jiancha qingqiu xiaoxi // Error_manager check_dispatch_request_msg(message::Dispatch_request_msg & dispatch_request_msg); //执行外界任务的执行函数 void execute_thread_fun(); //数据储存线程函数 void data_storage_thread_fun(); //封装 给plc的调度请求 Error_manager encapsulate_dispatch_request_to_plc(); //封装 给plc的调度请求 Error_manager encapsulate_dispatch_request_to_plc_new(); //更新plc通信 Error_manager update_dispatch_plc_communication(); //检查plc答复反馈 Error_manager check_response_from_plc(); //检查plc答复反馈 Error_manager check_response_from_plc_new(); //发送调度答复信息给主控 Error_manager send_dispatch_response_to_main_control(); //发送调度答复信息给主控 Error_manager send_dispatch_response_to_main_control_new(); protected://member variable public: std::atomic m_dispatch_plc_status; //设备总状态, 控制任务流程(长流程) int m_plc_id; //设备id, 索引, 就是楚天车库的单元号. std::mutex m_lock; //锁 //任务执行线程 std::thread* mp_execute_thread; //执行的线程指针,内存由本类管理 Thread_condition m_execute_condition; //执行的条件变量 //数据存储线程 std::thread* mp_data_storage_thread; //数据存储线程的指针,内存由本类管理 Thread_condition m_data_storage_condition; //数据存储线程的条件变量 //指令 Common_data::Dispatch_process_type m_dispatch_process_type ; //调度流程类型 // message::Dispatch_request_msg m_dispatch_request_msg; //1执行搬运请求(主控->调度管理) // message::Dispatch_response_msg m_dispatch_response_msg; //6搬运动作执行完成后反馈结果(调度管理->主控) park_table m_park_table_msg; //停车表单 pick_table m_pick_table_msg; //取车表单 // int m_terminal_id; //出入口id Common_data::Car_type m_car_type; //车的大小 std::string m_command_key; //任务唯一码, 索引 int m_timeout_ms; //超时时间,单位ms std::chrono::system_clock::time_point m_start_time; //流程开始时间 Error_manager m_result; //中间的错误码 //数据缓存 //调度管理给plc发送调度指令 std::string m_request_key; //请求唯一码, 用作识别 unsigned int m_request_status = 0; //请求确认标志 // 调度指令的起点,终点,方向 Common_data::Dispatch_process_type m_request_dispatch_motion_direction ; //调度方向 0=未知,1=存车,2=取车 unsigned int m_request_passageway_id = 0; //出入口id 6个入口和6个出口 Common_data::Passageway_direction m_request_passageway_direction ; //出入口方向 0=未知,1=入口,2=出口 unsigned short m_request_car_height_level = 0; //车高 0=无车 1=1480 2=1500 3=2050 4=超高车 unsigned int m_request_parkingspace_index_id = 0; //楼上车位索引id 1~180(3*6*13) unsigned int m_request_parkingspace_unit_id = 0; //楼上车位单元号 1~3 unsigned int m_request_parkingspace_label_id = 0; //楼上车位标签号 1~78 unsigned int m_request_parkingspace_floor_id = 0; //楼上车位楼层号 2~11 unsigned int m_request_parkingspace_room_id = 0; //楼上车位房间号 1~6 Common_data::Parkingspace_direction m_request_parkingspace_direction ; //楼上车位方向 0=未知,1=朝南,2=朝北 //汽车的定位信息(地面雷达) float m_request_car_center_x = 0; //整车的中心点x值, 四轮的中心, 单位:米 m float m_request_car_center_y = 0; //整车的中心点y值, 四轮的中心, 单位:米 m float m_request_car_angle = 0; //整车的车身旋转角, 单位:度 (-90~90) float m_request_car_front_theta = 0; //整车的前轮的旋转角, 单位:度 (-90~90) float m_request_car_length = 0; //整车的长度, 用于规避碰撞, 单位:米 m float m_request_car_width = 0; //整车的宽度, 用于规避碰撞, 单位:米 m float m_request_car_height = 0; //整车的高度, 用于规避碰撞, 单位:米 m float m_request_car_wheel_base = 0; //整车的轮距, 前后轮的距离, 用于机器人或agv的抓车, 单位:米 m float m_request_car_wheel_width = 0; //整车的轮距, 左右轮的距离, 用于机器人或agv的抓车, 单位:米 m std::string m_request_car_license; //车牌号(汽车唯一标示) 例如: 鄂A12345 Common_data::Car_type m_request_car_type; //车的大小 float m_request_uniformed_car_x = 0; //转角复位后,车辆中心点x float m_request_uniformed_car_y = 0; //转角复位后,车辆中心点y //防撞雷达 Common_data::Anticollision_lidar_flag m_request_anticollision_lidar_flag ; //汽车是否停到正确的位置, 防撞雷达 预留, 楚天暂时不用,0=未知,1=位置正常,2=位置异常 //轮距雷达 float m_request_car_wheel_base_exact_value = 0; //汽车前后轮距,轮距雷达的精确值 预留, 楚天暂时不用,单位:米 m //plc给调度管理发送调度答复 std::string m_response_key; //答复唯一码, 用作识别 Response_status m_response_status; //指令完成状态, 机器人答复指令, 返回任务完成的情况 float m_response_working_total_time; //搬运总时间(秒) float m_response_working_remaining_time; //剩余时间(秒) // 调度指令的起点,终点,方向 Common_data::Dispatch_process_type m_response_dispatch_motion_direction ; //调度方向 0=未知,1=存车,2=取车 unsigned int m_response_passageway_id = 0; //出入口id 6个入口和6个出口 Common_data::Passageway_direction m_response_passageway_direction ; //出入口方向 0=未知,1=入口,2=出口 unsigned short m_response_car_height_level = 0; //车高 0=无车 1=1480 2=1500 3=2050 4=超高车 unsigned int m_response_parkingspace_index_id = 0; //楼上车位索引id 1~180(3*6*13) unsigned int m_response_parkingspace_unit_id = 0; //楼上车位单元号 1~3 unsigned int m_response_parkingspace_label_id = 0; //楼上车位标签号 1~78 unsigned int m_response_parkingspace_floor_id = 0; //楼上车位楼层号 2~11 unsigned int m_response_parkingspace_room_id = 0; //楼上车位房间号 1~6 Common_data::Parkingspace_direction m_response_parkingspace_direction ; //楼上车位方向 0=未知,1=朝南,2=朝北 //汽车的定位信息(地面雷达) float m_response_car_center_x = 0; //整车的中心点x值, 四轮的中心, 单位:米 m float m_response_car_center_y = 0; //整车的中心点y值, 四轮的中心, 单位:米 m float m_response_car_angle = 0; //整车的车身旋转角, 单位:度 (-90~90) float m_response_car_front_theta = 0; //整车的前轮的旋转角, 单位:度 (-90~90) float m_response_car_length = 0; //整车的长度, 用于规避碰撞, 单位:米 m float m_response_car_width = 0; //整车的宽度, 用于规避碰撞, 单位:米 m float m_response_car_height = 0; //整车的高度, 用于规避碰撞, 单位:米 m float m_response_car_wheel_base = 0; //整车的轮距, 前后轮的距离, 用于机器人或agv的抓车, 单位:米 m float m_response_car_wheel_width = 0; //整车的轮距, 左右轮的距离, 用于机器人或agv的抓车, 单位:米 m std::string m_response_car_license; //车牌号(汽车唯一标示) 例如: 鄂A12345 Common_data::Car_type m_response_car_type; //车的大小 float m_response_uniformed_car_x = 0; //转角复位后,车辆中心点x float m_response_uniformed_car_y = 0; //转角复位后,车辆中心点y //防撞雷达 Common_data::Anticollision_lidar_flag m_response_anticollision_lidar_flag ; //汽车是否停到正确的位置, 防撞雷达 预留, 楚天暂时不用,0=未知,1=位置正常,2=位置异常 //轮距雷达 float m_response_car_wheel_base_exact_value = 0; //汽车前后轮距,轮距雷达的精确值 预留, 楚天暂时不用,单位:米 m #ifdef CHUTIAN_PROJECT_PROJECT //dispatch状态 unsigned char m_dispatch_heartbeat = 0; //心跳位, 0-255循环 //plc状态信息 unsigned char m_plc_heartbeat = 0; //心跳位, 0-255循环 unsigned char m_plc_status_info = 0; //plc状态的集合 //0 bit, 手动模式 //1 bit, 自动模式 //2 bit, 自动运行中 //3 bit, 复位 //4 bit, 1号口可以进车 //5 bit, 2号口可以进车 //6 bit, 预留 //7 bit, 预留 // unsigned char m_reserved2_37[36] = {0}; //预留 36个 float m_turnplate_angle_min1 = 0; //1号口转盘最小值 float m_turnplate_angle_max1 = 0; //1号口转盘最大值 float m_turnplate_angle_min2 = 0; //2号口转盘最小值 float m_turnplate_angle_max2 = 0; //2号口转盘最大值 #endif //CHUTIAN_PROJECT_PROJECT #ifdef SHANGGUJIE_PROJECT_PROJECT //硬件状态, 目前只做显示判断 std::chrono::system_clock::time_point m_last_update_time; //状态更新时间点 unsigned short m_last_heartbeat; //上一次的心跳 bool m_plc_communication_status; //调度和plc的通信状态, true=正常 //调度状态 Dispatch_communication::Dispatch_plc_status_from_manager_to_plc m_dispatch_plc_status_from_manager_to_plc;//调度管理给plc发送状态消息 的结构体 Dispatch_communication::Dispatch_plc_status_from_plc_to_manager m_dispatch_plc_status_from_plc_to_manager;//plc给调度管理发送状态消息 的结构体 #endif //SHANGGUJIE_PROJECT_PROJECT //test time std::chrono::system_clock::time_point test_start_time; std::chrono::system_clock::time_point test_end_time; private: }; #endif //NNXX_TESTS_DISPATCH_PLC_H