//
// Created by huli on 2020/7/28.
//

#ifndef CAN_TEST_MOTOR_DRIVER_H
#define CAN_TEST_MOTOR_DRIVER_H

#include <time.h>
#include <sys/time.h>
#include <chrono>
#include <atomic>

#include "../error_code/error_code.h"
#include "../communication_can/communication_can_base.h"

//电机驱动器 can通信id的基地址, 实际can id为基地址+电机驱动器设备ID
#define	MOTOR_DRIVER_CAN_SEND_MESSAGE_BASE		0x200
#define	MOTOR_DRIVER_CAN_RECEIVE_MESSAGE_BASE	0X180

//电机驱动器 can通信 超时时限, 默认5000ms, 如果长时间没有接受接受消息, 那么就报超时故障
#define	MOTOR_DRIVER_CAN_COMMUNICATION_TIME_OUT_MS		5000


//电机驱动器
class Motor_driver
{
	//电机驱动器 状态
	enum Motor_driver_status
	{
		MOTOR_DRIVER_UNKNOW								= 0,    //未知
		MOTOR_DRIVER_READY    							= 1,    //待机
		MOTOR_DRIVER_RUN								= 2,	//运转

		MOTOR_DRIVER_DEVICE_FAULT						= 10,	//设备故障
		MOTOR_DRIVER_COMMUNICATION_FAULT				= 11,	//通信故障
	};

	//控制字
	enum Control_byte
	{//default CONTROL_STOP = 0
	    CONTROL_STOP               		= 0x00,    //停止, 急停
		CONTROL_INIT               		= 0x01,    //初始化, 唤醒通信
		CONTROL_RUN               		= 0x03,    //启动, 运行, (此时速度生效)
		CONTROL_RESET					= 0x80,		//复位, 清除故障状态, 变为ready
	};
	//状态字
	enum Status_byte
	{//default  = 0
		STATUS_UNKNOW              		= 0,    	//
		STATUS_READY             		= 0x33,    	//
		STATUS_RUN						= 0x37,		//
		STATUS_FAULT					= 0x88,    	//设备故障
	    
	};


public:
	Motor_driver();
	Motor_driver(const Motor_driver& other)= default;
	Motor_driver& operator =(const Motor_driver& other)= default;
	~Motor_driver();
public://API functions
	Error_manager motor_driver_init(int motor_device_id, int can_device_id, int can_port_id);
	Error_manager motor_driver_uninit();

	//刷新状态
	Error_manager update_status();
	//检查状态
	Error_manager check_status();

	//检查消息是否有效, 判断这条消息是不是给我的.
	Error_manager check_msg(Can_message* p_msg);
	//处理消息
	Error_manager execute_msg(Can_message* p_msg);
	//处理任务, 电机驱动器的核心控制流程就在这里
	Error_manager execute_task();
	//定时封装发送消息, 循环式
	Error_manager encapsulate_send_data();
	//发送can消息, 触发式, 调用本函数就发送一条.
	Error_manager encapsulate_send_data_once();

public://get or set member variable
	Motor_driver_status get_motor_driver_status();
	Error_manager		set_target_velocity(float target_velocity);
	float 				get_actual_velocity();
	//复位
	Error_manager 		motor_driver_reset();
	//急停
	Error_manager 		motor_driver_stop();
protected://member variable
    int 					m_motor_device_id;		//电机驱动器 设备ID, 自定义, 但是要与驱动器的can通信设置节点id相同
	Motor_driver_status		m_motor_driver_status;	//电机驱动器 状态

    //can设备 匹配通信接口
	int 					m_can_device_id;		//can设备ID
	int  					m_can_port_id;			//can通道ID

	//发送消息
	std::atomic<int>					m_can_send_id;				//发送can消息的id
	std::atomic<bool>					m_can_send_extern_flag;		//发送can消息的id是否为扩展帧, (默认false 为标准帧)
	std::atomic<Control_byte>			m_control_byte;				//控制字
	std::atomic<float>					m_target_velocity;			//目标速度

	//接受消息
	std::atomic<int>					m_can_receive_id;			//接受can消息的id
	std::atomic<bool>					m_can_receive_extern_flag;	//接受can消息的id是否为扩展帧, (默认false 为标准帧)
	std::atomic<Status_byte>			m_status_byte;				//状态字
	std::atomic<float>					m_actual_velocity;			//实际速度
	std::chrono::system_clock::time_point		m_receive_time;				//接收消息的时间点

private:

};


#endif //CAN_TEST_MOTOR_DRIVER_H
