Browse Source

add yuhesen controller

pengcheng 3 years ago
parent
commit
89c87b3bdc

+ 51 - 0
src/controller/controller_yuhesen/boost.h

@@ -0,0 +1,51 @@
+#pragma once
+
+#ifndef _IV_BOOST_H_
+#define _IV_BOOST_H_
+
+#if defined __GNUC__
+#  pragma GCC system_header 
+#endif
+#ifndef __CUDACC__
+//https://bugreports.qt-project.org/browse/QTBUG-22829
+#ifndef Q_MOC_RUN
+#include <boost/version.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/inherit.hpp>
+#include <boost/mpl/inherit_linearly.hpp>
+#include <boost/mpl/joint_view.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/algorithm/string.hpp>
+#ifndef Q_MOC_RUN
+#include <boost/date_time/posix_time/posix_time.hpp>
+#endif
+#if BOOST_VERSION >= 104700
+#include <boost/chrono.hpp>
+#endif
+#include <boost/tokenizer.hpp>
+#include <boost/foreach.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/interprocess/sync/file_lock.hpp>
+#if BOOST_VERSION >= 104900
+#include <boost/interprocess/permissions.hpp>
+#endif
+#include <boost/iostreams/device/mapped_file.hpp>
+#define BOOST_PARAMETER_MAX_ARITY 7
+#include <boost/signals2.hpp>
+#include <boost/signals2/slot.hpp>
+#endif
+#endif
+#endif    // _IV_BOOST_H_

+ 1266 - 0
src/controller/controller_yuhesen/control/can.cpp

@@ -0,0 +1,1266 @@
+#include <control/can.h>
+#include <control/control_status.h>
+#include <common/constants.h>
+#include <common/logout.h>
+#include <perception/sensor_radar.h>
+
+#include <QTime>
+
+#define VCI_USBCAN1		3
+#define VCI_USBCAN2		4
+#define VCI_USBCAN2A		4
+
+#define VCI_USBCAN_E_U 		20
+#define VCI_USBCAN_2E_U 	21
+
+#define VCI_ACCCODE_DEFAULT		0x00000000
+#define VCI_ACCMASK_DEFAULT		0xFFFFFFFF
+#define VCI_TIMER0_DEFAULT		0x00
+#define VCI_TIMER1_DEFAULT		0x1C
+#define VCI_FILTER_DEFAULT		1
+#define VCI_MODE_DEFAULT		0
+
+//函数调用返回状态值
+#define	STATUS_OK					1
+#define STATUS_ERR					0
+
+#define LOG_ENABLE
+#ifndef M_PI
+#define M_PI (3.1415926535897932384626433832795)
+#endif
+
+iv::control::CanUtil::CanUtil() {
+	obs_radar1 = boost::shared_ptr<std::vector<iv::ObstacleBasic>>(new std::vector<iv::ObstacleBasic>);
+	obs_radar_ = boost::shared_ptr<std::vector<iv::ObstacleBasic>>(new std::vector<iv::ObstacleBasic>);
+	obs_radar_ui = boost::shared_ptr<std::vector<iv::ObstacleBasic>>(new std::vector<iv::ObstacleBasic>);
+#ifdef WIN32
+    m_hDLL = LoadLibrary(TEXT("ControlCAN.dll"));
+
+        VCI_OpenDevice = (LPVCI_OpenDevice)GetProcAddress(m_hDLL, "VCI_OpenDevice");//取得函数地址
+        VCI_CloseDevice = (LPVCI_CloseDevice)GetProcAddress(m_hDLL, "VCI_CloseDevice");
+        VCI_InitCAN = (LPVCI_InitCan)GetProcAddress(m_hDLL, "VCI_InitCAN");
+        VCI_ReadBoardInfo = (LPVCI_ReadBoardInfo)GetProcAddress(m_hDLL, "VCI_ReadBoardInfo");
+        VCI_ReadErrInfo = (LPVCI_ReadErrInfo)GetProcAddress(m_hDLL, "VCI_ReadErrInfo");
+        VCI_ReadCanStatus = (LPVCI_ReadCanStatus)GetProcAddress(m_hDLL, "VCI_ReadCANStatus");
+        VCI_GetReference = (LPVCI_GetReference)GetProcAddress(m_hDLL, "VCI_GetReference");
+        VCI_SetReference = (LPVCI_SetReference)GetProcAddress(m_hDLL, "VCI_SetReference");
+        VCI_GetReceiveNum = (LPVCI_GetReceiveNum)GetProcAddress(m_hDLL, "VCI_GetReceiveNum");
+        VCI_ClearBuffer = (LPVCI_ClearBuffer)GetProcAddress(m_hDLL, "VCI_ClearBuffer");
+        VCI_StartCAN = (LPVCI_StartCAN)GetProcAddress(m_hDLL, "VCI_StartCAN");
+        VCI_ResetCAN = (LPVCI_ResetCAN)GetProcAddress(m_hDLL, "VCI_ResetCAN");
+        VCI_Transmit = (LPVCI_Transmit)GetProcAddress(m_hDLL, "VCI_Transmit");
+        VCI_Receive = (LPVCI_Receive)GetProcAddress(m_hDLL, "VCI_Receive");
+        VCI_GetReference2 = (LPVCI_GetReference2)GetProcAddress(m_hDLL, "VCI_GetReference2");
+        VCI_SetReference2 = (LPVCI_SetReference2)GetProcAddress(m_hDLL, "VCI_SetReference2");
+        VCI_ResumeConfig = (LPVCI_ResumeConfig)GetProcAddress(m_hDLL, "VCI_ResumeConfig");
+        VCI_ConnectDevice = (LPVCI_ConnectDevice)GetProcAddress(m_hDLL, "VCI_ConnectDevice");
+        VCI_UsbDeviceReset = (LPVCI_UsbDeviceReset)GetProcAddress(m_hDLL, "VCI_UsbDeviceReset");
+#endif
+}
+iv::control::CanUtil::~CanUtil() {
+
+}
+
+void iv::control::CanUtil::openCanCard() {
+	VCI_INIT_CONFIG initconfig;
+	initconfig.AccCode = VCI_ACCCODE_DEFAULT;
+	initconfig.AccMask = VCI_ACCMASK_DEFAULT;
+	initconfig.Timing0 = VCI_TIMER0_DEFAULT;
+	initconfig.Timing1 = VCI_TIMER1_DEFAULT;
+	initconfig.Filter = VCI_FILTER_DEFAULT;
+	initconfig.Mode = VCI_MODE_DEFAULT;
+
+	int status = VCI_OpenDevice(m_devtype, m_devind, 0);		//打开设备
+    m_connect = -1;
+	if (status == 1)
+	{
+		int init = VCI_InitCAN(m_devtype, m_devind, m_cannum, &initconfig);	//初始化设备
+		if (init == 1)
+		{
+            if (VCI_StartCAN(m_devtype, m_devind, m_cannum) == 1) {
+                send_connect = true;
+                m_connect = 1;
+                thread_send = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&iv::control::CanUtil::send, this)));
+                thread_receive =  boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&iv::control::CanUtil::receive, this)));
+            }
+            else {
+                throw 0;
+			}
+		}
+        else
+        {
+            throw 1;
+        }
+		//	打开2通道,供毫米波雷达读取数据用
+		init = VCI_InitCAN(m_devtype, m_devind, m_cannum_radar, &initconfig);	//初始化设备
+		if (init == 1)
+		{
+			if (VCI_StartCAN(m_devtype, m_devind, m_cannum_radar) == 1) {
+                m_connect = 1;
+                thread_radar_receive = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&iv::control::CanUtil::receive_radar, this)));	//启动毫米波雷达接收线程5
+
+            }
+			else {
+                throw 2;
+			}
+			
+		}
+		else
+		{
+            throw 3;
+		}
+	}
+	else if(status == 0) {
+        throw 4;
+	}
+	else if (status == -1) {
+        throw 5;
+	}
+
+#ifdef USE_MOBILEYE
+    status = VCI_OpenDevice(m_devtype, m_devindmob, 0);		//打开设备
+    if (status == 1)
+    {
+        int init = VCI_InitCAN(m_devtype, m_devindmob, m_cannum, &initconfig);	//初始化设备
+        if (init == 1)
+        {
+            if (VCI_StartCAN(m_devtype, m_devindmob, m_cannum) == 1) {
+                m_connect = 1;
+                thread_mobileye_receive = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&iv::control::CanUtil::receive_mobileye, this)));
+             }
+            else {
+                throw 0;
+            }
+        }
+        else
+        {
+            throw 1;
+        }
+    }
+    else if(status == 0) {
+        throw 4;
+    }
+    else if (status == -1) {
+        throw 5;
+    }
+
+#endif
+}
+
+void iv::control::CanUtil::closeCanCard() {
+    if(m_connect != 0)
+    {
+        thread_receive->interrupt();
+        thread_receive->join();
+        thread_send->interrupt();
+        thread_send->join();
+        thread_receive->interrupt();
+        thread_receive->join();
+        unsigned int rec = VCI_CloseDevice(m_devtype, m_devind);
+#ifdef USE_MOBILEYE
+        rec = VCI_CloseDevice(m_devtype, m_devindmob);
+#endif
+         std::cout << "close can:" << rec << std::endl;
+    }
+}
+
+void iv::control::CanUtil::receive() {
+    while (m_connect)
+    {
+        VCI_CAN_OBJ receivedata[2500];
+        int res = VCI_Receive(m_devtype, m_devind, m_cannum, receivedata, 2500, 10);
+        if (res > 0)	//未能从can卡中读到数
+        {
+   //         std::cout<<"reee"<<std::endl;
+            int i;
+            for(i=0;i<res;i++)
+            {
+                if(receivedata[i].ID == 0x282)
+                {
+                    int i;
+                    unsigned int xvalue[8];
+                    float fvalue[8];
+                    unsigned int x;
+                    for(i=0;i<8;i++)
+                    {
+                        memcpy(&x,&receivedata[i].Data[0],4);
+                        x = (x<<((7-i)*4))>>28;
+                        xvalue[i] = x;
+                        fvalue[i] = x;
+                        if(x == 0)fvalue[i] = -1;
+                        else fvalue[i] = (fvalue[i] - 1.0)*0.2;
+                    }
+                    ServiceCarStatus.multrasonic_obs.mfront_leftmid = fvalue[0];
+                    ServiceCarStatus.multrasonic_obs.mfront_left = fvalue[1];
+                    ServiceCarStatus.multrasonic_obs.mfront_right = fvalue[2];
+                    ServiceCarStatus.multrasonic_obs.mfront_rightmid = fvalue[3];
+                    ServiceCarStatus.multrasonic_obs.mrear_leftmid = fvalue[4];
+                    ServiceCarStatus.multrasonic_obs.mrear_left = fvalue[5];
+                    ServiceCarStatus.multrasonic_obs.mrear_right = fvalue[6];
+                    ServiceCarStatus.multrasonic_obs.mrear_rightmid = fvalue[7];
+
+//                    std::cout<<"rec oooo value is back "<<(int)(receivedata[i].Data[3])<<" head "<<(int)receivedata[i].Data[1]<<std::endl;
+                }
+            }
+        }
+        else
+        {
+            usleep(1000);
+        }
+    }
+}
+
+void iv::control::CanUtil::initial()
+{
+    ServiceControlStatus.command.byte[0] = 0xEB;
+
+    ServiceControlStatus.command.byte[1] = 0;
+
+    ServiceControlStatus.command.byte[2] = 0;
+
+    ServiceControlStatus.command.byte[3] = 0;
+
+    ServiceControlStatus.command.byte[4] = 0;
+
+    ServiceControlStatus.command.byte[5] = 0;
+
+    ServiceControlStatus.command.byte[6] = 0;
+
+    ServiceControlStatus.command.byte[7] = 0;
+}
+
+void iv::control::CanUtil::pack_command()
+{
+    ServiceControlStatus.command.bit.heartbreak++;
+
+    if (ServiceControlStatus.command.bit.heartbreak >= 256)
+        ServiceControlStatus.command.bit.heartbreak = 0;
+
+    ServiceControlStatus.command.byte[7] = (ServiceControlStatus.command.byte[1] + ServiceControlStatus.command.byte[2]
+        + ServiceControlStatus.command.byte[3] + ServiceControlStatus.command.byte[4]
+        + ServiceControlStatus.command.byte[5] + ServiceControlStatus.command.byte[6]) % 256;
+}
+
+void iv::control::CanUtil::send()
+{
+    VCI_CAN_OBJ Command_data;
+
+        QTime time1;
+
+        int LastTimeSend1;
+
+        time1.start();
+
+        LastTimeSend1 = time1.elapsed();
+
+        int Send1Int = 10;  //100ms
+
+        Command_data.SendType = m_sendtype;
+        Command_data.ExternFlag = m_frameflag;
+        Command_data.RemoteFlag = m_frameformat;
+
+        Command_data.ID = ServiceControlStatus.command_ID;
+        Command_data.DataLen = 8;
+
+        initial();
+
+        while (true)
+        {
+            int print_time = time1.elapsed() - LastTimeSend1;
+            if (print_time >= Send1Int)
+            {
+                LastTimeSend1 = time1.elapsed();
+
+                pack_command();
+
+                memcpy(Command_data.Data, ServiceControlStatus.command.byte, 8);
+
+                VCI_Transmit(m_devtype, m_devind, m_cannum, &Command_data, 1);
+
+                /*for (int c = 0; c < 8; c++)
+                ODS("%x  ", Command_data.Data[c]);
+
+                ODS("\n");*/
+
+                //ODS("    %d  \n", print_time);
+            }
+        }
+}
+
+/******************************************************mobileye AWS display*****************************************************
+ *  message ID:0x700
+ *  member:                 type            physical unit       range                   note
+ *  dusk_time:              double                /              0,1
+ *  night_time              double                /              0,1
+ *******************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x700(VCI_CAN_OBJ receivedata)
+{
+    ServiceCarStatus.aws_display.dusk_time = (receivedata.Data[0] >> 3) & 0x1;
+    ServiceCarStatus.aws_display.night_time = (receivedata.Data[0] >> 4) & 0x1;
+    ServiceCarStatus.aws_display.lanes_on = receivedata.Data[4] & 0x1;
+    //std::cout << "lanes_on:" << ServiceCarStatus.aws_display.lanes_on << std::endl;
+}
+
+/******************************************************mobileye lane***********************************************************
+ *  message ID:0x737
+ *  member:                 type            physical unit       range                   note
+ *  curvature:              double             1/meter      [-0.12, 0.12]       "a" in the equation:y = ax^2+bx+c
+ *  heading:                double                /          [-1.0, 1.0]        "b" in the equation:y = ax^2+bx+c
+ *  construction area:      bool                  /               /                       /
+ *  pitch angle:            double             radians      [-0.05, 0.05]      pitch of the host vehicle(derived from lanes analysis)
+ *  yaw angle:              double             radians            /            yaw of the host vehicle(derived from lanes analysis)
+ *  right_LDW:              bit/bool              /              0,1           0 stands for unavailable, 1 for available
+ *  left_LDW:               bit/bool              /              0,1           0 stands for unavailable, 1 for available
+ *******************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x737(VCI_CAN_OBJ receivedata)
+{
+    //lane curvature
+    int32_t tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    tmp <<= 16;
+    tmp >>= 16;
+    ServiceCarStatus.Lane.curvature = tmp * 3.81 * 1e-6;
+    //std::cout<<"curvature:"<<ServiceCarStatus.Lane.curvature<<std::endl;
+
+    tmp = 0;
+
+    //lane heading
+    tmp = ((receivedata.Data[3] & 0xf) << 8) | receivedata.Data[2];
+    tmp <<= 20;
+    tmp >>= 20;
+    ServiceCarStatus.Lane.heading = tmp * 0.0005;
+
+    tmp = 0;
+
+    //construction area
+    ServiceCarStatus.Lane.is_ca = (receivedata.Data[3] >> 4) & 0x1;
+
+    //left_LDW
+    ServiceCarStatus.Lane.is_left_LDW_available = (receivedata.Data[3] >> 5) & 0x1;
+
+    //right_LDW
+    ServiceCarStatus.Lane.is_right_LDW_available = (receivedata.Data[3] >> 6) & 0x1;
+
+    //yaw
+    tmp = (receivedata.Data[5] >> 8) | receivedata.Data[4];
+    tmp <<= 16;
+    tmp >>= 16;
+    //ServiceCarStatus.Lane.yaw = (tmp - 0x7fff) / 1024.0;
+    ServiceCarStatus.Lane.yaw = tmp * 0.000977;
+    std::cout << "yaw:"<< ServiceCarStatus.Lane.yaw<< std::endl;
+
+    tmp = 0;
+
+    //pitch
+    tmp = (receivedata.Data[7] >> 8) | receivedata.Data[6];
+    tmp <<= 16;
+    tmp >>= 16;
+    //ServiceCarStatus.Lane.yaw = (tmp - 0x7fff) / 1024.0 / 512;
+    ServiceCarStatus.Lane.yaw = tmp * 0.000002;
+    std::cout << "pitch:" << ServiceCarStatus.Lane.pitch << std::endl;
+}
+
+/****************************************************  mobileye obstacle status  ****************************************************************************
+ *  message ID:0x738
+ *  member:                  type           physical unit       range               note
+ *  num_obstacles            int                   /           [0:255]                /
+ *  timestamp                int                   ms          [0:255]          only the lowest 8 bits of the timestamp is given
+ *  app_version:             int                   /           [0:255]          vesion info consists of X.Y.Z.W
+ *  active_version           int/2bits             /            [0:3]           index of the active section of app_version signal
+ *  left_close_rang_cut_in   bool                  /             0,1            0 false, 1 true
+ *  right_close_rang_cut_in  bool                  /             0,1            0 false, 1 true
+ *  go                       enum                  /           0,1...15         0 stop, 1 go, 2 undecided, 3 driver decisions is required, 4-14 unused, 15 not calculated
+ *  protocol version         uchar/8bit            /          0x00...0xff             /
+ *  is_close_car             bool                  /             0,1            0 no close, 1 close car exists
+ *  failsafe                 int/4bit              /            [0:7]           failsafe situation, 0000 no failsafe, 0001 low sun, 0010 blur image, 0100 1000 unused
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x738(VCI_CAN_OBJ receivedata)
+{
+    //num_obstacles
+    ServiceCarStatus.obstacleStatus.num_obstacles = receivedata.Data[0];
+    //std::cout << ServiceCarStatus.obstacleStatus.num_obstacles<< std::endl;
+
+
+    //timestamp
+    ServiceCarStatus.obstacleStatus.timestamp = receivedata.Data[1];
+
+    //app version
+    ServiceCarStatus.obstacleStatus.app_version = receivedata.Data[2];
+
+    //active version
+    ServiceCarStatus.obstacleStatus.active_version = receivedata.Data[3] & 0x3;
+
+    //is left close rang cut in
+    ServiceCarStatus.obstacleStatus.is_left_close_rang_cut_in = (receivedata.Data[3] >> 2) & 0x1;
+
+    //is right close rang cut in
+    ServiceCarStatus.obstacleStatus.is_right_close_rang_cut_in = (receivedata.Data[3] >> 3) & 0x1;
+
+    //go
+    ServiceCarStatus.obstacleStatus.go = receivedata.Data[3] >> 4;
+
+    //protocol version
+    ServiceCarStatus.obstacleStatus.protocol_version = receivedata.Data[4];
+
+    //close car
+    ServiceCarStatus.obstacleStatus.is_close_car = receivedata.Data[5] & 0x1;
+
+    //failsafe
+    ServiceCarStatus.obstacleStatus.failsafe = (receivedata.Data[5] >> 1) & 0xf;
+}
+
+/****************************************************  mobileye obstacle data a  ****************************************************************************
+ *  message ID:0x739
+ *  member:                  type           physical unit       range               note
+ *  obstacle_ID              int                   /           [0:63]           new obstacles are given the last used free ID
+ *  obstacle_pos_x           double                m           [0,250]          longtitude position of the obstacle relative to the ref point
+ *  obstacle_pos_y           double                m       [-31.93,31.93]       lateral position of the obstacle, error relative to pos_x  below 10% or 2meters
+ *  blinker_info             int/enum              /            [0:4]           0 unavailable, 1 off, 2 left, 3 right, 4 both   indicated blinkers status
+ *  cut_in_and_out           int                   /            [0:4]           0 undefined, 1 in_host_lane, 2 out_host_lane, 3 cut_in, 4 cut_out
+ *                                                                              cut_in: target entering the host lane, cut_out: exiting  but not distinguish between sides
+ *  obstacle_rel_vel_x       double               m/s      [-127.93,127.93]     relative longtitude velocity of the obstacle
+ *  obstacle_status          int/enum              /            [0:6]           0 undefined, 1 standing(never moved, back lights on), 2 stopped(moveable), 3 moving
+ *                                                                              4 oncoming,  5 parked(never moved, back lights off), 6 unused
+ *  is_obstacle_brake_lights bool                  /             0,1            0 object's brake light off or not identified, 1 object's brake light on
+ *  obstacle_valid           int/enum              /            [1:2]           1 new valid(detected this frame), 2 older valid
+ *************************************************************************************************************************************************************/
+obstacle_data_a iv::control::CanUtil::impl_0x739(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+    obstacle_data_a obs_tmp;
+
+    //obstacle id
+    obs_tmp.obstacle_ID = receivedata.Data[0];
+    //ServiceCarStatus.obstacleStatusA.obstacle_ID = receivedata.Data[0];
+
+    //obstacle pos x
+    tmp = ((receivedata.Data[2] & 0xf) << 8) | receivedata.Data[1];
+    obs_tmp.obstacle_pos_x = tmp * 0.0625;
+    //ServiceCarStatus.obstacleStatusA.obstacle_pos_x = tmp * 0.0625;
+
+    tmp = 0;
+
+    //obstacle pos y
+    tmp = ((receivedata.Data[4] & 0x3) << 8) | receivedata.Data[3];
+    obs_tmp.obstacle_pos_y = tmp * 0.0625;
+    //ServiceCarStatus.obstacleStatusA.obstacle_pos_y = tmp * 0.0625;
+
+    tmp = 0;
+    //blinker info
+    obs_tmp.blinker_info = (receivedata.Data[4] >> 2) & 0x7;
+    //ServiceCarStatus.obstacleStatusA.blinker_info = (receivedata.Data[4] >> 2) & 0x7;
+
+    //cut in and out
+    obs_tmp.cut_in_and_out = receivedata.Data[4] >> 5;
+    //ServiceCarStatus.obstacleStatusA.cut_in_and_out = receivedata.Data[4] >> 5;
+
+    //obstacle rel vel x
+    tmp = ((receivedata.Data[6] & 0xf) << 8) | receivedata.Data[5];
+    obs_tmp.obstacle_rel_vel_x = tmp * 0.0625;
+    //ServiceCarStatus.obstacleStatusA.obstacle_rel_vel_x = tmp * 0.0625;
+
+    tmp = 0;
+
+    //obstacle type
+    obs_tmp.obstacle_type = (receivedata.Data[6] >> 4) & 0x7;
+    //ServiceCarStatus.obstacleStatusA.obstacle_type = (receivedata.Data[6] >> 4) & 0x7;
+
+    //obstacle status
+    obs_tmp.obstacle_status = receivedata.Data[7] & 0x7;
+    //ServiceCarStatus.obstacleStatusA.obstacle_status = receivedata.Data[7] & 0x7;
+
+    //obstacle brake lights
+    obs_tmp.is_obstacle_brake_lights = (receivedata.Data[7] >> 3) & 0x1;
+    //ServiceCarStatus.obstacleStatusA.is_obstacle_brake_lights = (receivedata.Data[7] >> 3) & 0x1;
+
+    //obstacle valid
+    obs_tmp.obstacle_valid = (receivedata.Data[7] >> 6) & 0x7;
+    //ServiceCarStatus.obstacleStatusA.obstacle_valid = (receivedata.Data[7] >> 6) & 0x7;
+    return obs_tmp;
+}
+
+/****************************************************  mobileye obstacle data b  ****************************************************************************
+ *  message ID:0x73a
+ *  member:                  type           physical unit       range               note
+ *  obstacle_length          double                m           [0,31]           length of the obstacle(longitude axis)
+ *  obstacle_width           double                m           [0,12.5]         width of  the obstacle(lateral axis)
+ *  obstacle_age             int                   /           [0:255]          value starts at 1 when it is first detected, increaments in i each frame
+ *  obstacle_lane            int/enum              /           [0:3]            0 not assigned, 1 ego lane, 2 next lane(left or right) or next next lane,
+ *                                                                              3 invalid signal
+ *  is_cipv_flag             int/enum              /            [0:1]           0 not cipv, 1 cipv(closest in path vehicle)
+ *  radar_pos_x              double                m           [0,250]          longtitude postion of the primary radar target matched to the vision target, dist=relative to ref point
+ *                                                                              if no radar target is matched, value = 0xfff
+ *  radar_vel_x              double               m/s       [-127.93,127.93]    longitude velocity of the radar target matched to the vision targets, if no radar target is matched value=0xfff
+ *                                                                              4 oncoming,  5 parked(never moved, back lights off), 6 unused
+ *  radar_match_confidence   int                   /            [0:5]           0 no match, 1 multi match: radar doesn't describe well, 2-4 vision-radar match:with bounded error between
+ *                                                                              vision and radar measurements higher->smaller error, 5 high confidence match
+ *  matched_radar_id         int                   /           [0:127]          ID of Primary radar target matched to the vision target if applicable
+ *************************************************************************************************************************************************************/
+obstacle_data_b iv::control::CanUtil::impl_0x73a(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+    obstacle_data_b obs_tmp;
+
+    //obstacle length
+    tmp = receivedata.Data[0];
+    obs_tmp.obstacle_length = tmp * 0.5;
+    //ServiceCarStatus.obstacleStatusB.obstacle_length = tmp * 0.5;
+
+    tmp = 0;
+
+    //obstacle width
+    tmp = receivedata.Data[1];
+    obs_tmp.obstacle_width = tmp * 0.05;
+    //ServiceCarStatus.obstacleStatusB.obstacle_width = tmp * 0.05;
+
+    tmp = 0;
+
+    //obstacle age
+    obs_tmp.obstacle_age = receivedata.Data[2];
+    //ServiceCarStatus.obstacleStatusB.obstacle_age = receivedata.Data[2];
+
+    //obstacle lane
+    obs_tmp.obstacle_lane = receivedata.Data[3] & 0x3;
+    //ServiceCarStatus.obstacleStatusB.obstacle_lane = receivedata.Data[3] & 0x3;
+
+    //is cipv flag
+    obs_tmp.is_cipv_flag = (receivedata.Data[3] >> 2) & 0x1;
+    //ServiceCarStatus.obstacleStatusB.is_cipv_flag = (receivedata.Data[3] >> 2) & 0x1;
+
+    //radar pos x
+    tmp = (receivedata.Data[4] << 4) | (receivedata.Data[3] >> 4);
+    obs_tmp.radar_pos_x = tmp * 0.0625;
+    //ServiceCarStatus.obstacleStatusB.radar_pos_x = tmp * 0.0625;
+
+    tmp = 0;
+
+    //radar vel x
+    tmp = ((receivedata.Data[6] & 0xf) << 8) | receivedata.Data[5];
+    tmp <<= 20;
+    tmp >>= 20;
+    obs_tmp.radar_vel_x = tmp * 0.0625;
+    //ServiceCarStatus.obstacleStatusB.radar_vel_x = tmp * 0.0625;
+
+    tmp = 0;
+
+    //radar match confidence
+    obs_tmp.radar_match_confidence = (receivedata.Data[6] >> 4) & 0x7;
+    //ServiceCarStatus.obstacleStatusB.radar_match_confidence = (receivedata.Data[6] >> 4) & 0x7;
+
+    //matched radar ID
+    obs_tmp.matched_radar_id = receivedata.Data[7] & 0x7f;
+    //ServiceCarStatus.obstacleStatusB.matched_radar_id = receivedata.Data[7] & 0x7f;
+
+    return obs_tmp;
+}
+
+/****************************************************  mobileye obstacle data c  ****************************************************************************
+ *  message ID:0x73b
+ *  member:                  type           physical unit       range               note
+ *  obstacle_angle_rate      double           degree/s     [-327.68, 327.68]    Angle rate of Center of Obstacle, negative->moved to left
+ *  obstcale_scale_change    double            pix/s       [-6.5532, 6.5532]    /
+ *  object_accel_x           double            m/s2         [-14.97, 14.97]     longtitude acceleration of the object
+ *  obstacle_replaced        bool                /               0,1            0 not replaced in this frame, 1 replace in this frame
+ *  obstacle_angle           double           degree        [-327.68,327.68]    Angle to Center of Obstacle in degrees, 0 indicates that the obstacle is in
+ *                                                                              exactly in front of us, a positive angle indicates that theobstacle is to the right
+ *************************************************************************************************************************************************************/
+obstacle_data_c iv::control::CanUtil::impl_0x73b(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+    obstacle_data_c obs_tmp;
+
+    //obstacle angle rate
+    tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    tmp <<= 16;
+    tmp >>= 16;
+    obs_tmp.obstacle_angle_rate = tmp * 0.01;
+    //ServiceCarStatus.obstacleStatusC.obstacle_angle_rate = tmp * 0.01;
+
+    tmp = 0;
+
+    //obstacle scale change
+    tmp = (receivedata.Data[3] << 8) | receivedata.Data[2];
+    tmp <<= 16;
+    tmp >>= 16;
+    obs_tmp.obstacle_scale_change = tmp * 0.0002;
+    //ServiceCarStatus.obstacleStatusC.obstacle_scale_change = tmp * 0.0002;
+
+    tmp = 0;
+
+    //object accel x
+    tmp = ((receivedata.Data[5] & 0x3) << 8) | receivedata.Data[4];
+    tmp <<= 22;
+    tmp >>= 22;
+    obs_tmp.object_accel_x = tmp * 0.03;
+    //ServiceCarStatus.obstacleStatusC.object_accel_x = tmp * 0.03;
+
+    tmp = 0;
+
+    //obstacle replaced
+    obs_tmp.is_obstacle_replaced = (receivedata.Data[5] >> 4) & 0x1;
+    //ServiceCarStatus.obstacleStatusC.is_obstacle_replaced = (receivedata.Data[5] >> 4) & 0x1;
+
+    //obstacle angle
+    tmp = (receivedata.Data[7] << 8) | receivedata.Data[6];
+    tmp <<= 16;
+    tmp >>= 16;
+    obs_tmp.obstacle_angle = tmp * 0.01;
+    //ServiceCarStatus.obstacleStatusC.obstacle_angle = tmp * 0.01;
+
+    return obs_tmp;
+}
+
+/****************************************************  mobileye aftermarket lane  ****************************************************************************
+ *  message ID:0x669
+ *  member:                  type           physical unit       range               note
+ *  lane_conf_left           int/2bit              /            [0:3]            0 lowest, 3 highest
+ *  is_ldw_availablity_left  bool                  /             0,1             lane_conf>=2->on, speed>55km/h, configuration of LDW>=1
+ *  lane_type_left           int/enum              /            [0:6]            0 dashed, 1 solid, 2 none, 3 road edge, 4 double lane mark, 5 sbott's dots, 6 invalid
+ *  dist_to_lane_l           double                m           [-40:40]          "c" in the equation:y = ax^2+bx+c
+ *  lane_conf_right          int/2bit              /            [0:3]            0 lowest, 3 highest
+ *  is_ldw_availablity_right  bool                  /             0,1             lane_conf>=2->on, speed>55km/h, configuration of LDW>=1
+ *  lane_type_right          int/enum              /            [0:6]            0 dashed, 1 solid, 2 none, 3 road edge, 4 double lane mark, 5 sbott's dots, 6 invalid
+ *  dist_to_lane_r           double                m           [-40:40]          "c" in the equation:y = ax^2+bx+c
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x669(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp;
+    //lane confidence left
+    tmp = receivedata.Data[0] & 0x3;
+    tmp <<= 30;
+    tmp >>= 30;
+    ServiceCarStatus.aftermarketLane.lane_conf_left = tmp;
+    //std::cout << "left confidence:" << ServiceCarStatus.aftermarketLane.lane_conf_left << std::endl;
+
+    tmp = 0;
+
+    //is LDW availability left
+    ServiceCarStatus.aftermarketLane.is_ldw_availablility_left = (receivedata.Data[0] >> 2) & 0x1;
+
+    //lane type left
+    tmp = (receivedata.Data[0] >> 4) & 0xf;
+    tmp <<= 28;
+    tmp >>= 28;
+    ServiceCarStatus.aftermarketLane.lane_type_left = tmp;
+    std::cout << "lane_type_left: " << ServiceCarStatus.aftermarketLane.lane_type_left << std::endl;
+
+    tmp = 0;
+
+    //dist to left lane
+
+    tmp = (receivedata.Data[2] << 4) | ((receivedata.Data[1] >> 4) & 0xf);
+    tmp <<= 20;
+    tmp >>= 20;
+    ServiceCarStatus.aftermarketLane.dist_to_lane_l = tmp * 0.02;
+    std::cout << "dist_to_lane_l:" << ServiceCarStatus.aftermarketLane.dist_to_lane_l << std::endl;
+
+    tmp = 0;
+
+    //lane confidence right
+    tmp = receivedata.Data[5] & 0x3;
+    tmp <<= 30;
+    tmp >>= 30;
+    ServiceCarStatus.aftermarketLane.lane_conf_right = tmp;
+    //std::cout << "right confidence:" << ServiceCarStatus.aftermarketLane.lane_conf_right << std::endl;
+
+    tmp = 0;
+
+    //is LDW availability right
+    ServiceCarStatus.aftermarketLane.is_ldw_availablility_right = (receivedata.Data[5] >> 2) & 0x1;
+
+    //lane type right
+    tmp = (receivedata.Data[5] >> 4) & 0xf;
+    tmp <<= 28;
+    tmp >>= 28;
+    ServiceCarStatus.aftermarketLane.lane_type_right = tmp;
+    std::cout<<"lane_type_right: " << ServiceCarStatus.aftermarketLane.lane_type_right << std::endl;
+
+    tmp = 0;
+
+    //dist to right lane
+    tmp = (receivedata.Data[7] << 4) | ((receivedata.Data[6] >> 4) & 0xf);
+    tmp <<= 20;
+    tmp >>= 20;
+    ServiceCarStatus.aftermarketLane.dist_to_lane_r = tmp * 0.02;
+    std::cout << "dist_to_lane_r:" << ServiceCarStatus.aftermarketLane.dist_to_lane_r << std::endl;
+
+    tmp = 0;
+}
+
+/****************************************************  mobileye LKA left lane a ****************************************************************************
+ *  message ID:0x766
+ *  member:                  type           physical unit       range               note
+ *  lane_type                enum                  /            [0:6]            0 dashed, 1 solid, 2 undecided, 3 road edge, 4 double lane mark, 5 bott's dots, 6 invalid
+ *  quality                  enum                  /            [0:3]            0,1 low quality:lane measurements not valid and LDW not given, 2,3 high quality
+ *  model_degree             enum                  /            [1:3]            1 linear model, 2 parabolic model, 3 3rd-degree model
+ *  position                 double                m          [-127,128]         physical distance between lane mark and camera on the lateral position
+ *  curvature                double                /         [-0.02, 0.02]       given a very low curvature derivative, positive curvature indicates a right hand side curve
+ *  curvature_derivative     double                /      [-0.00012, 0.00012]    /
+ *  width_left_marking       double                m           [0, 2.5]          left lane marking width
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x766(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    //lane type
+    ServiceCarStatus.LKAleftLaneA.lane_type = receivedata.Data[0] & 0xf;
+
+    //quality
+    ServiceCarStatus.LKAleftLaneA.quality = (receivedata.Data[0] >> 4) & 0x3;
+
+    //model degree
+    ServiceCarStatus.LKAleftLaneA.model_degree = (receivedata.Data[0] >> 6) & 0x3;
+
+    //position
+    tmp = (receivedata.Data[2] << 8) | receivedata.Data[1];
+    tmp <<= 16;
+    tmp >>= 16;
+    ServiceCarStatus.LKAleftLaneA.position = tmp / 256.0;
+    //ServiceCarStatus.LKAleftLaneA.position = tmp * 0.003906;
+
+    tmp = 0;
+
+    //curvature
+    tmp = (receivedata.Data[4] << 8) | receivedata.Data[3];
+    ServiceCarStatus.LKAleftLaneA.curvature = (tmp - 0x7fff) / 1024.0 / 1000;
+    //ServiceCarStatus.LKAleftLaneA.curvature = tmp * 0.000001 + -0.031999;
+
+    tmp = 0;
+
+    //curvature derivative
+    tmp = (receivedata.Data[6] << 8) | receivedata.Data[5];
+    ServiceCarStatus.LKAleftLaneA.curvature_derivative = (double)(tmp - 0x7fff) / (1 << 28);
+    //ServiceCarStatus.LKAleftLaneA.curvature_derivative = tmp * 0.000000 + -0.000122;
+
+    tmp = 0;
+
+    //width left marking
+    tmp = receivedata.Data[7];
+    ServiceCarStatus.LKAleftLaneA.width_left_marking = tmp * 0.01;
+
+}
+
+/****************************************************  mobileye LKA left lane b ****************************************************************************
+ *  message ID:0x767
+ *  member:                  type           physical unit       range               note
+ *  heading_angle            double            radians     [-0.357, 0.357]       physical slope of the lane mark   positive->steering towards the right
+ *  view_range               double                m         [0, 127.996]        physical view range of lane mark
+ *  view_range_availability  enum                  /            0,1              0 not valid, 1 valid
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x767(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    //heading angle
+    tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    ServiceCarStatus.LKAleftLaneB.heading_angle = (tmp - 0x7fff) / 1024;
+    //ServiceCarStatus.LKAleftLaneB.heading_angle = tmp * 0.000977 + -31.999023;
+
+    tmp = 0;
+
+    //view range
+    tmp = ((receivedata.Data[3] & 0x7f) << 8) | receivedata.Data[2];
+    ServiceCarStatus.LKAleftLaneB.view_range = tmp / 256.0;
+    //ServiceCarStatus.LKAleftLaneB.view_range = tmp * 0.003906;
+
+    tmp = 0;
+
+    //view range availability
+    ServiceCarStatus.LKAleftLaneB.is_view_range_availability = (receivedata.Data[3] >> 7) & 0x1;
+
+}
+
+/****************************************************  mobileye LKA right lane a ****************************************************************************
+ *  message ID:0x768
+ *  member:                  type           physical unit       range               note
+ *  lane_type                enum                  /            [0:6]            0 dashed, 1 solid, 2 undecided, 3 road edge, 4 double lane mark, 5 bott's dots, 6 invalid
+ *  quality                  enum                  /            [0:3]            0,1 low quality:lane measurements not valid and LDW not given, 2,3 high quality
+ *  model_degree             enum                  /            [1:3]            1 linear model, 2 parabolic model, 3 3rd-degree model
+ *  position                 double                m          [-127,128]         physical distance between lane mark and camera on the lateral position
+ *  curvature                double                /         [-0.02, 0.02]       given a very low curvature derivative, positive curvature indicates a right hand side curve
+ *  curvature_derivative     double                /      [-0.00012, 0.00012]    /
+ *  width_right_marking      double                m           [0, 2.5]          right lane marking width
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x768(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    //lane type
+    ServiceCarStatus.LKArightLaneA.lane_type = receivedata.Data[0] & 0xf;
+
+    //quality
+    ServiceCarStatus.LKArightLaneA.quality = (receivedata.Data[0] >> 4) & 0x3;
+
+    //model degree
+    ServiceCarStatus.LKArightLaneA.model_degree = (receivedata.Data[0] >> 6) & 0x3;
+
+    //position
+    tmp = (receivedata.Data[2] << 8) | receivedata.Data[1];
+    tmp <<= 16;
+    tmp >>= 16;
+    ServiceCarStatus.LKArightLaneA.position = tmp / 256.0;
+    //ServiceCarStatus.LKArightLaneA.position = tmp * 0.003906;
+
+    tmp = 0;
+
+    //curvature
+    tmp = (receivedata.Data[4] << 8) | receivedata.Data[3];
+    ServiceCarStatus.LKArightLaneA.curvature = (tmp - 0x7fff) / 1024.0 / 1000;
+    //ServiceCarStatus.LKArightLaneA.curvature = tmp * 0.000001 + -0.031999;
+
+    tmp = 0;
+
+    //curvature derivative
+    tmp = (receivedata.Data[6] << 8) | receivedata.Data[5];
+    ServiceCarStatus.LKArightLaneA.curvature_derivative = (double)(tmp - 0x7fff) / (1 << 28);
+    //ServiceCarStatus.LKArightLaneA.curvature_derivative = tmp * 0.000000 + -0.000122;
+
+    tmp = 0;
+
+    //width left marking
+    tmp = receivedata.Data[7];
+    ServiceCarStatus.LKArightLaneA.width_left_marking = tmp * 0.01;
+}
+
+/****************************************************  mobileye LKA right lane b ****************************************************************************
+ *  message ID:0x767
+ *  member:                  type           physical unit       range               note
+ *  heading_angle            double            radians     [-0.357, 0.357]       physical slope of the lane mark   positive->steering towards the right
+ *  view_range               double                m         [0, 127.996]        physical view range of lane mark
+ *  view_range_availability  enum                  /            0,1              0 not valid, 1 valid
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x769(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    //heading angle
+    tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    ServiceCarStatus.LKArightLaneB.heading_angle = (tmp - 0x7fff) / 1024;
+    //ServiceCarStatus.LKArightLaneB.heading_angle = tmp * 0.000977 + -31.999023;
+
+    tmp = 0;
+
+    //view range
+    tmp = ((receivedata.Data[3] & 0x7f) << 8) | receivedata.Data[2];
+    ServiceCarStatus.LKArightLaneB.view_range = tmp / 256.0;
+    //ServiceCarStatus.LKArightLaneB.view_range = tmp * 0.003906;
+
+    tmp = 0;
+
+    //view range availability
+    ServiceCarStatus.LKArightLaneB.is_view_range_availability = (receivedata.Data[3] >> 7) & 0x1;
+
+}
+
+/****************************************************  mobileye next lane a **********************************************************************************
+ *  message ID:0x76c
+ *  member:                  type           physical unit       range               note
+ *  lane_type                enum                  /            [1:2]            1 solid, 2 undecided
+ *  quality                    /                   /              /              not yet implemented for next lanes
+ *  model_degree             enum                  /            [1:3]            1 linear model, 2 parabolic model, 3 3rd-degree model
+ *  position                 double                m          [-127,128]         physical distance between lane mark and camera on the lateral position
+ *  curvature                double                /         [-0.02, 0.02]       given a very low curvature derivative, positive curvature indicates a right hand side curve
+ *  curvature_derivative     double                /      [-0.00012, 0.00012]    /
+ *  lane_mark_widt           double                m           [0, 2.5]          lane marking width
+ *************************************************************************************************************************************************************/
+next_lane_a iv::control::CanUtil::impl_0x76c(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+    next_lane_a nextLane_tmp;
+
+    //lane type
+    nextLane_tmp.lane_type = receivedata.Data[0] & 0xf;
+    //ServiceCarStatus.nextLaneA.lane_type = receivedata.Data[0] & 0xf;
+
+    //quality
+    nextLane_tmp.quality = (receivedata.Data[0] >> 4) & 0x3;
+    //ServiceCarStatus.nextLaneA.quality = (receivedata.Data[0] >> 4) & 0x3;
+
+    //model degree
+    nextLane_tmp.model_degree = (receivedata.Data[0] >> 6) & 0x3;
+    //ServiceCarStatus.nextLaneA.model_degree = (receivedata.Data[0] >> 6) & 0x3;
+
+    //position
+    tmp = (receivedata.Data[2] << 8) | receivedata.Data[1];
+    tmp <<= 16;
+    tmp >>= 16;
+    nextLane_tmp.position = tmp * 0.003906;
+    //ServiceCarStatus.nextLaneA.position = tmp / 256.0;
+    //ServiceCarStatus.nextLaneA.position = tmp * 0.003906;
+
+    tmp = 0;
+
+    //curvature
+    tmp = (receivedata.Data[4] << 8) | receivedata.Data[3];
+    nextLane_tmp.curvature = tmp * 0.000001 + -0.031999;
+    //ServiceCarStatus.nextLaneA.curvature = (tmp - 0x7fff) / 1024.0 / 1000;
+    //ServiceCarStatus.nextLaneA.curvature = tmp * 0.000001 + -0.031999;
+
+    tmp = 0;
+
+    //curvature derivative
+    tmp = (receivedata.Data[6] << 8) | receivedata.Data[5];
+    nextLane_tmp.curvature_derivative = tmp * 0.000000 + -0.000122;
+    //ServiceCarStatus.nextLaneA.curvature_derivative = (double)(tmp - 0x7fff) / (1 << 28);
+    //ServiceCarStatus.nextLaneA.curvature_derivative = tmp * 0.000000 + -0.000122;
+
+    tmp = 0;
+
+    //width left marking
+    tmp = receivedata.Data[7];
+    nextLane_tmp.lane_mark_width = tmp * 0.01;
+    //ServiceCarStatus.nextLaneA.lane_mark_width = tmp * 0.01;
+
+    return nextLane_tmp;
+}
+
+/****************************************************  mobileye LKA right lane b ****************************************************************************
+ *  message ID:0x76d
+ *  member:                  type           physical unit       range               note
+ *  heading_angle            double            radians     [-0.357, 0.357]       physical slope of the lane mark   positive->steering towards the right
+ *  view_range               double                m         [0, 127.996]        physical view range of lane mark
+ *  view_range_availability  enum                  /            0,1              0 not valid, 1 valid
+ *************************************************************************************************************************************************************/
+next_lane_b iv::control::CanUtil::impl_0x76d(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    next_lane_b nextLane_tmp;
+
+    //heading angle
+    tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    nextLane_tmp.heading_angle = tmp * 0.000977 + -31.999023;
+    //ServiceCarStatus.nextLaneB.heading_angle = (tmp - 0x7fff) / 1024;
+    //ServiceCarStatus.nextLaneB.heading_angle = tmp * 0.000977 + -31.999023;
+
+    tmp = 0;
+
+    //view range
+    tmp = ((receivedata.Data[3] & 0x7f) << 8) | receivedata.Data[2];
+    nextLane_tmp.view_range = tmp * 0.003906;
+    //ServiceCarStatus.nextLaneB.view_range = tmp / 256.0;
+    //ServiceCarStatus.nextLaneB.view_range = tmp * 0.003906;
+
+    tmp = 0;
+
+    //view range availability
+    nextLane_tmp.is_view_range_availability = (receivedata.Data[3] >> 7) & 0x1;
+    //ServiceCarStatus.nextLaneB.is_view_range_availability = (receivedata.Data[3] >> 7) & 0x1;
+
+    return nextLane_tmp;
+}
+
+/****************************************************  mobileye reference points ******************************************************************************
+ *  message ID:0x76a
+ *  member:                  type           physical unit       range               note
+ *  ref_point_1_position     double               m      [-127.996, 127.996]     physical distance between camera and reference point 1 on lateral axis.
+ *                                                                               The reference point defines the lateral location of the lane center at ref-Point distance.
+ *                                                                               ref Point 1 is this measurement at 1 second headway.
+ *  ref_point_1_dist         double               m       [0, 127.99609376]      physical distance between reference point and camera
+ *  ref_point_1_validity     enum                 /              0,1             0 invalid, 1 valid
+ *  ref_point_2_position     double               m      [-127.996, 127.996]     empty! physical distance between camera and reference point 2 on lateral axis.
+ *                                                                               The reference point defines the lateral location of the lane center at ref-Point distance.
+ *                                                                               ref Point 2 is this measurement at 1 second headway.
+ *  ref_point_2_dist         double               m       [0, 127.99609376]      empty! physical distance between reference point and camera
+ *  ref_point_2_validity     enum                 /              0,1             empty! 0 invalid, 1 valid
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x76a(VCI_CAN_OBJ receivedata)
+{
+    int32_t tmp = 0;
+
+    //ref_point_1_position
+    //tmp = (receivedata.Data[1] << 8) | receivedata.Data[0];
+    ServiceCarStatus.refPoints.ref_point_1_position = (tmp - 0x7fff) / 256.0;
+    ServiceCarStatus.refPoints.ref_point_1_position = tmp * 0.003906 + -127.996094;
+
+    tmp = 0;
+
+    //ref_point_1_dist
+    tmp = ((receivedata.Data[3] & 0x7f) << 8) | receivedata.Data[2];
+    //ServiceCarStatus.refPoints.ref_point_1_dist = tmp / 256.0;
+    ServiceCarStatus.refPoints.ref_point_1_dist = tmp * 0.003906;
+
+    tmp = 0;
+
+    //is ref point 1 validity
+    ServiceCarStatus.refPoints.is_ref_point_1_validity = (receivedata.Data[3] >> 7) & 0x1;
+
+    //ref_point_2_position
+    tmp = (receivedata.Data[5] << 8) | receivedata.Data[4];
+    //ServiceCarStatus.refPoints.ref_point_2_position = (tmp - 0x7fff) / 256.0;
+    ServiceCarStatus.refPoints.ref_point_2_position = tmp * 0.003906 + -127.996094;
+
+    tmp = 0;
+
+    //ref_point_2_dist
+    tmp = ((receivedata.Data[7] & 0x7f) << 8) | receivedata.Data[6];
+    //ServiceCarStatus.refPoints.ref_point_2_dist = tmp / 256.0;
+    ServiceCarStatus.refPoints.ref_point_2_dist = tmp * 0.003906;
+
+    tmp = 0;
+
+    //is ref point 2 validity
+    ServiceCarStatus.refPoints.is_ref_point_2_validity = (receivedata.Data[7] >> 7) & 0x1;
+}
+
+/**********************************************  mobileye number of next lane markers reported **************************************************************
+ *  message ID:0x76b
+ *  member:                             type           physical unit       range               note
+ *  num_of_next_lane_mark_reported      enum                 /              1,2    indicates how many extra lane markers are also reported, on top of left
+ *                                                                                 and right lane. Currently two lane marks are always reported one for left and one for
+ *                                                                                 right, and they are valid only if the lane type is Solid.
+ *************************************************************************************************************************************************************/
+void iv::control::CanUtil::impl_0x76b(VCI_CAN_OBJ receivedata)
+{
+    //num_of_next_lane_mark_reported
+    ServiceCarStatus.numOfNextLaneMarkReported.num_of_next_lane_mark_reported = receivedata.Data[0];
+}
+
+void iv::control::CanUtil::receive_radar() {
+    int32_t range, rate, angle;
+	while (m_connect)
+	{
+		VCI_CAN_OBJ receivedata[2500];
+		int res = VCI_Receive(m_devtype, m_devind, m_cannum_radar, receivedata, 2500, 10);
+		int radar_ID_index = -1;
+		if (res <= 0)	//未能从can卡中读到数
+		{
+#ifdef linux
+            usleep(1000);
+#endif
+#ifdef WIN32
+            Sleep(1);
+#endif
+            continue;
+		}
+        for (int i = 0; i < res; i++) {
+			//对应毫米波雷达数据解析
+			radar_ID_index = receivedata[i].ID - 0x500;
+			if (radar_ID_index >= 0x00 && radar_ID_index <= 0x3f) {
+                ServiceCarStatus.mRadarS = 10;
+				angle = ((receivedata[i].Data[1] & 0x1F) << 5) + ((receivedata[i].Data[2] & 0xF8) / 8);
+				range = ((receivedata[i].Data[2] & 0x07) << 8) + receivedata[i].Data[3];
+				rate = ((receivedata[i].Data[6] & 0x3F) << 8) | receivedata[i].Data[7];
+				if (angle & 0x200) {
+					angle = angle | 0xFFFFFC00;
+				}
+				if (rate & 0x2000) {
+					rate = rate | 0xFFFFC000;
+				}
+				//If angle and range both are 0, it is an invalid data.
+				if (angle != 0 || range != 0) {
+                    obs_find_flag = true;
+                    ServiceCarStatus.obs_radar[radar_ID_index].valid = true;
+                    ServiceCarStatus.obs_radar[radar_ID_index].nomal_x = range * 0.1 * sin(angle * 1.0 / 1800.0 * M_PI);
+                    ServiceCarStatus.obs_radar[radar_ID_index].nomal_y = range * 0.1 * cos(angle * 1.0 / 1800.0 * M_PI);
+                    ServiceCarStatus.obs_radar[radar_ID_index].speed_relative = rate * 1.0 / 100.0;
+                    ServiceCarStatus.obs_radar[radar_ID_index].speed_x = ServiceCarStatus.obs_radar[radar_ID_index].speed_relative * sin(angle / 1800.0 * M_PI);
+                    ServiceCarStatus.obs_radar[radar_ID_index].speed_y = ServiceCarStatus.obs_radar[radar_ID_index].speed_relative * cos(angle / 1800.0 * M_PI);
+				}
+				else {
+					ServiceCarStatus.obs_radar[radar_ID_index].valid = false;
+				}
+			}
+        }
+    }
+}
+
+void iv::control::CanUtil::obs_print(std::vector<obstacle_data_a> obstacleStatusA, std::vector<obstacle_data_b> obstacleStatusB, std::vector<obstacle_data_c> obstacleStatusC)
+{
+    int vec_size = obstacleStatusA.size();
+    if(vec_size == 0)
+    {
+        return;
+    }
+    std::cout<< "*****************************************************************************************"<<std::endl;
+    for(int i = 0; i < vec_size; i++)
+    {
+
+        std::cout<< "obstacle ID: " << obstacleStatusA[i].obstacle_ID << std::endl;
+        std::cout<< "obstacle_pos_x: " << obstacleStatusA[i].obstacle_pos_x << std::endl;
+        std::cout<< "obstacle_pos_x: " << obstacleStatusA[i].obstacle_pos_y << std::endl;
+        std::cout<< "obstacle_rel_vel_x: " << obstacleStatusA[i].obstacle_rel_vel_x << std::endl;
+        std::cout<< "obstacle_type: " << obstacleStatusA[i].obstacle_type << std::endl;
+        std::cout<< "obstacle_status: " << obstacleStatusA[i].obstacle_status << std::endl;
+        std::cout<< "obstacle_brake_light: " << obstacleStatusA[i].is_obstacle_brake_lights << std::endl;
+        std::cout<< "obstacle_valid: " << obstacleStatusA[i].obstacle_valid << std::endl;
+//        //std::cout<< "obstacle_length: " << obstacleStatusB[i].obstacle_length << std::endl;
+//        std::cout<< "obstacle_width: " << obstacleStatusB[i].obstacle_width << std::endl;
+//        std::cout<< "obstacle_age: " << obstacleStatusB[i].obstacle_age << std::endl;
+//        std::cout<< "obstacle_cipv: " << obstacleStatusB[i].is_cipv_flag << std::endl;
+//        std::cout<< "obstacle_radar_pos_x: " << obstacleStatusB[i].radar_pos_x << std::endl;
+//        std::cout<< "obstacle_radar_vel_x: " << obstacleStatusB[i].radar_vel_x << std::endl;
+//        std::cout<< "obstacle_angle_rate: " << obstacleStatusC[i].obstacle_angle_rate << std::endl;
+//        std::cout<< "obstacle_angle" << obstacleStatusC[i].obstacle_angle << std::endl;
+//        std::cout<< "object_accel_x" << obstacleStatusC[i].object_accel_x << std::endl;
+//        std::cout<< "obstacle_scale_change: " << obstacleStatusC[i].obstacle_scale_change << std::endl;
+//        std::cout<< "is_obstacle_replaced: " << obstacleStatusC[i].is_obstacle_replaced<< std::endl;
+    }
+    std::cout<< "*****************************************************************************************"<<std::endl;
+}
+
+#ifdef USE_MOBILEYE
+void iv::control::CanUtil::receive_mobileye(){
+    while(m_connect)
+    {
+        memset(ServiceCarStatus.obstacleStatusA, 0, sizeof(obstacle_data_a) * 15);
+        memset(ServiceCarStatus.obstacleStatusA, 0, sizeof(obstacle_data_b) * 15);
+        memset(ServiceCarStatus.obstacleStatusA, 0, sizeof(obstacle_data_c) * 15);
+        int obs_a_count = 0, obs_b_count = 0, obs_c_count = 0;
+        int left_lane_a_count = 0, right_lane_a_count = 0, left_lane_b_count = 0, right_lane_b_count = 0;
+        obstacle_data_a a_tmp;
+        obstacle_data_b b_tmp;
+        obstacle_data_c c_tmp;
+        next_lane_a left_tmp_a, right_tmp_a;
+        next_lane_b left_tmp_b, right_tmp_b;
+        VCI_CAN_OBJ receivedata[2500];
+        int res = VCI_Receive(m_devtype, m_devindmob, m_cannum, receivedata, 2500, 10);
+        if (res <= 0)
+        {
+#ifdef linux
+            usleep(1000);
+#endif
+#ifdef WIN32
+            Sleep(1);
+#endif
+            continue;
+        }
+        for (int i = 0; i < res; i++)
+        {
+            switch(receivedata[i].ID)
+            {
+                case 0x700:
+                    impl_0x700(receivedata[i]);
+                    break;
+                case 0x737:
+                    impl_0x737(receivedata[i]);
+                    break;
+                case 0x738:
+                    impl_0x738(receivedata[i]);
+                    break;
+                case 0x739: case 0x73c: case 0x73f: case 0x742: case 0x745: case 0x748: case 0x74b: case 0x74e: case 0x751: case 0x754: case 0x757: case 0x75a: case 0x75d: case 0x760: case 0x763:
+                    a_tmp = impl_0x739(receivedata[i]);
+                    memcpy(&(ServiceCarStatus.obstacleStatusA[obs_a_count]), &a_tmp, sizeof(obstacle_data_a));
+                    obs_a_count++;
+                    break;
+                case 0x73a: case 0x73d: case 0x740: case 0x743: case 0x746: case 0x749: case 0x74c: case 0x74f: case 0x752: case 0x755: case 0x758: case 0x75b: case 0x75e: case 0x761: case 0x764:
+                    b_tmp = impl_0x73a(receivedata[i]);
+                    memcpy(&(ServiceCarStatus.obstacleStatusB[obs_b_count]), &b_tmp, sizeof(obstacle_data_b));
+                    obs_b_count++;
+                    break;
+                case 0x73b: case 0x73e: case 0x741: case 0x744: case 0x747: case 0x74a: case 0x74d: case 0x750: case 0x753: case 0x756: case 0x759: case 0x75c: case 0x75f: case 0x762: case 0x765:
+                    c_tmp = impl_0x73b(receivedata[i]);
+                    memcpy(&(ServiceCarStatus.obstacleStatusC[obs_a_count]), &c_tmp, sizeof(obstacle_data_c));
+                    obs_c_count++;
+                    break;
+                case 0x669:
+                    impl_0x669(receivedata[i]);
+                    break;
+                case 0x766:
+                    impl_0x766(receivedata[i]);
+                    break;
+                case 0x767:
+                    impl_0x767(receivedata[i]);
+                    break;
+                case 0x768:
+                    impl_0x768(receivedata[i]);
+                    break;
+                case 0x769:
+                    impl_0x769(receivedata[i]);
+                    break;
+                case 0x76c: case 0x76e: case 0x771: case 0x773: case 0x775: case 0x777: case 0x779: case 0x77b:
+                    if (receivedata[i].ID == 0x76c || receivedata[i].ID == 0x771 || receivedata[i].ID == 0x775 || receivedata[i].ID == 0x779)
+                    {
+                        left_tmp_a = impl_0x76c(receivedata[i]);
+                        memcpy(&(ServiceCarStatus.nextLaneA_left[left_lane_a_count]), &left_tmp_a, sizeof(next_lane_a));
+                        left_lane_a_count++;
+                    }
+                    else
+                    {
+                        right_tmp_a = impl_0x76c(receivedata[i]);
+                        memcpy(&(ServiceCarStatus.nextLaneA_right[right_lane_a_count]), &right_tmp_a, sizeof(next_lane_a));
+                        right_lane_a_count++;
+                    }
+                    //impl_0x76c(receivedata[i]);
+                    break;
+                case 0x76d: case 0x76f: case 0x772: case 0x774: case 0x776: case 0x778: case 0x77a: case 0x77c:
+                    if (receivedata[i].ID == 0x76d || receivedata[i].ID == 0x772 || receivedata[i].ID == 0x776 || receivedata[i].ID == 0x77a)
+                    {
+                        left_tmp_b = impl_0x76d(receivedata[i]);
+                        memcpy(&(ServiceCarStatus.nextLaneB_left[left_lane_b_count]), &left_tmp_b, sizeof(next_lane_b));
+                        left_lane_b_count++;
+                    }
+                    else
+                    {
+                        right_tmp_b = impl_0x76d(receivedata[i]);
+                        memcpy(&(ServiceCarStatus.nextLaneB_right[right_lane_b_count]), &right_tmp_b, sizeof(next_lane_b));
+                        right_lane_b_count++;
+                    }
+                    break;
+                case 0x76a:
+                    impl_0x76a(receivedata[i]);
+                    break;
+                case 0x76b:
+                    impl_0x76b(receivedata[i]);
+                    break;
+                default:
+                    break;
+            }
+        }
+       // obs_print(ServiceCarStatus.obstacleStatusA, ServiceCarStatus.obstacleStatusB, ServiceCarStatus.obstacleStatusC);
+    }
+}
+#endif
+
+//void iv::control::CanUtil::send() {
+	
+//    VCI_CAN_OBJ senddata;
+
+//	QTime time;
+//    int nTimeLastSend1;
+//	time.start();
+//    nTimeLastSend1 = time.elapsed();
+//    int nSend1Int = 10;  //10ms
+
+//	senddata.SendType = m_sendtype;
+//	senddata.ExternFlag = m_frameflag;
+//    senddata.RemoteFlag = m_frameformat;
+//    ServiceControlStatus.control_cmd_.Head = 0xEB;
+
+//	while (true) {
+//        usleep(1000);
+//		if ((time.elapsed() - nTimeLastSend1) >= nSend1Int)
+//        {
+//			nTimeLastSend1 = time.elapsed();
+//			senddata.ID = ServiceControlStatus.id;
+//            senddata.DataLen = 8;
+//            ServiceControlStatus.control_cmd_.CommunicationCount++;
+//            ServiceControlStatus.control_cmd_.CheckSum = (ServiceControlStatus.control_cmd_.Acceleration_frac + ServiceControlStatus.control_cmd_.Acceleration_int + ServiceControlStatus.control_cmd_.CommunicationCount + ServiceControlStatus.control_cmd_.Control + ServiceControlStatus.control_cmd_.Wheel_Angel[0] + ServiceControlStatus.control_cmd_.Wheel_Angel[1])%256;
+//            memcpy(senddata.Data, &ServiceControlStatus.control_cmd_.Head, 8);
+//            VCI_Transmit(m_devtype, m_devind, m_cannum, &senddata, 1);
+//            ServiceControlStatus.control_cmd_.Control &= 0xCB;
+//        }
+//	}
+//}
+
+
+void iv::control::CanUtil::startsend(bool start_or_stop)
+{
+    if(start_or_stop == true && send_connect == true && is_repeat == false)
+    {
+        is_repeat = true;
+        thread_send = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&iv::control::CanUtil::send, this)));			//启动发送线程
+    }
+    else if(start_or_stop == false && send_connect == true && is_repeat == true)
+    {
+        thread_send->interrupt();
+        thread_send->join();
+        is_repeat = false;
+    }
+}
+
+bool iv::control::CanUtil::did_radar_ok()
+{
+    bool temp = obs_find_flag;
+    obs_find_flag = false;
+    return temp;
+}

+ 138 - 0
src/controller/controller_yuhesen/control/can.h

@@ -0,0 +1,138 @@
+#pragma once
+#ifndef _IV_CONTROL_CAN_
+#define _IV_CONTROL_CAN_
+#include <control/controlcan.h>
+#include <common/boost.h>
+#include <common/car_status.h>
+#include <boost/serialization/singleton.hpp>
+#include <common/obstacle_type.h>
+#include <control/mobileye.h>
+#ifdef WIN32
+#include <control/can_card.h>
+#endif
+
+//#define USE_MOBILEYE
+
+namespace iv {
+    namespace control {
+        class CanUtil : public boost::noncopyable
+        {
+        public:
+            CanUtil();
+            ~CanUtil();
+
+            void openCanCard();
+            void closeCanCard();
+            void receive();
+            void send();
+
+            void initial();
+            void pack_command();
+
+            void receive_radar();	//毫米波雷达接收数据线程执行方法
+
+#ifdef USE_MOBILEYE
+            void receive_mobileye();
+#endif
+
+            /* 获取毫米波雷达传输数据*/
+            void getRadarData(iv::ObsRadar & obs_radar);
+            //zsl 2018.06.19
+            void Ui_GetRadarDate(iv::ObsRadar & obs_radar);
+        //	void Ui_GetRadarDate(iv::ObsRadarPointer & obs_radar);
+
+            bool did_radar_ok();
+            void startsend(bool start_or_stop);
+            void set_trumpet_on();
+            void set_trumpet_off();
+            void set_handbrake_on();
+            void set_handbrake_off();
+
+            void impl_0x700(VCI_CAN_OBJ receivedata);
+            void impl_0x737(VCI_CAN_OBJ receivedata);
+            void impl_0x738(VCI_CAN_OBJ receivedata);
+            obstacle_data_a impl_0x739(VCI_CAN_OBJ receivedata);
+            obstacle_data_b impl_0x73a(VCI_CAN_OBJ receivedata);
+            obstacle_data_c impl_0x73b(VCI_CAN_OBJ receivedata);
+            void impl_0x669(VCI_CAN_OBJ receivedata);
+            void impl_0x766(VCI_CAN_OBJ receivedata);
+            void impl_0x767(VCI_CAN_OBJ receivedata);
+            void impl_0x768(VCI_CAN_OBJ receivedata);
+            void impl_0x769(VCI_CAN_OBJ receivedata);
+            next_lane_a impl_0x76c(VCI_CAN_OBJ receivedata);
+            next_lane_b impl_0x76d(VCI_CAN_OBJ receivedata);
+            void impl_0x76a(VCI_CAN_OBJ receivedata);
+            void impl_0x76b(VCI_CAN_OBJ receivedata);
+
+            void obs_print(std::vector<obstacle_data_a> obstacleStatusA, std::vector<obstacle_data_b> obstacleStatusB, std::vector<obstacle_data_c> obstacleStatusC);
+
+            bool is_stop = false;
+            bool is_trumpet_duang = false;
+            bool remotecontrol_is_stop = false;
+            bool remotecontrol_is_start = false;
+        private:
+            boost::shared_ptr<boost::thread> thread_receive;	//接收控制板数据线程
+            boost::shared_ptr<boost::thread> thread_radar_receive;	//接收毫米波雷达数据线程
+
+            boost::shared_ptr<boost::thread> thread_mobileye_receive;   //mobileye
+
+            boost::shared_ptr<boost::thread> thread_send;		//发送数据线程 每10毫秒发送一次
+            iv::ObsRadar obs_radar1;
+            iv::ObsRadar obs_radar_;		//毫米波雷达障碍物数据
+            iv::ObsRadar obs_radar_ui;		//专门用来给GUI读毫米波雷达的数据
+            bool obs_find_flag = false;		//采集内容标志位,有内容就是true
+
+
+            boost::mutex mutex_;
+#ifdef WIN32
+            HINSTANCE  m_hDLL;//用来保存打开的动态库句柄
+
+
+                        LPVCI_OpenDevice VCI_OpenDevice; //接口函数指针
+                        LPVCI_CloseDevice VCI_CloseDevice;
+                        LPVCI_InitCan VCI_InitCAN;
+                        LPVCI_ReadBoardInfo VCI_ReadBoardInfo;
+                        LPVCI_ReadErrInfo VCI_ReadErrInfo;
+                        LPVCI_ReadCanStatus VCI_ReadCanStatus;
+                        LPVCI_GetReference VCI_GetReference;
+                        LPVCI_SetReference VCI_SetReference;
+                        LPVCI_GetReceiveNum VCI_GetReceiveNum;
+                        LPVCI_ClearBuffer VCI_ClearBuffer;
+                        LPVCI_StartCAN VCI_StartCAN;
+                        LPVCI_ResetCAN VCI_ResetCAN;
+                        LPVCI_Transmit VCI_Transmit;
+                        LPVCI_Receive VCI_Receive;
+                        LPVCI_GetReference2 VCI_GetReference2;
+                        LPVCI_SetReference2 VCI_SetReference2;
+                        LPVCI_ResumeConfig VCI_ResumeConfig;
+                        LPVCI_ConnectDevice VCI_ConnectDevice;
+                        LPVCI_UsbDeviceReset VCI_UsbDeviceReset;
+                        LPVCI_FindUsbDevice VCI_FindUsbDevice;
+#endif
+
+
+
+            DWORD m_devtype = 4;//USBCAN2类型号
+            DWORD m_devind = 0;		//can卡设备号  第一个插入的是0  第二个是1
+            DWORD m_cannum = 0;		//can通道号
+            DWORD m_cannum_radar = 1;	//毫米波雷达can通道号
+
+#ifdef USE_MOBILEYE
+             DWORD m_devindmob = 1;
+#endif
+
+            BYTE m_sendtype = 0;
+            BYTE m_frameflag = 0;
+            BYTE m_frameformat = 0;
+
+            bool send_connect = false;
+            bool is_repeat = false;
+            int m_connect = 0;
+
+        };
+        typedef boost::serialization::singleton<iv::control::CanUtil> CanUtilSingleton;
+    }
+}
+
+#define ServiceCanUtil iv::control::CanUtilSingleton::get_mutable_instance()
+#endif // !_IV_CONTROL_CAN_

+ 229 - 0
src/controller/controller_yuhesen/control/can_card.h

@@ -0,0 +1,229 @@
+#pragma once
+#ifndef CONTROLCAN_H
+#define CONTROLCAN_H
+
+////文件版本:v2.00 20150920
+//#include <cvidef.h>	//使用CVI平台开发,请使用该语句。
+
+#include <Windows.h>
+
+//接口卡类型定义
+
+#define VCI_USBCAN1		3
+#define VCI_USBCAN2		4
+#define VCI_USBCAN2A		4
+
+#define VCI_USBCAN_E_U 		20
+#define VCI_USBCAN_2E_U 	21
+
+#define VCI_ACCCODE_DEFAULT		0x00000000
+#define VCI_ACCMASK_DEFAULT		0xFFFFFFFF
+#define VCI_TIMER0_DEFAULT		0x00
+#define VCI_TIMER1_DEFAULT		0x1C
+#define VCI_FILTER_DEFAULT		1
+#define VCI_MODE_DEFAULT		0
+
+//函数调用返回状态值
+#define	STATUS_OK					1
+#define STATUS_ERR					0
+
+/*------------------------------------------------兼容ZLG的函数及数据类型------------------------------------------------*/
+
+typedef  struct  _VCI_BOARD_INFO {//1.ZLGCAN系列接口卡信息的数据类型。
+    USHORT	hw_Version;
+    USHORT	fw_Version;
+    USHORT	dr_Version;
+    USHORT	in_Version;
+    USHORT	irq_Num;
+    BYTE	can_Num;
+    CHAR	str_Serial_Num[20];
+    CHAR	str_hw_Type[40];
+    USHORT	Reserved[4];
+} VCI_BOARD_INFO, *PVCI_BOARD_INFO;
+
+
+typedef  struct  _VCI_BOARD_INFO1 {//USB-CAN总线适配器板卡信息的数据类型,该类型在VCI_FindUsbDevice函数中引用。
+    USHORT	hw_Version;
+    USHORT	fw_Version;
+    USHORT	dr_Version;
+    USHORT	in_Version;
+    USHORT	irq_Num;
+    BYTE	can_Num;
+    BYTE    reserved;
+    CHAR	str_Serial_Num[8];
+    CHAR	str_hw_Type[16];
+    CHAR	str_USB_Serial[4][4];
+} VCI_BOARD_INFO1, *PVCI_BOARD_INFO1;
+
+
+typedef  struct  _VCI_CAN_OBJ {//2.定义CAN信息帧的数据类型。
+    UINT	ID;
+    UINT	TimeStamp;
+    BYTE	TimeFlag;
+    BYTE	SendType;
+    BYTE	RemoteFlag;//是否是远程帧
+    BYTE	ExternFlag;//是否是扩展帧
+    BYTE	DataLen;
+    BYTE	Data[8];
+    BYTE	Reserved[3];
+}VCI_CAN_OBJ, *PVCI_CAN_OBJ;
+
+
+typedef struct _VCI_INIT_CONFIG {//3.定义初始化CAN的数据类型
+    DWORD	AccCode;
+    DWORD	AccMask;
+    DWORD	Reserved;
+    UCHAR	Filter;
+    UCHAR	Timing0;
+    UCHAR	Timing1;
+    UCHAR	Mode;
+}VCI_INIT_CONFIG, *PVCI_INIT_CONFIG;
+
+
+typedef struct _VCI_FILTER_RECORD {///////// new add struct for filter /////////
+    DWORD ExtFrame;	//是否为扩展帧
+    DWORD Start;
+    DWORD End;
+}VCI_FILTER_RECORD, *PVCI_FILTER_RECORD;
+
+#define EXTERNC		extern "C"
+
+EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType, DWORD DeviceInd, DWORD Reserved);
+EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType, DWORD DeviceInd);
+EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);
+
+EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType, DWORD DeviceInd, PVCI_BOARD_INFO pInfo);
+
+EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, DWORD RefType, PVOID pData);
+
+EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);
+EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);
+
+EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);
+EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd);
+
+EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pSend, ULONG Len);
+EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pReceive, ULONG Len, INT WaitTime);
+
+
+/*------------------------------------------------其他补充函数及数据结构描述------------------------------------------------*/
+
+
+
+typedef  struct  _VCI_BOARD_INFO2 {//USB-CAN总线适配器板卡信息的数据类型2,该类型为VCI_FindUsbDevice函数的返回参数。为扩展更多的设备
+    USHORT	hw_Version;
+    USHORT	fw_Version;
+    USHORT	dr_Version;
+    USHORT	in_Version;
+    USHORT	irq_Num;
+    BYTE	can_Num;
+    BYTE	Reserved;
+    CHAR	str_Serial_Num[8];
+    CHAR	str_hw_Type[16];
+    CHAR	str_Usb_Serial[10][4];
+} VCI_BOARD_INFO2, *PVCI_BOARD_INFO2;
+
+
+#define EXTERNC		extern "C"
+
+EXTERNC DWORD __stdcall VCI_GetReference2(DWORD DevType, DWORD DevIndex, DWORD CANIndex, DWORD Reserved, BYTE *pData);
+EXTERNC DWORD __stdcall VCI_SetReference2(DWORD DevType, DWORD DevIndex, DWORD CANIndex, DWORD RefType, BYTE *pData);
+
+
+EXTERNC DWORD __stdcall VCI_ConnectDevice(DWORD DevType, DWORD DevIndex);
+EXTERNC DWORD __stdcall VCI_UsbDeviceReset(DWORD DevType, DWORD DevIndex, DWORD Reserved);
+EXTERNC DWORD __stdcall VCI_FindUsbDevice(PVCI_BOARD_INFO1 pInfo);
+EXTERNC DWORD __stdcall VCI_FindUsbDevice2(PVCI_BOARD_INFO2 pInfo);
+
+
+
+typedef struct _VCI_CAN_STATUS {//定义CAN控制器状态的数据类型。
+    UCHAR	ErrInterrupt;
+    UCHAR	regMode;
+    UCHAR	regStatus;
+    UCHAR	regALCapture;
+    UCHAR	regECCapture;
+    UCHAR	regEWLimit;
+    UCHAR	regRECounter;
+    UCHAR	regTECounter;
+    DWORD	Reserved;
+}VCI_CAN_STATUS, *PVCI_CAN_STATUS;
+
+
+typedef struct _ERR_INFO {//定义错误信息的数据类型。
+    UINT	ErrCode;
+    BYTE	Passive_ErrData[3];
+    BYTE	ArLost_ErrData;
+} VCI_ERR_INFO, *PVCI_ERR_INFO;
+
+//接下来定义要导入的函数类型
+//根据ControlCAN.h中的函数声明定义函数指针类型
+//////////////////////////////////////////////////////////////////////////
+//兼容ZLG的函数
+typedef DWORD(CALLBACK*  LPVCI_OpenDevice)(DWORD, DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_CloseDevice)(DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_InitCan)(DWORD, DWORD, DWORD, PVCI_INIT_CONFIG);
+
+typedef DWORD(CALLBACK*  LPVCI_ReadBoardInfo)(DWORD, DWORD, PVCI_BOARD_INFO);
+typedef DWORD(CALLBACK*  LPVCI_ReadErrInfo)(DWORD, DWORD, DWORD, PVCI_ERR_INFO);
+typedef DWORD(CALLBACK*  LPVCI_ReadCanStatus)(DWORD, DWORD, DWORD, PVCI_CAN_STATUS);
+
+typedef DWORD(CALLBACK*  LPVCI_GetReference)(DWORD, DWORD, DWORD, DWORD, PVOID);
+typedef DWORD(CALLBACK*  LPVCI_SetReference)(DWORD, DWORD, DWORD, DWORD, PVOID);
+
+typedef ULONG(CALLBACK*  LPVCI_GetReceiveNum)(DWORD, DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_ClearBuffer)(DWORD, DWORD, DWORD);
+
+typedef DWORD(CALLBACK*  LPVCI_StartCAN)(DWORD, DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_ResetCAN)(DWORD, DWORD, DWORD);
+
+typedef ULONG(CALLBACK*  LPVCI_Transmit)(DWORD, DWORD, DWORD, PVCI_CAN_OBJ, ULONG);
+typedef ULONG(CALLBACK*  LPVCI_Receive)(DWORD, DWORD, DWORD, PVCI_CAN_OBJ, ULONG, INT);
+
+
+
+/*-------------------------其他函数及数据类型描述-----------------------------*/
+//首先定义需要用到的数据结构
+
+
+typedef struct _REF_NORMAL {//定义常规参数类型
+    BYTE Mode;		 //工作模式
+    BYTE Filter;		 //滤波方式
+    DWORD AccCode;		//接收滤波验收码
+    DWORD AccMask;		//接收滤波屏蔽码
+    BYTE kBaudRate;		//波特率索引号,0-SelfDefine,1-5Kbps(未用),2-18依次为:10kbps,20kbps,40kbps,50kbps,80kbps,100kbps,125kbps,200kbps,250kbps,400kbps,500kbps,666kbps,800kbps,1000kbps,33.33kbps,66.66kbps,83.33kbps
+    BYTE Timing0;
+    BYTE Timing1;
+    BYTE CANRX_EN;		//保留,未用
+    BYTE UARTBAUD;		//保留,未用
+}VCI_REF_NORMAL, *PVCI_REF_NORMAL;
+
+
+typedef struct _BAUD_TYPE {//定义波特率设置参数类型
+    DWORD Baud;		//存储波特率实际值
+    BYTE SJW;		//同步跳转宽度,取值1-4
+    BYTE BRP;		//预分频值,取值1-64
+    BYTE SAM;		//采样点,取值0=采样一次,1=采样三次
+    BYTE PHSEG2_SEL;	//相位缓冲段2选择位,取值0=由相位缓冲段1时间决定,1=可编程
+    BYTE PRSEG;		//传播时间段,取值1-8
+    BYTE PHSEG1;		//相位缓冲段1,取值1-8
+    BYTE PHSEG2;		//相位缓冲段2,取值1-8
+}VCI_BAUD_TYPE, *PVCI_BAUD_TYPE;
+
+
+typedef struct _REF_STRUCT {//定义Reference参数类型
+    VCI_REF_NORMAL RefNormal;
+    BYTE Reserved;
+    VCI_BAUD_TYPE BaudType;
+}VCI_REF_STRUCT, *PVCI_REF_STRUCT;
+
+//其他函数
+typedef DWORD(CALLBACK*  LPVCI_GetReference2)(DWORD, DWORD, DWORD, DWORD, PVCI_REF_STRUCT);
+typedef DWORD(CALLBACK*  LPVCI_SetReference2)(DWORD, DWORD, DWORD, DWORD, PVOID);
+typedef DWORD(CALLBACK*  LPVCI_ResumeConfig)(DWORD, DWORD, DWORD);
+
+typedef DWORD(CALLBACK*  LPVCI_ConnectDevice)(DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_UsbDeviceReset)(DWORD, DWORD, DWORD);
+typedef DWORD(CALLBACK*  LPVCI_FindUsbDevice)(PVCI_BOARD_INFO1);
+//////////////////////////////////////////////////////////////////////////
+#endif

+ 10 - 0
src/controller/controller_yuhesen/control/control.pri

@@ -0,0 +1,10 @@
+HEADERS += \
+    $$PWD/controller.h \
+    $$PWD/control_status.h \
+    $$PWD/yuhesen.h
+
+SOURCES += \
+    $$PWD/controller.cpp \
+    $$PWD/control_status.cpp
+
+DISTFILES +=

+ 56 - 0
src/controller/controller_yuhesen/control/control_status.cpp

@@ -0,0 +1,56 @@
+#include <control/control_status.h>
+
+void iv::control::ControlStatus::set_head()
+{
+    command.bit.head = 0xEB;
+}
+
+void iv::control::ControlStatus::set_wheel_angle(float angle)
+{
+    int ang = (int)(angle * 100);
+    command.bit.ang_H = (ang) >> 8;
+    command.bit.ang_L = (ang) % 256;
+}
+
+void iv::control::ControlStatus::set_brake(bool enable)
+{
+    command.bit.brake=(unsigned)true;
+}
+
+void iv::control::ControlStatus::set_velocity(float vel)
+{
+    int v = (int)(vel * 1000);
+    command.bit.vel_H = v >> 8;
+    command.bit.vel_L = v % 256;
+}
+
+void iv::control::ControlStatus::set_left_light(bool enable)
+{
+    if (enable)
+        command.bit.steer_light |= 1;
+    else
+        command.bit.steer_light &= 2;
+}
+
+void iv::control::ControlStatus::set_right_light(bool enable)
+{
+    if (enable)
+        command.bit.steer_light |= 2;
+    else
+        command.bit.steer_light &= 1;
+}
+
+void iv::control::ControlStatus::set_highbeam(bool enable)
+{
+    command.bit.high_beam = (char)enable;
+}
+
+void iv::control::ControlStatus::set_dangwei(int dangwei)
+{
+    command.bit.DangWei = dangwei;
+}
+
+void iv::control::ControlStatus::set_horn(bool enable)
+{
+    command.bit.horn = (unsigned char)enable;
+}

+ 31 - 0
src/controller/controller_yuhesen/control/control_status.h

@@ -0,0 +1,31 @@
+#pragma once
+//由于控制器指令共享同一个ID 0x20,建立此类维护控制指令的最新状态
+
+#include "boost.h"
+#include <cstdint>
+#include <boost/serialization/singleton.hpp>
+#include <control/yuhesen.h>
+
+namespace iv {
+    namespace control {
+        class ControlStatus : public boost::noncopyable
+        {
+        public:
+            Command command;
+
+            int command_ID = 0x12;
+
+            void set_head();
+            void set_wheel_angle(float angle);
+            void set_brake(bool brake);
+            void set_velocity(float vel);
+            void set_left_light(bool enable);
+            void set_right_light(bool enable);
+            void set_highbeam(bool enable);
+            void set_dangwei(int dangwei);
+            void set_horn(bool enable);
+        };
+        typedef boost::serialization::singleton<iv::control::ControlStatus> ControlStatusSingleton;
+    }
+}
+#define ServiceControlStatus iv::control::ControlStatusSingleton::get_mutable_instance()

+ 145 - 0
src/controller/controller_yuhesen/control/controlcan.h

@@ -0,0 +1,145 @@
+#ifndef CONTROLCAN1_H
+#define CONTROLCAN1_H
+
+
+#ifdef linux
+//接口卡类型定义
+#define VCI_PCI5121		1
+#define VCI_PCI9810		2
+#define VCI_USBCAN1		3
+#define VCI_USBCAN2		4
+#define VCI_PCI9820		5
+#define VCI_CAN232		6
+#define VCI_PCI5110		7
+#define VCI_CANLite		8
+#define VCI_ISA9620		9
+#define VCI_ISA5420		10
+
+//CAN错误码
+#define	ERR_CAN_OVERFLOW			0x0001	//CAN控制器内部FIFO溢出
+#define	ERR_CAN_ERRALARM			0x0002	//CAN控制器错误报警
+#define	ERR_CAN_PASSIVE				0x0004	//CAN控制器消极错误
+#define	ERR_CAN_LOSE				0x0008	//CAN控制器仲裁丢失
+#define	ERR_CAN_BUSERR				0x0010	//CAN控制器总线错误
+
+//通用错误码
+#define	ERR_DEVICEOPENED			0x0100	//设备已经打开
+#define	ERR_DEVICEOPEN				0x0200	//打开设备错误
+#define	ERR_DEVICENOTOPEN			0x0400	//设备没有打开
+#define	ERR_BUFFEROVERFLOW			0x0800	//缓冲区溢出
+#define	ERR_DEVICENOTEXIST			0x1000	//此设备不存在
+#define	ERR_LOADKERNELDLL			0x2000	//装载动态库失败
+#define ERR_CMDFAILED				0x4000	//执行命令失败错误码
+#define	ERR_BUFFERCREATE			0x8000	//内存不足
+
+
+//函数调用返回状态值
+#define	STATUS_OK					1
+#define STATUS_ERR					0
+	
+#define USHORT unsigned short int
+#define BYTE unsigned char
+#define CHAR char
+#define UCHAR unsigned char
+#define UINT unsigned int
+#define DWORD unsigned int
+#define PVOID void*
+#define ULONG unsigned int
+#define INT int
+#define UINT32 UINT
+#define LPVOID void*
+#define BOOL BYTE
+#define TRUE 1
+#define FALSE 0
+
+
+#if 1
+
+typedef  struct  _VCI_BOARD_INFO{//1.ZLGCAN系列接口卡信息的数据类型。
+		USHORT	hw_Version;
+		USHORT	fw_Version;
+		USHORT	dr_Version;
+		USHORT	in_Version;
+		USHORT	irq_Num;
+		BYTE	can_Num;
+		CHAR	str_Serial_Num[20];
+		CHAR	str_hw_Type[40];
+		USHORT	Reserved[4];
+} VCI_BOARD_INFO,*PVCI_BOARD_INFO; 
+
+
+typedef  struct  _VCI_CAN_OBJ{//2.定义CAN信息帧的数据类型。
+	UINT	ID;
+	UINT	TimeStamp;
+	BYTE	TimeFlag;
+	BYTE	SendType;
+	BYTE	RemoteFlag;//是否是远程帧
+	BYTE	ExternFlag;//是否是扩展帧
+	BYTE	DataLen;
+	BYTE	Data[8];
+	BYTE	Reserved[3];
+}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
+
+
+typedef struct _VCI_CAN_STATUS{//3.定义CAN控制器状态的数据类型。
+	UCHAR	ErrInterrupt;
+	UCHAR	regMode;
+	UCHAR	regStatus;
+	UCHAR	regALCapture;
+	UCHAR	regECCapture; 
+	UCHAR	regEWLimit;
+	UCHAR	regRECounter; 
+	UCHAR	regTECounter;
+	DWORD	Reserved;
+}VCI_CAN_STATUS,*PVCI_CAN_STATUS;
+
+
+typedef struct _ERR_INFO{//4.定义错误信息的数据类型。
+		UINT	ErrCode;
+		BYTE	Passive_ErrData[3];
+		BYTE	ArLost_ErrData;
+} VCI_ERR_INFO,*PVCI_ERR_INFO;
+
+
+typedef struct _INIT_CONFIG{//5.定义初始化CAN的数据类型
+	DWORD	AccCode;
+	DWORD	AccMask;
+	DWORD	Reserved;
+	UCHAR	Filter;
+	UCHAR	Timing0;	
+	UCHAR	Timing1;	
+	UCHAR	Mode;
+}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DWORD VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
+DWORD VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);
+DWORD VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);
+
+DWORD VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);
+DWORD VCI_ReadErrInfo(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo);
+DWORD VCI_ReadCANStatus(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus);
+
+DWORD VCI_GetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
+DWORD VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
+
+ULONG VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+DWORD VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+
+DWORD VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+DWORD VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+
+ULONG VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,UINT Len);
+ULONG VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,UINT Len,INT WaitTime);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
+
+#endif

+ 61 - 0
src/controller/controller_yuhesen/control/controller.cpp

@@ -0,0 +1,61 @@
+#include <control/controller.h>
+#include <control/control_status.h>
+
+
+iv::control::Controller::Controller() {
+
+}
+
+iv::control::Controller::~Controller() {
+
+}
+
+void iv::control::Controller::inialize() {
+    ServiceControlStatus.set_head();
+}
+
+
+void iv::control::Controller::control_wheel(float angle) {
+    ServiceControlStatus.set_wheel_angle(angle);
+}
+
+void iv::control::Controller::control_brake(bool enable)
+{
+    ServiceControlStatus.set_brake(enable);
+}
+
+void iv::control::Controller::control_velocity(float vel)
+{
+    ServiceControlStatus.set_velocity(vel);
+}
+
+void iv::control::Controller::control_left_light(bool enable)
+{
+    ServiceControlStatus.set_left_light(enable);
+}
+void iv::control::Controller::control_right_light(bool enable)
+{
+    ServiceControlStatus.set_right_light(enable);
+}
+
+void iv::control::Controller::control_highbeam(bool enable)
+{
+    ServiceControlStatus.set_highbeam(enable);
+}
+
+
+void iv::control::Controller::control_dangwei(int dangwei)
+{
+    ServiceControlStatus.set_dangwei(dangwei);
+}
+
+void iv::control::Controller::control_horn(bool enable)
+{
+    ServiceControlStatus.set_horn(enable);
+}
+
+
+
+
+
+

+ 34 - 0
src/controller/controller_yuhesen/control/controller.h

@@ -0,0 +1,34 @@
+#pragma once
+/*
+*控制器
+*/
+#ifndef _IV_CONTROL_CONTROLLER_
+#define _IV_CONTROL_CONTROLLER_
+
+#include <boost.h>
+#include <control/control_status.h>
+
+namespace iv {
+    namespace control {
+        class Controller
+        {
+        public:
+            Controller();
+            ~Controller();
+            void inialize();// 初始化
+
+            void control_wheel(float angle);		//方向盘控制
+            void control_brake(bool enable);
+            void control_velocity(float vel);
+            void control_left_light(bool enable);
+            void control_right_light(bool enable);
+            void control_highbeam(bool enable);
+            void control_dangwei(int dangwei);
+            void control_horn(bool enable);
+
+        private:
+        };
+    }
+}
+
+#endif // !_IV_CONTROL_CONTROLLER_

+ 33 - 0
src/controller/controller_yuhesen/control/yuhesen.h

@@ -0,0 +1,33 @@
+#pragma once
+
+struct Command_Bit
+{
+    unsigned char head;//0xEB
+
+    unsigned char vel_H;//纵向速度0~65.535
+    unsigned char vel_L;
+
+    unsigned char ang_H;//横向车轮转向-40~4-
+    unsigned char ang_L;
+
+    unsigned char brake;//0/1
+
+
+    unsigned char brake_light: 1;
+    unsigned char Reserved1: 2;
+    unsigned char drive_mode: 1;
+    unsigned char high_beam: 1;
+    unsigned char low_beam: 1;
+    unsigned char steer_light: 2;
+
+    unsigned char Reserved3: 3;
+    unsigned char horn: 1;
+    unsigned char Reserved2: 2;
+    unsigned char DangWei : 2;   //00 P       01 D       10 R      11 N
+};
+
+union Command
+{
+    Command_Bit bit;
+    unsigned char byte[8];
+};

+ 55 - 0
src/controller/controller_yuhesen/controller_yuhesen.pro

@@ -0,0 +1,55 @@
+QT -= gui
+
+QT += network
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += $$PWD/main.cpp \
+    ../../include/msgtype/cameraobject.pb.cc \
+    ../../include/msgtype/cameraobjectarray.pb.cc \
+    ../../include/msgtype/decition.pb.cc \
+    ../../include/msgtype/brainstate.pb.cc \
+    ../../include/msgtype/canmsg.pb.cc \
+    ../../include/msgtype/canraw.pb.cc \
+    ../../include/msgtype/remotectrl.pb.cc
+
+include($$PWD/control/control.pri)
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivboost.pri ) {
+    error( "Couldn't find the ivboost.pri file!" )
+}
+
+#unix:!macx: LIBS += -L/home/yuchuli/qt/lib -lncomgnss -ladcmemshare
+
+unix:!macx: INCLUDEPATH += $$PWD/.
+unix:!macx: DEPENDPATH += $$PWD/.
+
+HEADERS += \
+    ../../include/msgtype/cameraobject.pb.h \
+    ../../include/msgtype/cameraobjectarray.pb.h \
+    ../../include/msgtype/decition.pb.h \
+    ../../include/msgtype/canmsg.pb.h \
+    ../../include/msgtype/canraw.pb.h \
+    ../../include/msgtype/remotectrl.pb.h
+
+

+ 245 - 0
src/controller/controller_yuhesen/main.cpp

@@ -0,0 +1,245 @@
+#include <QCoreApplication>
+
+#include <QTime>
+#include <QMutex>
+
+#include "control/control_status.h"
+#include "control/controller.h"
+
+#include "xmlparam.h"
+#include "modulecomm.h"
+#include "ivversion.h"
+#include "ivbacktrace.h"
+
+#include "canmsg.pb.h"
+#include "decition.pb.h"
+#include <thread>
+
+#include "remotectrl.pb.h"
+
+QMutex gMutex;
+
+void * gpacansend;
+void * gpadecition;
+void * gparemote;
+
+std::string gstrmemdecition;
+std::string gstrmemcansend;
+std::string gstrmemremote; //Remote Ctrl
+
+bool gbSendRun = true;
+
+iv::brain::decition gdecition_def;
+iv::brain::decition gdecition;
+
+bool gbAllowRemote = false;   //Default, Not Allow Remote
+
+bool gbAutoDriving = true; //if true, Auto Driving, false, remote controll
+
+bool gbChassisEPS = true;
+
+iv::brain::decition gdecition_remote;
+
+qint64 gLastRemoteTime = 0;
+
+QTime gTime;
+int gnLastSendTime = 0;
+int gnLastRecvDecTime = -1000;
+int gnDecitionNum = 0; //when is zero,send default;
+const int gnDecitionNumMax = 100;
+int gnIndex = 0;
+
+boost::shared_ptr<iv::control::Controller> gcontroller;	//实际车辆控制器
+
+
+void executeDecition(const iv::brain::decition decition)
+{
+    std::cout<<"acc is "<<decition.torque()<<" ang is "<<decition.wheelangle()<<std::endl;
+    std::cout<<"limitspeed is "<<decition.speed()<<" brake is "<<decition.brake()<<std::endl;
+    std::cout<<"drive_mode is "<<decition.mode()<<" elec_brake is "<<decition.handbrake()<<std::endl;
+    std::cout<<"brake_light is "<<decition.brakelamp()<<" dangwei is "<<decition.gear()<<std::endl;
+    gcontroller->inialize();
+    gcontroller->control_wheel(decition.wheelangle());
+    gcontroller->control_brake(decition.brake());
+    gcontroller->control_velocity(decition.speed());
+    gcontroller->control_left_light(decition.leftlamp());
+    gcontroller->control_right_light(decition.rightlamp());
+    gcontroller->control_highbeam(decition.highbeam());
+    gcontroller->control_dangwei(decition.gear());
+}
+
+
+
+void ListenRemotectrl(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+//    qint64 oldtime;
+    iv::brain::decition xdecition;
+
+    iv::remotectrl xrc;
+
+    if(!xrc.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"ListenRemotectrl parse error."<<std::endl;
+        return;
+    }
+
+    if(xrc.ntype() == iv::remotectrl_CtrlType_AUTO)
+    {
+        gbAutoDriving = true;
+    }
+    else
+    {
+        gbAutoDriving = false;
+        xdecition.set_torque(xrc.acc());
+        xdecition.set_brake(xrc.brake());
+        xdecition.set_wheelangle(xrc.wheel()*5.5f);
+        xdecition.set_speed(5);
+        xdecition.set_gear(1);
+        xdecition.set_handbrake(0);
+        xdecition.set_grade(1);
+        xdecition.set_mode(1);
+        xdecition.set_speak(0);
+        xdecition.set_headlight(false);
+        xdecition.set_engine(0);
+        xdecition.set_taillight(false);
+        gMutex.lock();
+        gdecition_remote.CopyFrom(xdecition);
+        gMutex.unlock();
+        gLastRemoteTime = QDateTime::currentMSecsSinceEpoch();
+
+    }
+
+}
+
+
+void ListenDeciton(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    iv::brain::decition xdecition;
+
+    if(!xdecition.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"ListenDecition parse error."<<std::endl;
+        return;
+    }
+
+    gMutex.lock();
+    gdecition.CopyFrom(xdecition);
+    gMutex.unlock();
+    gnDecitionNum = gnDecitionNumMax;
+}
+
+void ExecSend()
+{
+    iv::can::canmsg xmsg;
+    iv::can::canraw xraw;
+    xraw.set_id(ServiceControlStatus.command_ID);
+    xraw.set_data(ServiceControlStatus.command.byte,8);
+    xraw.set_bext(false);
+    xraw.set_bremote(false);
+    xraw.set_len(8);
+    iv::can::canraw * pxraw = xmsg.add_rawmsg();
+    pxraw->CopyFrom(xraw);
+    xmsg.set_channel(0);
+    xmsg.set_index(gnIndex);
+    gnIndex++;
+    xmsg.set_mstime(QDateTime::currentMSecsSinceEpoch());
+    int ndatasize = xmsg.ByteSize();
+    char * strser = new char[ndatasize];
+    std::shared_ptr<char> pstrser;
+    pstrser.reset(strser);
+    if(xmsg.SerializePartialToArray(strser,ndatasize))
+    {
+        iv::modulecomm::ModuleSendMsg(gpacansend,strser,ndatasize);
+    }
+    else
+    {
+        std::cout<<"MainWindow::onTimer serialize error."<<std::endl;
+    }
+}
+
+
+void sendthread()
+{
+    iv::brain::decition xdecition;
+    while(gbSendRun)
+    {
+        if(gbAutoDriving)
+        {
+            if(gnDecitionNum <= 0)
+            {
+                xdecition.CopyFrom(gdecition_def);
+            }
+            else
+            {
+                gMutex.lock();
+                xdecition.CopyFrom(gdecition);
+                gMutex.unlock();
+                gnDecitionNum--;
+            }
+        }
+        else
+        {
+            if((QDateTime::currentMSecsSinceEpoch() - gLastRemoteTime)> 1000)
+            {
+                xdecition.CopyFrom(gdecition_def);
+            }
+            else
+            {
+                gMutex.lock();
+                xdecition.CopyFrom(gdecition_remote);
+                gMutex.unlock();
+            }
+        }
+        executeDecition(xdecition);
+        ExecSend();
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    RegisterIVBackTrace();
+    showversion("controller_midcar");
+    QCoreApplication a(argc, argv);
+
+     QString strpath = QCoreApplication::applicationDirPath();
+
+    if(argc < 2)
+        strpath = strpath + "/controller_midcar.xml";
+    else
+        strpath = argv[1];
+    std::cout<<strpath.toStdString()<<std::endl;
+
+    gdecition_def.set_brake(0);
+    gdecition_def.set_torque(0);
+    gdecition_def.set_speed(105);
+    gTime.start();
+
+    gcontroller = boost::shared_ptr<iv::control::Controller>(new iv::control::Controller());
+
+    iv::xmlparam::Xmlparam xp(strpath.toStdString());
+
+    gstrmemcansend = xp.GetParam("cansend","cansend0");
+    gstrmemdecition = xp.GetParam("dection","deciton");
+    gstrmemremote =  xp.GetParam("remotectrl","remotectrl");
+
+    std::string strremote = xp.GetParam("allowremote","true");
+    if(strremote == "true")
+    {
+        gbAllowRemote = true;
+    }
+
+
+    gpacansend = iv::modulecomm::RegisterSend(gstrmemcansend.data(),10000,3);
+    gpadecition = iv::modulecomm::RegisterRecv(gstrmemdecition.data(),ListenDeciton);
+
+
+    if(gbAllowRemote)
+    {
+        gparemote = iv::modulecomm::RegisterRecv(gstrmemremote.data(),ListenRemotectrl);
+    }
+
+    std::thread xthread(sendthread);
+
+    return a.exec();
+}

+ 150 - 0
src/decition/decition_brain/decition/adc_adapter/yuhesen_adapter.cpp

@@ -0,0 +1,150 @@
+#include <decition/adc_adapter/yuhesen_adapter.h>
+#include <common/constants.h>
+#include <common/car_status.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+
+using namespace std;
+
+
+iv::decition::YuHeSenAdapter::YuHeSenAdapter(){
+    adapter_id= 7;
+    adapter_name="yuhesen";
+}
+iv::decition::YuHeSenAdapter::~YuHeSenAdapter(){
+
+}
+
+
+
+iv::decition::Decition iv::decition::YuHeSenAdapter::getAdapterDeciton(GPS_INS now_gps_ins, std::vector<Point2D>  trace , float dSpeed, float obsDistance ,
+                                                                        float  obsSpeed,float accAim,float accNow  ,bool changingDangWei,Decition *decition){
+
+
+    float controlSpeed=accAim;
+    float controlBrake=0;
+    float u = 0- accAim;
+    float realSpeed = now_gps_ins.speed;
+    float ttc = 0-(obsDistance/obsSpeed);
+    bool turn_around=false;
+    if(now_gps_ins.roadMode==14||now_gps_ins.roadMode==15||now_gps_ins.roadMode==16||now_gps_ins.roadMode==17){
+        turn_around=true;
+    }
+
+    if(ttc<0){
+        ttc=15;
+    }
+    if (accAim < 0)
+    {
+        //0110
+        if(changingDangWei){
+            controlSpeed=min(-0.5f,controlSpeed);
+        }
+//        else if((obsDistance<0 ||obsDistance>50)&&(abs(dSpeed-realSpeed)<3)){
+//             controlSpeed=max(-0.2f,controlSpeed);
+//        }
+    }
+    else
+    {
+        controlSpeed=min(1.0f,controlSpeed);
+
+    }
+
+    //0227 10m nei xianzhi shache
+    if(obsDistance<10 &&obsDistance>0){
+        controlSpeed=min(controlSpeed,-0.8f);
+    }
+
+
+    if(DecideGps00::minDecelerate<0){
+        controlSpeed = min(DecideGps00::minDecelerate, controlSpeed);
+    }
+    controlSpeed = limitSpeed(realSpeed, controlBrake, dSpeed, controlSpeed);
+
+    (*decition)->accelerator=controlSpeed;
+
+    if((*decition)->leftlamp){
+        (*decition)->directLight=1;
+    }else if((*decition)->rightlamp){
+         (*decition)->directLight=2;
+    }else{
+        (*decition)->directLight=0;
+    }
+
+
+    (*decition)->wheel_angle+=ServiceCarStatus.mfEPSOff;
+
+    (*decition)->wheel_angle=max((float)-500.0,(*decition)->wheel_angle);
+     (*decition)->wheel_angle=min((float)500.0,(*decition)->wheel_angle);
+
+    if((*decition)->accelerator>=0){
+        (*decition)->torque= (*decition)->accelerator;
+        (*decition)->brake=0;
+    }else{
+        (*decition)->torque=0;
+        (*decition)->brake=0-(*decition)->accelerator;
+    }
+
+
+
+
+std::cout<<"==========================================="<<std::endl;
+     std::cout<<"dSpeed:"<<dSpeed<<"   realSpeed:"<<realSpeed<<"   acc:"<<accAim
+    <<std::endl;
+std::cout<<"========================================="<<std::endl;
+
+    return *decition;
+}
+
+
+
+float iv::decition::VV7Adapter::limitBrake(float realSpeed, float controlBrake,float dSpeed,float obsDistance , float ttc){
+
+    //刹车限制
+
+    //刹车限制
+
+    float vs =realSpeed*3.6;
+    int BrakeIntMax = 10;
+    if (vs < 10.0 / 3.6) BrakeIntMax = 4;
+    else if (vs < 20.0 / 3.6) BrakeIntMax = 6;
+
+    //`
+    if(ttc>10){
+        BrakeIntMax = 2;
+    }else if(ttc>6){
+        BrakeIntMax = 3;
+    }else if(ttc>3){
+        BrakeIntMax = 4;
+    }else if(ttc>1.6){
+        BrakeIntMax = 5;
+    }else if(ttc>0.8){
+        BrakeIntMax = 8;
+    }else{
+        BrakeIntMax = 10;
+    }
+    if(obsDistance>0 && obsDistance<10){
+        BrakeIntMax=max(BrakeIntMax,3);
+    }
+
+    if (controlBrake > BrakeIntMax) controlBrake = BrakeIntMax;
+
+
+
+
+    controlBrake=min(10.0f,controlBrake);
+    controlBrake=max(0.0f,controlBrake);
+    return controlBrake;
+
+}
+
+float iv::decition::VV7Adapter::limitSpeed(float realSpeed, float controlBrake,float dSpeed,float controlSpeed ){
+
+    controlSpeed=min((float)5.0,controlSpeed);
+    controlSpeed=max((float)-7.0,controlSpeed);
+    return controlSpeed;
+}
+
+

+ 46 - 0
src/decition/decition_brain/decition/adc_adapter/yuhesen_adapter.h

@@ -0,0 +1,46 @@
+#ifndef VV7_ADAPTER_H
+#define VV7_ADAPTER_H
+
+
+
+#include <common/gps_type.h>
+#include <decition/decition_type.h>
+#include <common/obstacle_type.h>
+#include<vector>
+#include <decition/adc_tools/gnss_coordinate_convert.h>
+#include <decition/adc_adapter/base_adapter.h>
+#include <decition/adc_tools/transfer.h>
+#include<decition/decide_gps_00.h>
+
+
+namespace iv {
+     namespace decition {
+         class VV7Adapter: public BaseAdapter {
+                    public:
+
+                        float lastTorque;
+                        float lastBrake;
+                        int lastDangWei=0;
+                        int seizingCount=0;
+
+                        VV7Adapter();
+                        ~VV7Adapter();
+
+                        iv::decition::Decition getAdapterDeciton(GPS_INS now_gps_ins, std::vector<Point2D>  trace , float dSpeed, float obsDistacne ,
+                                                                                 float  obsSpeed,float acc,float accNow  ,bool changingDangWei,Decition *decition);
+
+                        float limitBrake(float realSpeed, float controlBrake,float dSpeed,float obsDistance , float ttc);
+                        float limitSpeed(float realSpeed, float controlBrake,float dSpeed,float controlSpeed );
+
+                    private:
+
+            };
+
+    }
+}
+
+
+
+
+
+#endif // VV7_ADAPTER_H