寫在前面
首先我對未及時分享自己的配置及源碼向各位網友道歉。本文是對博文ros_arduino_bridge功能包集的使用的拓展,主要是對如何修改ros arduino bridge功能包集,使其兼容其他硬件做一些簡要的說明。在這裏我以自己的配置爲例爲大家講解,如有疑問可以通過csdn私信我或者通過郵箱聯繫我,我的email:[email protected],歡迎大家爲我糾錯。
硬件說明
如果要直接使用ros arduino bridge功能包集的話比較困難,因爲原作者使用的硬件很多在國內很難買到,因此我們需要修改其中的源碼來適應我們的硬件。下面是我對這些硬件做一些說明。正如我在ros_arduino_bridge功能包集的使用這篇博文中所提到的,如果你有一定的Arduino編程基礎,你就可以隨心所欲的讓該功能包集支持任何你想用的硬件。
電動機
我所用的電動機爲普通的直流減速電動機。對於電動機我們並沒有太高的要求,但是筆者建議最好要選購那些帶編碼器的電動機,如果要自己安裝編碼器的話是比較麻煩的。
NOTE:如果要買“裸奔”的電動機的話,一定要確定所買電動機可以安裝編碼器(電動機尾軸要足夠長)。
電動機驅動板
對於兩輪的輪式機器人可以選用目前市面上比較常見的L298N雙H橋電機驅動板,而四輪的話可以使用L293D電動機驅動板。這裏我們以L298N爲例進行介紹。
編碼器
編碼器要儘量選用精度較高的,這樣有利於精確地控制小車。我們可以選用磁編碼器和光電編碼器,這兩種都是比較常用的,而且也很容易使用。我這裏採用的是AB相增量式磁編碼器,線數爲390。當然,如果你選用其他的編碼器也是沒有問題的,只要你可以單獨地驅動起來獲取數據。對於這種AB相的編碼器是比較容易使用的,基本一個驅動程序就可以驅動大部分的AB相編碼器。
Arduino驅動板
Arduino的種類很多,筆者建議使用Arduino Mega 2560。這款板子的各種管腳都比較多,可以拓展比較多的傳感器。當然如果你使用的傳感器不多,可以使用其他型號的Arduino,例如UNO等。
源碼修改
ros arduino bridge功能包集包括四個主要部分:
- ros_arduino_bridge:包含功能包集的功能包集文件和cmake配置文件CMakeLists.txt
- ros_arduino_firmware:固件程序命令,主要負責驅動硬件
- ros_arduino_msgs:自定義的ROS消息類型及服務
- ros_arduino_python:與ROS base controller(基礎控制器)的功能相同,主要負責與硬件驅動程序的通信,具體可以參考《ROS機器人程序設計》這本書
由於我們需要使該功能包適應我們的硬件,因此我們需要對ros_arduino_firmware(固件程序功能包,主要負責硬件的驅動)功能包的源碼進行修改,修改時爲了保持系統正常調用,必須使驅動程序的接口與原來保持一致。
由於我這裏並未使用伺服機或者超聲波傳感器,因此我這裏只對電動機驅動和編碼器驅動以及主文件ROSArduinoBridge.ino做一些修改。
電動機驅動的修改
打開motor_driver.ino文件,這時你會看到一些#if defined
和#elif
等指令,這裏用到就是C語言中所謂的條件編譯——根據預處理器所執行的測試結果來包含或排除程序的片段,即編譯器只對滿足相應條件的代碼進行編譯。其實這些很好理解,它們就類似與我們編程時經常用到的if ... else
語句。
#if defined POLOLU_VNH5019
/* Include the Pololu library */
#include "DualVNH5019MotorShield.h"
/* Create the motor driver object */
DualVNH5019MotorShield drive;
/* Wrap the motor driver initialization */
void initMotorController() {
drive.init();
}
/* Wrap the drive motor set speed function */
void setMotorSpeed(int i, int spd) {
if (i == LEFT) drive.setM1Speed(spd);
else drive.setM2Speed(spd);
}
// A convenience function for setting both motor speeds
void setMotorSpeeds(int leftSpeed, int rightSpeed) {
setMotorSpeed(LEFT, leftSpeed);
setMotorSpeed(RIGHT, rightSpeed);
}
在上面的代碼中#if defined POLOLU_VNH5019
就意味着你在ROSArduinoBridge.ino文件中聲明瞭宏POLOLU_VNH5019
,而你聲明這個宏就意味着你使用了POLOLU VNH5019這個硬件。所以如果我們要在這裏添加我們用到的硬件驅動也就很簡單了,只需要做三件事:
- 在ROSArduinoBridge.ino文件中添加相應的宏,比如
L298N_DUAL_HBRIDGE
- 使用條件編譯指令添加相應的條件分支,下面是一個編寫框架:
#elif defined L298N_DUAL_HBRIDGE
void initMotorController() {
...
}
void setMotorSpeed(int i, int spd) {
...
}
void setMotorSpeeds(int leftSpeed, int rightSpeed) {
setMotorSpeed(LEFT, leftSpeed);
setMotorSpeed(RIGHT, rightSpeed);
}
當然我們的電動機驅動不能隨心所欲,一定要按照其他硬件驅動的格式編寫,保持接口一致,設置電動機速度的函數的名字及參數要完全相同。
NOTE:本文並不對驅動的編寫細節做詳細說明,第一,這不是本文的重點,本文主要介紹如何根據自己的硬件來修改該功能包集;第二,我之前的博客中說過,如果想要自定義該功能包集的話,必須有一定的Arduino編程基礎,所以驅動硬件這部分需要讀者自行編寫。當然,讀者可以參考我的源碼。
- 在motor_driver.h中添加必要的函數聲明或宏
編碼器驅動的修改
這部分源碼與上節中對電動機驅動的修改十分相似,同樣使用到了條件編譯。因此我們的工作同樣是三步:
- 在ROSArduinoBridge.ino文件中添加相應的宏,例如
ABPHASE_COUNTER
- 使用條件編譯指令添加相應的條件分支,下面是一個編寫框架:
#elif defined(ABPHASE_COUNTER)
volatile long left_enc_pos = 0L;
volatile long right_enc_pos = 0L;
void initEncoders() {
}
// encoder event for the interrupt call
void leftEncoderEvent() {
}
// encoder event for the interrupt call
void rightEncoderEvent() {
}
/* Wrap the encoder reading function */
long readEncoder(int i) {
if (i == LEFT) return left_enc_pos;
else return right_enc_pos;
}
/* Wrap the encoder reset function */
void resetEncoder(int i) {
if (i == LEFT){
left_enc_pos=0L;
return;
} else {
right_enc_pos=0L;
return;
}
}
- 在encoder_driver.h中添加必要的函數聲明或宏
如果你用的是AB相的編碼器,那麼筆者的編碼器驅動你可以直接使用,基本不需要修改。
ROSArduinoBridge.ino文件的修改
這個文件相當於這個工程的主文件。你可以參考之前博客中加載ROSArduinoBridge的Sketch這部分對該文件進行相應的修改。
總結
使用ros arduino bridge功能包集的好處是,我們只需要掌握Arduino的相關編程就可以設計一個兼容多數硬件的base controller,而無需從零開始一層一層的設計base controller。所以如果你想使用這個功能包,最好初步學一下Arduino編程,否則使用這個功能包將遇到很多障礙。
在這裏可以下載我的源碼,有興趣的朋友可以參考一下。
NOTE:分支indigo-devel-lcy是我創建的分支。
參考資料
- C語言程序設計現代方法,[美]K.N.King著,人民郵電出版社
- ROS機器人程序設計,[西班牙]Aaron Martinez Enrique Fem a nedz著 機械工業出版社
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。