ROS部署到機器人小車並實現底層電機控制過程中遇到的問題

任務:在實驗室原有的基於can總線控制的移動機器人平臺上應用ROS
步驟:1.ROS推薦系統爲ubuntu,首先需要重裝機器人的操作系統。
           2.下載並安裝ROS。
           3.原can卡不支持linux系統,須更換機器人的usbcan設備。
           4.利用所購產品附帶的測試代碼(c語言)測試硬件連接以及驅動和共享庫的安裝是否正常(即usbcan設備能否正常使用)。
           5.使用c++方式重新編譯測試代碼,解決出現的問題。
           6.原機器人平臺採用的c#編程語言,但ROS暫不支持c#,必須把底層的控制代碼移植爲c++或python。
           7.應用ROS的目的是爲了將底層的運動控制作爲無需人爲操作獨立運行的一個節點,不需要操作界面,所以改寫爲控制檯程序即可。

 

系統安裝及硬件更換過程(略)

 

爲新更換的can卡安裝驅動與接口庫

Linux下的usbcan驅動基於libusb實現,請先通過以下命令安裝依賴庫:

sudo apt-get install libusb-1.0-0

然後將can卡廠商提供的驅動共享庫libusbcan.so, libusbcan.so.1拷到/lib目錄下,在測試代碼test目錄下打開終端運行make命令即可編譯。編譯完成後運行./test,查看參數調用示例作爲參考進行測試。

問題及注意事項

1、未安裝驅動和動態鏈接庫時,can卡指示燈會顯示爲紅色。

只需,將libusbcan.so,libusbcan.so.1拷入/lib目錄下即可(驅動和動態接口庫同時解決)。成功後can卡指示燈變爲綠色。

 

2、運行測試程序時出現錯誤:ret=-3。

ret=-3是指程序運行過程中出現權限問題,即需要使用root權限運行本程序。

sudo ./test

運行程序時可以根據前面提到的調用示例添加參數,eg:sudo ./test 4 0 1 0x1400 2 3 10 1000

 

3、在自己編寫的c++代碼中調用can卡接口庫函數總是提示:未定義的引用。

1)、廠商提供的接口庫函數是用c語言寫的,所以如果要在c++文件中調用接口庫函數(即在c++中調用c動態鏈接庫),需要在頭文件中的函數聲明語句開頭添加 extern "C" 。

在C++出現以前,很多代碼都是C語言寫的,而且很底層的庫也是C語言寫的,爲了更好的支持原來的C代碼和已經寫好的C語言庫,C++中提供了extern "C"這個宏。extern "C"的主要作用就是爲了能夠正確實現C++代碼調用C語言代碼。加上extern "C"後,會指示編譯器這部分代碼按C語言的方式進行編譯以及連接,而不是C++的。(由於C++支持函數重載,因此編譯器編譯函數的過程中會將函數的返回類型也加到編譯後的代碼中,而不僅僅是函數名;而C語言並不支持函數重載,因此編譯C語言代碼的函數時不會帶上函數的返回類型,一般只包括函數名。因此,同樣的頭文件,使用c和c++方式編譯後的函數名是不同的,也就無法進行互相調用)

2)、由於extern "C"語法在C編譯環境下是不允許的,因此如果想要使頭文件中聲明的庫函數同時可以被c文件和c++文件調用編譯(廠商提供的測試程序是c文件,而我們要寫的是c++文件),要將extern "C"置於

#ifdef __cplusplus    

#endif

條件編譯之中。即:

#ifdef __cplusplus
extern "C" {
#endif
//函數聲明語句
#ifdef __cplusplus
}
#endif

這段代碼的含義是如果是在C++文件中,才使用extern "C",這樣使用是爲了保證當這個頭文件被用做C文件編譯時,可以去掉C++結構,也就是建立起C和C++公共的頭文件。

 

4、在自己編寫的ros功能包中使用c++編寫usbcan連接程序時,不僅要添加頭文件,還要把動態鏈接庫和頭文件放置於同一文件夾(include)中,然後安裝下面的步驟更改CMakeLists文件。否則也會報錯:未定義的引用。

首先要添加動態鏈接庫的絕對路徑:

    include_directories(
      include ${catkin_INCLUDE_DIRS}
    # include
      ${catkin_INCLUDE_DIRS}    /home/ldz/TEST/src/test1/include/test1 #####就這樣直接添加到後面即可
    )

然後要添加鏈接庫的名稱:

    target_link_libraries(testcan
      ${catkin_LIBRARIES}   usbcan  #####同樣直接添加
    )

即可成功編譯。

 

5、c程序移植爲c++程序運行時出現malloc非法格式轉換的問題:

C下,建議 int p = malloc(len sizeof(int))
C++下,建議 int p = (int )malloc(len * sizeof(int))    #####要使用強制類型轉換
因爲C++下有更嚴格的類型檢查 ,c允許void*指針與普通指針互相賦值,但c++不允許void*指針賦予普通指針,必須經過強制轉換纔可以。

 

6、can卡設備不能夠重複打開,否則報錯:

device opened: Type=4, Card=0
段錯誤

 

7、調用usbcan共享庫函數VCI_Transmit測試發送單條數據時可能出現的錯誤:

1)、硬件連接時高低電勢接反,報錯:request=1,transferred=0;

2)、發送數據的傳入參數格式爲整數時,注意08要寫爲8,因爲c++中08代表八進制數且超過了表示範圍,編譯報錯:invalid digit "8" in octal constant

3)、參數的數值大小一定要根據進制來轉換,如十進制的144,16進制下應爲90,如果數字不對會報錯:request=1,transferred=0

 

8、不能使用【sudo+節點名稱】的方式啓動ROS節點,只能先利用sudo su進入root用戶權限,再進入節點目錄下啓動或者使用rosrun的方式啓動否則報錯:

[FATAL] [1531025487.718466473]: ROS_MASTER_URI is not defined in the environment. Either t
ype the following or (preferrably) add this to your ~/.bashrc file in order set up your lo
cal machine as a ROS master:

export ROS_MASTER_URI=http://localhost:11311

then, type 'roscore' in another shell to actually launch the master program.
段錯誤

同時還要注意,一定記得修改root用戶的~/.bashrc文件,將ROS環境變量添加到~/.bashrc文件中,即:
source /opt/ros/kinetic/setup.bash,否則一樣會報錯

除此之外,如果想要以rosrun的方式啓動,還需要將功能包的環境變量配置腳本添加到~/.bashrc文件中,即:
source /home/ldz/New1/devel/setup.bash(普通用戶下爲:source ~/New1/devel/setup.bash,其中“~”代表當前用戶目錄,如果root用戶下不修改“~”爲絕對路徑也會找不到功能包),否則會報錯:package "new1" not found

 

9、編譯和啓動需要root權限的節點如何免root

1)、進入root用戶下,gcc或catkin_make對源文件重新進行編譯得到可執行文件(如果普通用戶下編譯過,必須刪掉原可執行文件,重新編譯生成可執行文件,否則無法利用第二步的操作更改運行權限)

2)、繼續在root用戶下輸入命令“chmod u+s 可執行文件”即可成功免root運行程序,或者回到普通用戶下輸入命令“sudo chmod u+s 可執行文件”


 

【番外】小技巧,使當前用戶免密使用sudo權限:

sudo cp /etc/sudoers .      # 備份 /etc/sudoers
sudo visudo                 # 打開 /etc/sudoers
ldz ALL=NOPASSWD:ALL        # 在文件末尾加入當前用戶權限

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章