基于RT-Thread的RoboMaster電控框架設(shè)計(jì)_第1頁(yè)
基于RT-Thread的RoboMaster電控框架設(shè)計(jì)_第2頁(yè)
基于RT-Thread的RoboMaster電控框架設(shè)計(jì)_第3頁(yè)
基于RT-Thread的RoboMaster電控框架設(shè)計(jì)_第4頁(yè)
基于RT-Thread的RoboMaster電控框架設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩7頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第第頁(yè)基于RT-Thread的RoboMaster電控框架設(shè)計(jì)

由于(RT-Thread)穩(wěn)定高效的內(nèi)核,豐富的文檔(教程),積極活躍的社區(qū)氛圍,以及設(shè)備驅(qū)動(dòng)框架、Kconfig、Scons、日志系統(tǒng)、海量的軟件包……很難不選擇RT-Thread進(jìn)行項(xiàng)目開(kāi)發(fā)。但也正是因?yàn)檫@些優(yōu)點(diǎn)的覆蓋面較廣,很多初學(xué)者會(huì)覺(jué)得無(wú)從下手,但只要步入RT-Thread的大門(mén),你就發(fā)現(xiàn)她的美好。這系列文檔將作為本人基于RT-Thread開(kāi)發(fā)(RoboMaster)電控框架的記錄與分享,希望能幫助到更多初識(shí)RT-Thread的小伙伴,也歡迎大家交流分享,指正不足,共同進(jìn)步。

背景

Robomaster(機(jī)器人)比賽包含多個(gè)兵種,為了提高研發(fā)效率,模塊化尤為重要,使用RT-Thread有助于面對(duì)對(duì)象思想開(kāi)發(fā);通過(guò)配備的Kconfig,Scons等工具可以實(shí)現(xiàn)工程的靈活配置;軟件(定時(shí)器)可用作各(電機(jī))等模塊監(jiān)控,RingBuffer可以實(shí)現(xiàn)(傳感器)信息的高效處理…….

使用的開(kāi)發(fā)板為(大疆)的RoboMaster-C型開(kāi)發(fā)板,基礎(chǔ)工程為rt-thread>bsp>(stm32)f407-robomaster-c

電機(jī)模塊開(kāi)發(fā)

使用電機(jī)和電調(diào)均為大疆官方出品,如2023,3508,6020等,采用(CAN)通訊方式。

構(gòu)建對(duì)象

首先我們根據(jù)使用的電機(jī)特性,構(gòu)建一個(gè)通用的電機(jī)對(duì)象

/**

@briefDJI(intel)ligentmotortypedef

/

typedefstructdji_motor_object

{

rt_device_tcan_dev;//電機(jī)CAN實(shí)例

dji_motor_measure_tmeasure;//電機(jī)測(cè)量值

uint32_ttx_id;//發(fā)送id(主發(fā))

uint32_trx_id;//接收id(主收)

/分組發(fā)送設(shè)置/

uint8_tsend_group;//同一幀報(bào)文分組

uint8_tmessage_num;//一幀報(bào)文中位置

motor_type_emotor_type;//電機(jī)類型

mot(or)_working_type_estop_flag;//啟停標(biāo)志

/監(jiān)控線程相關(guān)/

rt_(ti)mer_ttimer;//電機(jī)監(jiān)控定時(shí)器

/(電機(jī)控制)相關(guān)*/

void*controller;//電機(jī)控制器

int16_t(*control)(dji_motor_measure_tmeasure);//控制電機(jī)的(接口)用戶可以自定義,返回值為16位的電壓或(電流)值

}dji_motor_object_t;

因?yàn)檫@些電機(jī)我們均使用CAN方式進(jìn)行驅(qū)動(dòng),是CAN設(shè)備的延申,于是將rt_device_tcan_dev父類結(jié)構(gòu)體對(duì)象內(nèi)嵌。

dji_motor_measure_t結(jié)構(gòu)體中為,電機(jī)控制時(shí)需要用到的一些反饋值,包括電調(diào)直接反饋的數(shù)據(jù)以及進(jìn)一步解算的得出的:

/**

@briefDJImotorfeedb(ac)k

/

typedefstruct

{

/以下是處理得出的數(shù)據(jù)/

floatangle_single_round;//單圈角度

floatspeed_aps;//角速度,單位為:度/秒

floattotal_angle;//總角度,注意方向

int32_ttotal_round;//總?cè)?shù),注意方向

floattarget;//目標(biāo)值(輸出軸扭矩矩/速度/角度(單位度))

/以下是電調(diào)直接回傳的數(shù)據(jù)*/

uint16_tecd;//0-8191

uint16_tlast_ecd;//上一次讀取的(編碼器)值

int16_tspeed_rpm;//電機(jī)的轉(zhuǎn)速值

int16_treal_current;//實(shí)際轉(zhuǎn)矩電流

uint8_t(te)mperature;//Celsius

}dji_motor_measure_t;

注冊(cè)實(shí)例

通過(guò)dji_motor_object_t*dji_motor_register(motor_config_t*config,void*controller)注冊(cè)對(duì)應(yīng)的電機(jī)實(shí)例,用戶通過(guò)motor_config_t*config對(duì)實(shí)例進(jìn)行靈活配置:

/**

@brief電機(jī)初始化,返回一個(gè)電機(jī)實(shí)例

@pa(ram)config電機(jī)配置

@returndji_motor_object_t*電機(jī)實(shí)例指針

*/

dji_motor_object_t*dji_motor_register(motor_config_t*config,void*controller)

{

dji_motor_object_t*object=(dji_motor_object_t)rt_malloc(sizeof(dji_motor_object_t));

rt_(mems)et(object,0,sizeof(dji_motor_object_t));

//對(duì)接用戶配置的motor_config

object->motor_type=config->motor_type;//6020or2023or3508

object->rx_id=config->rx_id;//電機(jī)接收?qǐng)?bào)文的ID

object->control=controller;//電機(jī)控制器

/查找CAN設(shè)備/

object->can_dev=rt_device_find(config->can_name);

//電機(jī)分組,因?yàn)橹炼?個(gè)電機(jī)可以共用一幀CAN控制報(bào)文

motor_send_grou(pi)ng(object,config);

//電機(jī)離線檢測(cè)定時(shí)器相關(guān)

object->timer=rt_timer_create("motor1",

motor_lost_callback,

object,20,

RT_TIMER_FLAG_PERIODIC);

rt_timer_start(object->timer);

dji_motor_enable(object);

dji_motor_obj[idx++]=object;

returnobject;

}

/電機(jī)配置結(jié)構(gòu)體*/

typedefstruct

{

motor_type_emotor_type;

constchar*can_name;

uint32_ttx_id;//發(fā)送id(主發(fā))

uint32_trx_id;//接收id(主收)

void*controller;//電機(jī)控制器

}motor_config_t;

motor_config_t結(jié)構(gòu)體中的void*controller為電機(jī)所使用到的(控制器)集合,是一個(gè)控制器類型為其成員的結(jié)構(gòu)體變量,如下:

stat(ic)structchassis_controller_t{

pid_object_t*speed_pid;

}chassis_controller;

staticstructgimbal_controller_t{

pid_object_t*speed_pid;

pid_object_t*angle_pid;

}gimbal_controlelr;

調(diào)用dji_motor_object_t*dji_motor_register時(shí)傳入的void*controller為電機(jī)對(duì)應(yīng)的控制器具體實(shí)現(xiàn),如進(jìn)行pid計(jì)算,濾波等,會(huì)賦值給電機(jī)對(duì)象對(duì)應(yīng)的函數(shù)指針,在進(jìn)行電機(jī)控制計(jì)算時(shí)被執(zhí)行,如下:

rt_int16_tchassis_control(dji_motor_measure_tmeasure){

staticrt_int16_tset=0;

set=pid_calculate(chassis_controller.speed_pid,measure.speed_rpm,1000);

returnset;

}

數(shù)據(jù)處理

電機(jī)對(duì)象離不開(kāi)對(duì)數(shù)據(jù)穩(wěn)定快速的收發(fā)和解析計(jì)算,接下來(lái)展開(kāi)討論使用RT-Thread的CAN設(shè)備驅(qū)動(dòng)收發(fā)數(shù)據(jù)的思路。

首先是數(shù)據(jù)的接收,stm32f4擁有2個(gè)CAN外設(shè),所有電機(jī)和使用CAN總線的設(shè)備都掛載在這兩條總線上,但RT-Thread的每個(gè)CAN總線只能通過(guò)rt_device_set_rx_indicate(can_dev,can_rx_call);注冊(cè)一個(gè)對(duì)應(yīng)的接收回調(diào)函數(shù)。但不同類型電機(jī),不同CAN設(shè)備的數(shù)據(jù)解析處理都是不一樣的,我這里的解決思路是:首先創(chuàng)建了一個(gè)usr_callback文件,用于統(tǒng)一管理CAN、串口等設(shè)備可能用到的用戶接收對(duì)調(diào)函數(shù);將一個(gè)大的設(shè)備類型回調(diào)函數(shù)注冊(cè)到對(duì)應(yīng)CAN設(shè)備,其中再細(xì)分各掛載設(shè)備的數(shù)據(jù)解析,實(shí)現(xiàn)如下:

#ifdefBSP_USING_CAN

rt_err_tcan_rx_call(rt_device_tdev,rt_size_tsize)

{

structrt_can_msgrxmsg={0};

uint8_trxbuff=rxmsg.data;

/從CAN讀取一幀數(shù)據(jù)/

rt_device_re(ad)(dev,0,

/CAN接收到數(shù)據(jù)后產(chǎn)生中斷,調(diào)用此回調(diào)函數(shù),然后發(fā)送接收(信號(hào))量/

#ifdefBSP_USING_DJI_MOTOR

dji_motot_rx_callback(rxmsg.id,rxbuff);

#endif/BSP_USING_DJI_MOTOR/

returnRT_EOK;

}

#endif/BSP_USING_CAN*/

但是這其中也有一點(diǎn)問(wèn)題,rt_err_tcan_rx_call(rt_device_tdev,rt_size_tsize)傳入的參數(shù)無(wú)法判斷具體的CAN設(shè)備來(lái)源,因此所有使用到的CAN外設(shè)數(shù)據(jù)處理函數(shù)都會(huì)被調(diào)用,但目前問(wèn)題不大,因?yàn)橥粭l總線上不會(huì)掛載相同ID的設(shè)備,這也是一開(kāi)始就應(yīng)該避免的錯(cuò)誤。

接下來(lái)是CAN報(bào)文的發(fā)送,調(diào)用rt_device_write發(fā)送填充好的CAN報(bào)文幀即可。

離線檢測(cè)

這里使用RT-Thread的軟件定時(shí)器對(duì)電機(jī)進(jìn)行離線檢測(cè),當(dāng)超過(guò)定時(shí)間沒(méi)有接收到對(duì)應(yīng)電機(jī)反饋報(bào)文,則進(jìn)入超時(shí)回調(diào),并輸出警告日志:

/**

@brief電機(jī)定時(shí)器超時(shí)回調(diào)函數(shù)

@parammotor_ptr

*/

staticvoidmotor_lost_callback(void*motor_ptr)

{

dji_motor_object_t*motor=(dji_motor_object_t*)motor_ptr;

//dji_motor_stop(motor);

LOG_W("[dji_motor]Motorlost,canbus[%s],id0x[%x]",motor->can_dev->,motor->rx_id);

}

使用實(shí)例

封裝完成的電機(jī)模塊使用示例如下:

staticstructchassis_controller_t{

pid_object_t*speed_pid;

}chassis_controller;

staticstructgimbal_controller_t{

pid_object_t*speed_pid;

pid_object_t*angle_pid;

}gimbal_controlelr;

staticdji_motor_object_t*chassis_motor;

staticdji_motor_object_t*gimbal_motor;

rt_int16_tchassis_control(dji_motor_measure_tmeasure){

staticrt_int16_tset=0;

set=pid_calculate(chassis_controller.speed_pid,measure.speed_rpm,1000);

returnset;

}

rt_int16_tgimbal_control(dji_motor_measure_tmeasure){

staticrt_int16_tset=0;

set=pid_calculate(gimbal_controlelr.speed_pid,measure.speed_rpm,0);

returnset;

}

staticvoidexample_init()

{

pid_config_tchassis_speed_config={

.Kp=10,//4.5

.Ki=0,//0

.Kd=0,//0

.IntegralLimit=3000,

.Improve=PID_Trapezoid_Intergral|PID_Integral_Limit|PID_Derivative_On_Measurement,

.MaxOut=12000,

};

pid_config_tgimbal_speed_config={

.Kp=50,//50

.Ki=200,//200

.Kd=0,

.Improve=PID_Trapezoid_Intergral|PID_Integral_Limit|PID_Derivative_On_Measurement,

.IntegralLimit=3000,

.MaxOut=20000,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論