目前市场上存在CAN控制的小车,如何利用ardupilot来控制这类小车是本专题的重点,ardupilot中支持uavcan,对于普通的can我们又如何去开发呢。那么,开始这个专栏的学习把,答案就在里面。
一,ardupilot中支持的can
目前ardupilot中在4.3之前支持kecan,ToshibaCAN,AP_PiccoloCAN,4.3之后删除了ToshibaCAN。对于普通CAN来说我们需要参照ToshibaCAN来设计,对于其他的CAN来说就不仔细看了。
二,ToshibaCAN讲解以及参照需要修改的地方
首先肯定是建立自己的文件:....CAN,然后建立相应的.h,.cpp文件,将ToshibaCAN的内容复制过来,首先来看一下ToshibaCAN.h文件修改的地方。
1,替换名称,将ToshibaCAN改为自己的CAN名称
2,加入自己的CANID;
static constexpr uint8_t COMMAND_STOP = 0x0;
static constexpr uint8_t COMMAND_LOCK = 0x10;
static constexpr uint8_t COMMAND_REQUEST_DATA = 0x20;
static constexpr uint8_t COMMAND_MOTOR3 = 0x3B;
static constexpr uint8_t COMMAND_MOTOR2 = 0x3D;
static constexpr uint8_t COMMAND_MOTOR1 = 0x3F;
注意自己的CANid,CAN相关知识自己去了解,注意对应的数据格式例如有一条报文为0x12EFE1E0,那设置如下:
static constexpr uint32_t xxxxxx = 0x12EFE1E0;
把不需要的ID删除。
3,建立自己的数据结构体;
union motor_lock_cmd_t {
struct PACKED {
uint8_t motor2:4;
uint8_t motor1:4;
uint8_t motor4:4;
uint8_t motor3:4;
uint8_t motor6:4;
uint8_t motor5:4;
uint8_t motor8:4;
uint8_t motor7:4;
uint8_t motor10:4;
uint8_t motor9:4;
uint8_t motor12:4;
uint8_t motor11:4;
};
uint8_t data[6];
};
如上图所时这是存诸报文数据的,共64位,motor2:4,4代表一个功能数据所占的位数,例如控制速度占4位,那么这个位代表的是速度;
3,定义报文数据封装报;
AP_HAL::CANFrame mot_rot_frame1;
AP_HAL::CANFrame mot_rot_frame2;
AP_HAL::CANFrame mot_rot_frame3;
此处的定义是为了发送CAN报文封装数据用。
ToshibaCAN.cpp文件修改的地方
1,添加定义和存入数据;
数据重定义
motor_rotation_cmd_t mot_rot_cmd2;
motor_rotation_cmd_t mot_rot_cmd3;
将自己的数据定义的功能存入,根据自己的需求修改
unlock_cmd.motor1 = (_scaled_output[0] == 0) ? 2 : 1;
unlock_cmd.motor2 = (_scaled_output[1] == 0) ? 2 : 1;
unlock_cmd.motor3 = (_scaled_output[2] == 0) ? 2 : 1;
unlock_cmd.motor4 = (_scaled_output[3] == 0) ? 2 : 1;
unlock_cmd.motor5 = (_scaled_output[4] == 0) ? 2 : 1;
unlock_cmd.motor6 = (_scaled_output[5] == 0) ? 2 : 1;
unlock_cmd.motor7 = (_scaled_output[6] == 0) ? 2 : 1;
2,封装数据,注意CAN的id的格式,对应修改
mot_rot_frame1 = {((uint8_t)COMMAND_MOTOR1 & AP_HAL::CANFrame::MaskStdID), driving_sent_cmd.data, sizeof(driving_sent_cmd.data)};
3. 发送CAN报文
if (send_stage == 1) {
timeout = AP_HAL::native_micros64() + timeout_us;
if (!write_frame(unlock_frame, timeout)) {
continue;
}
send_stage++;
}
基本到这里基本修改完成,根据模板修改成自己的CAN协议,根据自己的需求把不需要的删除,这样就把协议添加进去了。不过目前来说编译是不通过的。需要在其他的函数里添加一些设置。这下次再讲。没有ToshibaCAN的版本也是可以这样写的。