讓伺服機運轉順暢的ROS程式設計

三月 6, 2017
Facebook
Twitter
ROS(Robot Operating System)是開源的機器人系統平臺。使用這個之後,機器人就可以看見東西、測繪、導航,或是以最新的演算法作用於周圍的環境當中。假如想要製造複雜的機器人,已經準備好的ROS程式碼就能派上用場。ROS能在最低限度下運用。這可以透過Raspberry Pi等級的電腦安裝。
我們就來看看如何控制伺服機,做為ROS的入門篇吧。伺服機的缺點是會盡快遵照指令運轉,因此頭部常常會突然活動,以至於失去平衡。不過使用ROS之後,就可以進行正弦曲線運動,讓機器人保持穩定。由於可以在ROS當中進行這項操作,因此無須改寫控制用的程式碼。另外,連接伺服機和ROS的程式碼,以及伺服機的硬體都無須變更。再者,程式碼還可以任意使用。
 
ROS很適合用在Ubuntu或Debian上,無須編譯。建置時要在Linux機器上執行Ubuntu,使用業餘用伺服機、Arduino和普通的導線。ROS要在Ubuntu機器上啟動,訊息則透過USB傳送到Arduino。只要安裝二進位的ROS套件,就會在主控臺程式(像是gnome-terminal或konsole)追加以下指令,這樣Arduino系統就能辨識ROS函式庫。
 
cd ~/sketchbook/libraries
rm -rf ros_lib
rosrun rosserial_arduino make_l ibraries.py .

 
Arduino的程式
 
接下來要將程式碼上傳到Arduino當中,執行低階的伺服機控制,以便能從Linux機器操作。這時要以限制範圍內的百分比(0.0~1.0)指定伺服機的位置。之所以使用百分比而不是寫明角度,是因為Arduino的程式碼限制了正確的角度,要避免在指定角度時發生衝突。
 
就如各位所見,使用ROS之後,一般的迴圈函數就會變得相當簡單。迴圈函數只會訂閱(subscribe)資料,任何Arduino迴圈都一樣。設定時要將ROS初始化,將各個ROS訊息訂閱者的訂閱叫出來。每個訂閱者會佔據Arduino的RAM,數量取決於要用程式碼做什麼,以6個到12個為限。
 
#include <Arduino.h>
#include <Servo.h>
 
#include <ros.h>
#include <std_msgs/Float32.h>
 
#define SERVOPIN 3
 
Servo servo;
void servo_cb( const std_msgs:: Float32& msg )
{
const float min = 45;
const float range = 90;
float v = msg.data;
 
if( v > 1 ) v = 1;
if( v < 0 ) v = 0;
 
float angle = min + (range * v);
servo.write(angle);
}
ros::Subscriber<std_msgs::Float 32> sub( “/head/tilt”, servo_cb );
 
ros::NodeHandle nh;
 
void setup()
{
servo.attach(SERVOPIN);
 
nh.initNode();
nh.subscribe(sub);
}
 
void loop()
{
nh.spinOnce();
delay(1); }
 

接下來要設法透過Arduino在ROS的世界說話。最簡單的方法是使用機器人啟動檔。雖然以下的檔案內容非常簡單,但是這裡要追加啟動檔,如此一來即使是非常複雜的機器人,也能用一個指令啟動。
 
$ cat rosservo.launch
 
<launch>
<node pkg=”rosserial_python” type=”serial_node.py” name= “osservo” respawn=”true”output=”screen”>
<param name=”port” value=”/dev/ttyUSB0″ />
</node>
</launch>
 
$ roslaunch ./rosservo.lanch

 
rostopic指令可以看出ROS訊息傳送到機器人的哪個部位。看了下面的程式碼就會發現,「/head/tilt」可以透過Arduino使用。訊息要使用「rostopic」傳送。-1的選項只會發布(publish)訊息一次,通知/head/tilt傳送一個浮點數。
 
$ rostopic list
/diagnostics
/head/tilt
/rosout
/rosout_agg
 
$ rostopic pub -1 /head/tilt std_msgs/Float32 0.4
$ rostopic pub -1 /head/tilt std_msgs/Float32 0.9

 
這個階段當中,能夠將所有發布數值到ROS的已知方法用在控制伺服機上。假如從0改成1,伺服機就會全速運行。這本來並沒有問題,但實際上我們想要逐漸加速以達到全速,然後再逐漸減速,停在目標角度上。假如伺服機驟然運轉,機器人的動作就會變得僵硬,讓周圍的人嚇一跳。
用另一個節點平滑運動
圖片

Houndbot

圖片

Terry

Terry和Houndbot都是ROS機器人,以6061個鋁合金零件製造而成。我的目標是要盡量讓這些機器人自主運動。
 
以下的Python腳本程式會監聽「/head/tilt/smooth」的訊息,朝「/head/tilt」發布許多訊息,好讓伺服機轉到目標角度之前慢慢加速,再慢慢延遲旋轉。當訊息抵達「/head/tilt/smooth」時一定會呼叫「moveServo_cb」。這個回呼函式會從-90到+90度之間每10度產生1個數值,追加到角度陣列當中。「sin()」會取這個角度,數值從-1到+1慢慢增加。該數值加1之後,範圍就會變成0到+2,再除以2之後, 0到+1的曲線數值陣列就完成了。然後再看看m陣列當中,每當發布訊息時,就會稍微前進一點,範圍在r之內,直到1*r或是全範圍為止。
 
#!/usr/bin/env python
 
from time import sleep
import numpy as np
 
import rospy
from std_msgs.msg import Float32
 
currentPosition = 0.5
pub = None
 
def moveServo_cb(data):
global currentPosition, pub
 
targetPosition = data.data
r = targetPosition – currentPosition
angles = np.array( (range(190)) [0::10]) – 90
m = ( np.sin( angles * np.pi/ 180. ) + 1 ) /2
 
for mi in np.nditer(m):
pos = currentPosition + mi*r
print “pos: “, pos
pub.publish(pos)
sleep(0.05)
 
currentPosition = targetPosition
print “pos-e: “, currentPosition
pub.publish(currentPosition)
 
def listener():
global pub
rospy.init_node(‘servoencoder’, anonymous=True)
rospy.Subscriber(‘/head/tilt/smooth’, Float32, moveServo_cb)
pub = rospy.Publisher(‘/head/tilt’, Float32, queue_size=10)
rospy.spin()
 
if __name__ == ‘__main__’:
listener()
 

想要測試伺服機順暢的動作,就要啟動Python腳本,將訊息發布到「/head/tilt/smooth」,這樣一來即可檢視順暢的動作。
 
$ ./servoencoder.py
$ rostopic pub -1 /head/tilt/smooth std_msgs/Float32 1
$ rostopic pub -1 /head/tilt/smooth std_msgs/Float32 0

 
ROS當中的名稱也可以重新測繪。只要將「/head/tilt/smooth」重新測繪為「/head/tilt」,程式就能向伺服機發出命令,而不會意識到正弦曲線的數值在變化。
 
迎向未來
 
雖然這裡只說明了簡單的伺服機控制,ROS卻有更多功能。假如想要知道妨礙機器人的東西是什麼,不妨使用已經支援ROS的Kinect。就算導航堆疊使用這項資料測繪,也可以饋送簡短的Python腳本,讓伺服機動起來,命令機器人追蹤附近的物體。沒錯,眼睛真的會追逐物體。
 
我用ROS做出Terry和Houndbot這2臺機器人。Terry是室內用機器人,搭載2個Kinect。一個專門用來導航,另一個則用於深度測繪。Terry使用6個Arduinos,能夠從用了ROS的網路介面或PS3遙控器直接操作。
 
Houndbot是設計成要在戶外使用。裡頭有遙控器、GPS、羅盤和ROS耳形控制器。現在我正想要搭載導航用的PS4雙鏡頭攝影機,因為Kinect不能在陽光下使用。這臺機器人重量為20公斤。前幾天追加了懸吊系統,為此還自行製造鋁合金客製化零件。
 
ROS相關資訊

Installation on Ubuntu
Delve into the world of navigation with ROS
ROS Q&A
Grab one of the many books on ROS
Get your robot arm on the move with ROS & MoveIt!
Run the NASA-GM Robonaut2 in a simulator. ROS is up there!
By Ben Martin
[原文]

(譯:李友君)
Social media & sharing icons powered by UltimatelySocial