//
// Created by huli on 2020/9/25.
//

#ifndef NNXX_TESTS_DISPATCH_COMMUNICATION_H
#define NNXX_TESTS_DISPATCH_COMMUNICATION_H

#include "../tool/singleton.h"
#include "../snap7_communication/snap7_communication_base.h"

class Dispatch_communication:public Singleton<Dispatch_communication>, public Snap7_communication_base
{
public:
	//发送db快的标记位, 保证先发数据再发唯一码
	enum Send_database_flag
	{
		E_SEND_UNKNOW					= 0,
		E_SEND_DATA_START              	= 1,    //开始发送数据
		E_SEND_DATA_END              	= 2,    //结束发送数据
		E_SEND_KEY_START				= 3,	//开始发送唯一码
		E_SEND_KEY_END					= 4,	//结束发送唯一码
	};


#pragma pack(push, 1)	//struct按照1个byte对齐

	//抓车模块给plc发送请求消息的DB编号
#define CATCHER_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_1		110
#define CATCHER_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_2		120
	//抓车模块给plc发送请求消息的指令结构体
	struct Catcher_request_from_dispatch_to_plc_for_data
	{
		//指令信息
		unsigned char			m_reserved50 = 0;					//预留
		unsigned char			m_reserved51_69[19] = {0};	//预留
		// 请求的目标坐标和动作
		float 					m_request_x = 0;				//机器人坐标x轴,
		float 					m_request_y = 0;				//机器人坐标y轴,
		float 					m_request_b = 0;				//机器人坐标b轴, 旋转范围80~280
		float 					m_request_z = 0;				//机器人坐标z轴,
		unsigned char			m_request_clamp_motion = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_reserved87_89[3] = {0};			//预留
		float 					m_request_wheelbase = 0;		//机器人抓车杆前后轮距.
		float 					m_request_d1 = 0;				//机器人坐标d1轴, 机器人抓车杆纵向移动(前轮抓杆)
		float 					m_request_d2 = 0;				//机器人坐标d2轴, 机器人抓车杆纵向移动(后轮抓杆)
	};

	//抓车模块给plc发送请求消息的指令结构体
	struct Catcher_request_from_dispatch_to_plc_for_key
	{
		//指令信息
		unsigned char			m_request_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位
	};

	//plc给抓车模块发送答复消息的DB编号
#define CATCHER_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_1		111
#define CATCHER_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_2		121
	//plc给抓车模块发送答复消息的指令结构体
	struct Catcher_response_from_plc_to_dispatch
	{
		//指令信息
		unsigned char			m_respons_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位
		unsigned char			m_respons_status = 0;			//指令完成状态, 机器人答复指令, 返回任务完成的情况
		unsigned char			m_reserved51_69[19] = {0};	//预留
		//请求的目标坐标和动作
		float 					m_respons_x = 0;				//机器人坐标x轴,
		float 					m_respons_y = 0;				//机器人坐标y轴,
		float 					m_respons_b = 0;				//机器人坐标b轴, 旋转范围80~280
		float 					m_respons_z = 0;				//机器人坐标z轴,
		unsigned char			m_respons_clamp_motion = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_reserved87_89[3] = {0};			//预留
		float 					m_respons_wheelbase = 0;		//机器人抓车杆前后轮距.
		float 					m_respons_d1 = 0;				//机器人坐标d1轴, 机器人抓车杆纵向移动(前轮抓杆)
		float 					m_respons_d2 = 0;				//机器人坐标d2轴, 机器人抓车杆纵向移动(后轮抓杆)
	};

	//plc给抓车模块发送状态消息的DB编号
#define CATCHER_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_1		113
#define CATCHER_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_2		123
	//plc给抓车模块发送状态消息的指令结构体
	struct Catcher_status_from_plc_to_dispatch
	{
		unsigned char			m_heartbeat = 0;				//心跳位, 0-255循环

		unsigned char			m_safe_status = 0;				//设备的安全状态
		unsigned char			m_work_status = 0;				//机器人的硬件设备状态
		unsigned char			m_actual_load_status = 0;		//机器人的负载状态, 机器人上面是否有车.
		unsigned char			m_reserved4_37[34] = {0};		//预留

		float 					m_actual_x = 0;					//机器人坐标x轴,
		float 					m_actual_y = 0;					//机器人坐标y轴,
		float 					m_actual_b = 0;					//机器人坐标b轴, 旋转范围80~280
		float 					m_actual_z = 0;					//机器人坐标z轴,
		float 					m_actual_d1 = 0;				//机器人坐标d1轴, 机器人抓车杆纵向移动(前轮抓杆)
		float 					m_actual_d2 = 0;				//机器人坐标d2轴, 机器人抓车杆纵向移动(后轮抓杆)
		unsigned char			m_actual_clamp_motion1 = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_actual_clamp_motion2 = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_actual_clamp_motion3 = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_actual_clamp_motion4 = 0;		//机器人夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_reserved66_99[34] = {0};		//预留

		//故障信息
		unsigned char			m_actual_error_code[50] = {0};		//搬运器错误码
		unsigned char			m_actual_warning_code[50] = {0};	//升降机错误码
		unsigned char			m_actual_error_description[256] = {0};	//升降机错误描述
	};





	//搬运器给plc发送请求消息的DB编号
#define CARRIER_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_1		200
#define CARRIER_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_2		270
#define CARRIER_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_3		230
	//搬运器给plc发送请求消息的指令结构体
	struct Carrier_request_from_dispatch_to_plc_for_data
	{
		//指令信息
		unsigned char						m_reserved50 = 0;			//预留
		unsigned char						m_reserved51_71[21] = {0};	//预留
		//请求的目标坐标和动作
		float 								m_request_x;				//搬运器坐标x轴, 中跑车控制横向移动
		float 								m_request_y;				//搬运器坐标y轴, 小跑车控制纵向移动
		float 								m_request_z;				//搬运器坐标z轴, 电梯控制上下移动
		float 								m_request_y1;				//搬运器坐标y1轴, 小跑车控制纵向移动(前轮抓杆)
		float 								m_request_y2;				//搬运器坐标y2轴, 小跑车控制纵向移动(后轮抓杆)
		unsigned char						m_request_clamp_motion;		//小跑车夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char						m_request_joint_motion_x;	//电梯与X轴的横向轨道对接,0=无动作，1=进行对接, 2=松开对接
		unsigned char						m_request_joint_motion_y;	//小跑车与Y轴的横向轨道对接,0=无动作，1=进行对接, 2=松开对接
		unsigned char						m_reserved95 = 0;					//预留
		int 								m_request_space_id;			//搬运器空间位置的id.
		int 								m_request_floor_id;			//搬运器楼层位置的id.
		float 								m_request_wheelbase;		//搬运器小跑车的抓车杆前后轮距.
	};

	//搬运器给plc发送请求消息的指令结构体
	struct Carrier_request_from_dispatch_to_plc_for_key
	{
		//指令信息
		unsigned char						m_request_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位
	};

	//plc给搬运器发送答复消息的DB编号
#define CARRIER_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_1		201
#define CARRIER_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_2		271
#define CARRIER_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_3		231
	//plc给搬运器发送答复消息的指令结构体
	struct Carrier_response_from_plc_to_dispatch
	{
		//指令信息
		unsigned char						m_respons_key[50] = {0};	//指令key(任务唯一码), 作为通信标志位
		unsigned char						m_respons_status = 0;		//指令完成状态, 机器人答复指令, 返回任务完成的情况
		unsigned char						m_reserved51_71[21] = {0};	//预留
		//请求的目标坐标和动作
		float 								m_respons_x;				//搬运器坐标x轴, 中跑车控制横向移动
		float 								m_respons_y;				//搬运器坐标y轴, 小跑车控制纵向移动
		float 								m_respons_z;				//搬运器坐标z轴, 电梯控制上下移动
		float 								m_respons_y1;				//搬运器坐标y1轴, 小跑车控制纵向移动(前轮抓杆)
		float 								m_respons_y2;				//搬运器坐标y2轴, 小跑车控制纵向移动(后轮抓杆)
		unsigned char						m_respons_clamp_motion;		//小跑车夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char						m_respons_joint_motion_x;	//电梯与X轴的横向轨道对接,0=无动作，1=进行对接, 2=松开对接
		unsigned char						m_respons_joint_motion_y;	//小跑车与Y轴的横向轨道对接,0=无动作，1=进行对接, 2=松开对接
		unsigned char						m_reserved95 = 0;					//预留
		int 								m_respons_space_id;			//搬运器空间位置的id.
		int 								m_respons_floor_id;			//搬运器楼层位置的id.
		float 								m_respons_wheelbase;		//搬运器小跑车的抓车杆前后轮距.
	};

	//plc给搬运器发送状态消息的DB编号
#define CARRIER_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_1		203
#define CARRIER_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_2		273
#define CARRIER_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_3		233
	//plc给搬运器发送状态消息的指令结构体
	struct Carrier_status_from_plc_to_dispatch
	{
		unsigned char			m_heartbeat = 0;				//心跳位, 0-255循环

		unsigned char			m_safe_status = 0;				//设备的安全状态
		unsigned char			m_work_status = 0;				//搬运器的硬件设备状态
		unsigned char			m_actual_load_status = 0;		//搬运器的负载状态, 小跑车上面是否有车.
		unsigned char			m_reserved4_37[34] = {0};		//预留

		float 					m_actual_x = 0;					//搬运器坐标x轴,
		float 					m_actual_y = 0;					//搬运器坐标y轴,
		float 					m_actual_z = 0;					//搬运器坐标z轴,
		float 					m_actual_y1 = 0;				//搬运器坐标y1轴, 小跑车控制纵向移动(前轮抓杆)
		float 					m_actual_y2 = 0;				//搬运器坐标y2轴, 小跑车控制纵向移动(前轮抓杆)
		unsigned char			m_actual_clamp_motion1 = 0;		//小跑车夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_actual_clamp_motion2 = 0;		//小跑车夹车杆. 0=无动作，1=夹紧，2=松开
		unsigned char			m_actual_small_sports_car_motion = 0;		//小跑车的位置,是否在中跑车上面, 0=无动作，1=出发到位，2=返回到位
		unsigned char			m_actual_joint_motion_x1 = 0;		//电梯与X轴的横向轨道对接,0=无动作，1=伸出到位，2=收回到位
		unsigned char			m_actual_joint_motion_x2 = 0;		//电梯与X轴的横向轨道对接,0=无动作，1=伸出到位，2=收回到位
		unsigned char			m_reserved63_101[39] = {0};		//预留
		//故障信息
		unsigned char			m_actual_error_code[50] = {0};		//搬运器错误码
		unsigned char			m_actual_warning_code[50] = {0};	//升降机错误码
		unsigned char			m_actual_error_description[256] = {0};	//升降机错误描述
	};








	//通道口给plc发送请求消息的DB编号
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_0		300
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_1		310
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_2		320
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_3		330
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_4		340
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_5		350
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_6		360
#define PASSAGEWAY_REQUEST_FROM_DISPATCH_TO_PLC_DBNUMBER_7		370

	//通道口给plc发送请求消息的指令结构体
	struct Passageway_request_from_dispatch_to_plc_for_data
	{
		//指令信息
		unsigned char			m_reserved50 = 0;					//预留
		unsigned char			m_reserved51_69[19] = {0};	//预留
		// 请求的目标坐标和动作
		unsigned char			m_request_inside_door_motion = 0;		//通道口 内门动作
		unsigned char			m_request_outside_door_motion = 0;		//通道口 外门动作
		unsigned char			m_request_turntable_direction = 0;		//通道口 转台方向
	};

	//通道口给plc发送请求消息的指令结构体
	struct Passageway_request_from_dispatch_to_plc_for_key
	{
		//指令信息
		unsigned char						m_request_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位
	};

	//plc给通道口发送答复消息的DB编号
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_0		301
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_1		311
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_2		321
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_3		331
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_4		341
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_5		351
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_6		361
#define PASSAGEWAY_RESPONSE_FROM_PLC_TO_DISPATCH_DBNUMBER_7		371

	//plc给通道口发送答复消息的指令结构体
	struct Passageway_response_from_plc_to_dispatch
	{
		//指令信息
		unsigned char						m_respons_key[50] = {0};	//指令key(任务唯一码), 作为通信标志位
		unsigned char						m_respons_status = 0;		//指令完成状态, 机器人答复指令, 返回任务完成的情况
		unsigned char						m_reserved51_69[19] = {0};	//预留

		unsigned char			m_respons_inside_door_motion = 0;		//通道口 内门动作
		unsigned char			m_respons_outside_door_motion = 0;		//通道口 外门动作
		unsigned char			m_respons_turntable_direction = 0;		//通道口 转台方向
	};

	//plc给通道口发送状态消息的DB编号
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_0		303
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_1		313
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_2		323
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_3		333
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_4		343
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_5		353
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_6		363
#define PASSAGEWAY_STATUS_FROM_PLC_TO_DISPATCH_DBNUMBER_7		373

	//plc给通道口发送状态消息的指令结构体
	struct Passageway_status_from_plc_to_dispatch
	{
		unsigned char			m_heartbeat = 0;				//心跳位, 0-255循环

		unsigned char			m_safe_status = 0;				//设备的安全状态
		unsigned char			m_sensor_status1 = 0;			//设备的传感器状态1
		unsigned char			m_sensor_status2 = 0;			//设备的传感器状态2
		unsigned char			m_reserved4_35[32] = {0};		//预留
		unsigned char			m_actual_turntable_direction;	//通道口 转台方向
		unsigned char			m_reserved37 = 0;					//预留

		//故障信息
		unsigned char			m_actual_error_code[50] = {0};		//通道口错误码
		unsigned char			m_actual_warning_code[50] = {0};	//升降机错误码
		unsigned char			m_actual_error_description[256] = {0};	//升降机错误描述
	};









	//snap7的通信参数路径
#define SNAP7_COMMUNICATION_PARAMETER_PATH_A	"../setting/snap7_communication_a.prototxt"
#define SNAP7_COMMUNICATION_PARAMETER_PATH_B	"../setting/snap7_communication_b.prototxt"
#define SNAP7_COMMUNICATION_PARAMETER_PATH_C	"../setting/snap7_communication_c.prototxt"



//调度管理给plc发送调度指令 的DB编号
#define DISPATCH_REQUEST_FROM_MANAGER_TO_PLC_DBNUMBER_0		9000
//调度管理给plc发送调度指令 的结构体
	struct Dispatch_request_from_manager_to_plc_for_data
	{
		//指令信息
		unsigned char			m_request_status = 0;			//指令完成状态, 机器人答复指令, 返回任务完成的情况
		unsigned char			m_reserved51 = 0;				//预留
		float					m_request_working_total_time;				//搬运总时间(秒)
		float					m_request_working_remaining_time;			//剩余时间(秒)
		unsigned char			m_reserved60_73[14] = {0};			//预留
		// 调度指令的起点,终点,方向
		unsigned char			m_request_dispatch_motion_direction = 0;			//调度方向	0=未知，1=存车，2=取车
		unsigned char			m_reserved75_79[5] = {0};							//预留
		unsigned int			m_request_passageway_id = 0;						//出入口id	6个入口和6个出口
		unsigned char			m_request_passageway_direction = 0;				//出入口方向	0=未知，1=入口，2=出口
		unsigned char			m_reserved85_89[5] = {0};							//预留
		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
		unsigned char			m_request_parkingspace_direction = 0;				//楼上车位方向	0=未知，1=朝南，2=朝北
		unsigned char			m_reserved111 = 0;							//预留

		//汽车的定位信息(地面雷达)
		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
		unsigned char			m_request_car_license[20] = {0};			//车牌号(汽车唯一标示)	例如: 鄂A12345
		unsigned char			m_reserved168_187[20] = {0};							//预留

		unsigned char			m_request_car_type = 0;						//0=未知，1=小车，2=中车,3=大车 ..188
		unsigned char			m_reserved189_191[3] = {0};							//预留

		float					m_request_uniformed_car_x = 0;					//转角复位后,车辆中心点x
		float					m_request_uniformed_car_y = 0;					//转角复位后,车辆中心点y
		unsigned char			m_reserved200_209[10] = {0};							//预留

		//防撞雷达 ..210
		unsigned char			m_request_anticollision_lidar_flag = 0;		//汽车是否停到正确的位置, 防撞雷达	预留, 楚天暂时不用,0=未知，1=位置正常，2=位置异常
		unsigned char			m_reserved211_215[5] = {0};							//预留
		//轮距雷达 ..216
		float  					m_request_car_wheel_base_exact_value = 0;	//汽车前后轮距,轮距雷达的精确值	预留, 楚天暂时不用,单位:米 m
		float					m_request_clamp_lidar_deviation_1 = 0;		//jia ce gan lei da pian cha zhi
		float					m_request_clamp_lidar_deviation_2 = 0;		//jia ce gan lei da pian cha zhi
		float					m_request_clamp_lidar_deviation_3 = 0;		//jia ce gan lei da pian cha zhi
		float					m_request_clamp_lidar_deviation_4 = 0;		//jia ce gan lei da pian cha zhi

	};
//调度管理给plc发送调度指令 的结构体
	struct Dispatch_request_from_manager_to_plc_for_key
	{
		//指令信息
		unsigned char						m_request_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位
	};

//plc给调度管理发送调度答复 的DB编号
#define DISPATCH_RESPONSE_FROM_PLC_TO_MANAGER_DBNUMBER_0		9001
//plc给调度管理发送调度答复 的结构体
	struct Dispatch_response_from_plc_to_manager
	{
		unsigned char						m_response_key[50] = {0};		//指令key(任务唯一码), 作为通信标志位

		//指令信息
		unsigned char			m_response_status = 0;			//指令完成状态, 机器人答复指令, 返回任务完成的情况
		unsigned char			m_reserved51 = 0;				//预留
		float					m_response_working_total_time;				//搬运总时间(秒)
		float					m_response_working_remaining_time;			//剩余时间(秒)
		unsigned char			m_reserved60_73[14] = {0};			//预留
		// 调度指令的起点,终点,方向
		unsigned char			m_response_dispatch_motion_direction = 0;			//调度方向	0=未知，1=存车，2=取车
		unsigned char			m_reserved75_79[5] = {0};							//预留
		unsigned int			m_response_passageway_id = 0;						//出入口id	6个入口和6个出口
		unsigned char			m_response_passageway_direction = 0;				//出入口方向	0=未知，1=入口，2=出口
		unsigned char			m_reserved85_89[5] = {0};							//预留
		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
		unsigned char			m_response_parkingspace_direction = 0;				//楼上车位方向	0=未知，1=朝南，2=朝北
		unsigned char			m_reserved111 = 0;							//预留

		//汽车的定位信息(地面雷达)
		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
		unsigned char			m_response_car_license[20] = {0};			//车牌号(汽车唯一标示)	例如: 鄂A12345
		unsigned char			m_reserved168_187[20] = {0};							//预留

		unsigned char			m_response_car_type = 0;						//0=未知，1=小车，2=中车,3=大车 ..188
		unsigned char			m_reserved189_191[3] = {0};							//预留

		float					m_response_uniformed_car_x = 0;					//转角复位后,车辆中心点x
		float					m_response_uniformed_car_y = 0;					//转角复位后,车辆中心点y
		unsigned char			m_reserved200_209[10] = {0};							//预留
		//防撞雷达 ..210
		unsigned char			m_response_anticollision_lidar_flag = 0;		//汽车是否停到正确的位置, 防撞雷达	预留, 楚天暂时不用,0=未知，1=位置正常，2=位置异常
		unsigned char			m_reserved211_215[5] = {0};							//预留
		//轮距雷达 ..216
		float  					m_response_car_wheel_base_exact_value = 0;	//汽车前后轮距,轮距雷达的精确值	预留, 楚天暂时不用,单位:米 m
		float					m_response_clamp_lidar_deviation_1 = 0;		//jia ce gan lei da pian cha zhi
		float					m_response_clamp_lidar_deviation_2 = 0;		//jia ce gan lei da pian cha zhi
		float					m_response_clamp_lidar_deviation_3 = 0;		//jia ce gan lei da pian cha zhi
		float					m_response_clamp_lidar_deviation_4 = 0;		//jia ce gan lei da pian cha zhi

	};

	//调度管理的的状态信息 的DB编号
#define DISPATCH_PLC_STATUS_FROM_MANAGER_TO_PLC_DBNUMBER_0		9002
//调度管理给plc发送状态消息的指令结构体
	struct Dispatch_plc_status_from_manager_to_plc
	{
		unsigned char			m_dispatch_heartbeat = 0;				//心跳位, 0-255循环

	};

	//plc的状态信息 的DB编号
#define DISPATCH_PLC_STATUS_FROM_PLC_TO_MANAGER_DBNUMBER_0		9003
//plc给通道口发送状态消息的指令结构体
	struct Dispatch_plc_status_from_plc_to_manager
	{
		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号口转盘最大值


	};







	//地面雷达给plc
#define GROUND_LIDAR_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_0		9004
#define GROUND_LIDAR_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_1		9014
	struct Ground_lidar_response_from_manager_to_plc_for_key
	{
		unsigned char			m_response_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_response_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_response_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_response_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效

	};

	struct Ground_lidar_response_from_manager_to_plc_for_data
	{
		//汽车的定位信息(地面雷达)
		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
		float					m_response_uniformed_car_x = 0;					//转角复位后,车辆中心点x
		float					m_response_uniformed_car_y = 0;					//转角复位后,车辆中心点y
		unsigned char			m_response_locate_correct = 0;				//数据是否有效, 0=无效, 1=有效

		unsigned char			m_response_ground_status = 0;				////0  ok 1,nothing 2,noise  3,border
		unsigned char			m_reserved46_47[2] = {0};							//预留

		unsigned char			m_response_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_response_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_response_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_response_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效

		int 					m_response_border_status = 0;						//超界状态描述, 按位运算
	};

	//plc给地面雷达
#define GROUND_LIDAR_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_0		9005
#define GROUND_LIDAR_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_1		9015
	struct Ground_lidar_request_from_plc_to_manager
	{
		unsigned char			m_request_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_request_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_request_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_request_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效
	};


	//防撞雷达给plc
#define ANTICOLLISION_LIDAR_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_0		9006
	struct Anticollision_lidar_response_from_manager_to_plc_for_key
	{
		unsigned char			m_response_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_response_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_response_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_response_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效

	};

	struct Anticollision_lidar_response_from_manager_to_plc_for_data
	{
		unsigned char			m_response_anticollision_lidar_flag = 0;		//汽车是否停到正确的位置, 防撞雷达	预留, 楚天暂时不用,0=未知，1=位置正常，2=位置异常
		unsigned char			m_reserved5_7[3] = {0};							//预留
		float					m_response_offset_x = 0;						//汽车x轴的偏移量, -1.0~+1.0, 单位米
		float					m_response_offset_angle = 0;					//汽车角度的偏移量, -7~+7, 单位度
	};

	//plc给防撞雷达
#define ANTICOLLISION_LIDAR_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_0		9007
	struct Anticollision_lidar_request_from_plc_to_manager
	{
		unsigned char			m_request_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_request_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_request_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_request_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效
	};



	//单片机给plc
#define SINGLECHIP_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_0		9008
#define SINGLECHIP_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_1		9018
#define SINGLECHIP_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_2		9028
#define SINGLECHIP_RESPONSE_FROM_MANAGER_TO_PLC_DBNUMBER_3		9038
	struct Singlechip_response_from_manager_to_plc
	{
		unsigned char					m_process_status;	//流程状态
		unsigned char					m_process_control;	//流程控制

		unsigned char					m_over_border_status;							//超界状态, 0:未知, 1:正常, 2:前超界, 3:后超界, 4:左超界, 5:右超界
		unsigned char					m_car_height_status_current;					//车高状态，当前持续的状态, 0:未知, 1:小车, 2:中车, 3:大车, 4:巨大车, 5:故障车
		unsigned char					m_car_height_status_passing;					//车高状态，经过外门口的状态, 0:未知, 1:小车, 2:中车, 3:大车, 4:巨大车, 5:故障车
		unsigned char					m_outside_door_status;							//外门的状态, 0:未知, 1:外门开到位, 2:外门关到位, 3:外门运行中, 4:外门故障
		unsigned char					m_outside_door_control;							//外门的控制, 0:未知, 1:外门开, 2:外门关,

		unsigned char					m_dispatch_finish_flag;			//调度完成标志位，true表示允许终端放下一辆车进入入口
		unsigned char					m_inside_existence_flag;		//门内是否存在汽车的标志位, true表示有车
		unsigned char					m_outside_existence_flag;		//门外是否存在汽车的标志位, 门外地感触发停车流程, true表示有车
		unsigned char					m_reset_flag;					//重启标志, true：控制看门狗重启
		unsigned char					m_stop_flag;					//急停标志，true：把控制口全部写0，并关闭流程。

		unsigned int					m_error_code;					//错误码

		unsigned char					m_reserved16_35[20] = {0};							//预留

		unsigned char					m_gpio_input[16] = {0};							//gpio输入口原始数据,
		unsigned char					m_gpio_output[8] = {0};							//gpio输出口原始数据,
		unsigned char					m_reserved60_79[20] = {0};							//预留


		unsigned char			m_response_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_response_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_response_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_response_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效
	};

	//plc给单片机
#define SINGLECHIP_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_0		9009
#define SINGLECHIP_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_1		9019
#define SINGLECHIP_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_2		9029
#define SINGLECHIP_REQUEST_FROM_PLC_TO_MANAGER_DBNUMBER_3		9039
	struct Singlechip_request_from_plc_to_manager
	{
		unsigned char			m_request_heartbeat = 0;							//心跳位, 0-255循环
		unsigned char			m_request_communication_mode = 0;					//通信模式	0 = 未知, 1=自动循环模式,2=手动刷新模式
		unsigned char			m_request_refresh_command = 0;						//刷新指令 0-255任意数字,与上一次不同即可
		unsigned char			m_request_data_validity = 0;						//数据有效性, 0 = 未知, 1 = 有效, 2 = 无效

		unsigned char			m_request_insidedoor_status = 0;					//内门状态,  0:未知, 1:外门开到位, 2:外门关到位,
		unsigned char			m_request_outsidedoor_control = 0;					//外门控制, 0:必须关门, 1:可以开门, (触发地感后可以开门)

	};

	//plc数据储存
#define DATA_STORAGE_FROM_PLC_TO_MANAGER_DBNUMBER_0			9500
#define DATA_STORAGE_PLC_DATA_LENGTH						349
	struct Data_storage_from_plc_to_manager
	{
		float m_plc_data[DATA_STORAGE_PLC_DATA_LENGTH];
		float m_heartbeat;
	};


#pragma pack(pop)		//取消对齐

// 子类必须把父类设定为友元函数，这样父类才能使用子类的私有构造函数。
	friend class Singleton<Dispatch_communication>;
private:
	// 父类的构造函数必须保护，子类的构造函数必须私有。
	Dispatch_communication();
public:
	//必须关闭拷贝构造和赋值构造，只能通过 get_instance 函数来进行操作唯一的实例。
	Dispatch_communication(const Dispatch_communication& other) = delete;
	Dispatch_communication& operator =(const Dispatch_communication& other) = delete;
	~Dispatch_communication();
public://API functions
	//初始化 通信 模块。如下三选一
	virtual Error_manager communication_init(int plc_id);
	//反初始化 通信 模块。
	virtual Error_manager communication_uninit();
public://get or set member variable
//	std::mutex * get_data_lock();
//	Request_from_dispatch_to_plc * get_request_from_dispatch_to_plc();
//	Response_from_plc_to_dispatch * get_response_from_plc_to_dispatch();
//	Status_from_dispatch_to_plc * get_status_from_dispatch_to_plc();
//	Status_from_plc_to_dispatch * get_status_from_plc_to_dispatch();
protected://member functions
	//更新数据
	virtual Error_manager updata_receive_buf();
	virtual Error_manager updata_send_buf();

protected://member variable
public:

	int											m_plc_id;		//plc的id, 楚天车库的单元号

	std::mutex									m_data_lock;						//数据锁

	Catcher_request_from_dispatch_to_plc_for_data		m_catcher_request_from_dispatch_to_plc_for_data[2];	//抓车模块给plc发送请求消息的指令结构体
	Catcher_request_from_dispatch_to_plc_for_key		m_catcher_request_from_dispatch_to_plc_for_key[2];	//抓车模块给plc发送请求消息的指令结构体
	Catcher_response_from_plc_to_dispatch				m_catcher_response_from_plc_to_dispatch[2];	//plc给抓车模块发送答复消息的指令结构体
	Catcher_status_from_plc_to_dispatch					m_catcher_status_from_plc_to_dispatch[2];	//plc给抓车模块发送状态消息的指令结构体

	Carrier_request_from_dispatch_to_plc_for_data		m_carrier_request_from_dispatch_to_plc_for_data[3];	//搬运器给plc发送请求消息的指令结构体
	Carrier_request_from_dispatch_to_plc_for_key		m_carrier_request_from_dispatch_to_plc_for_key[3];	//搬运器给plc发送请求消息的指令结构体
	Carrier_response_from_plc_to_dispatch				m_carrier_response_from_plc_to_dispatch[3];	//plc给搬运器发送答复消息的指令结构体
	Carrier_status_from_plc_to_dispatch					m_carrier_status_from_plc_to_dispatch[3];	//plc给搬运器发送状态消息的指令结构体

	Passageway_request_from_dispatch_to_plc_for_data	m_passageway_request_from_dispatch_to_plc_for_data[8];	//通道口给plc发送请求消息的指令结构体
	Passageway_request_from_dispatch_to_plc_for_key		m_passageway_request_from_dispatch_to_plc_for_key[8];	//通道口给plc发送请求消息的指令结构体
	Passageway_response_from_plc_to_dispatch			m_passageway_response_from_plc_to_dispatch[8];	//plc给通道口发送答复消息的指令结构体
	Passageway_status_from_plc_to_dispatch				m_passageway_status_from_plc_to_dispatch[8];	//plc给通道口发送状态消息的指令结构体


	//调度指令
	Dispatch_request_from_manager_to_plc_for_data				m_dispatch_request_from_manager_to_plc_for_data;
	Dispatch_request_from_manager_to_plc_for_key				m_dispatch_request_from_manager_to_plc_for_key;
	Dispatch_response_from_plc_to_manager						m_dispatch_response_from_plc_to_manager;
	//调度状态
	Dispatch_plc_status_from_manager_to_plc						m_dispatch_plc_status_from_manager_to_plc;
	Dispatch_plc_status_from_plc_to_manager						m_dispatch_plc_status_from_plc_to_manager;

	//地面雷达指令
	Ground_lidar_response_from_manager_to_plc_for_data			m_ground_lidar_response_from_manager_to_plc_for_data[2];
	Ground_lidar_response_from_manager_to_plc_for_key			m_ground_lidar_response_from_manager_to_plc_for_key[2];
	Ground_lidar_request_from_plc_to_manager					m_ground_lidar_request_from_plc_to_manager[2];

	//防撞雷达指令
	Anticollision_lidar_response_from_manager_to_plc_for_data	m_anticollision_lidar_response_from_manager_to_plc_for_data;
	Anticollision_lidar_response_from_manager_to_plc_for_key	m_anticollision_lidar_response_from_manager_to_plc_for_key;
	Anticollision_lidar_request_from_plc_to_manager				m_anticollision_lidar_request_from_plc_to_manager;

	//单片机
	Singlechip_response_from_manager_to_plc					m_singlechip_response_from_manager_to_plc[4];
	Singlechip_request_from_plc_to_manager					m_singlechip_request_from_plc_to_manager[4];

	//plc数据储存
	Data_storage_from_plc_to_manager						m_data_storage_from_plc_to_manager;
private:

};


#endif //NNXX_TESTS_DISPATCH_COMMUNICATION_H
