ROS
[ROS Husky主題實作] 單元1 : 創建 WORKSPACE 和 讓Husky Car自主移動的Publisher (發佈者/節點)
<source : gazebo中的模擬截圖>
一、前言
開始進行ROS應用開發前,最重要的就是建立開發環境,常見的工作環境名稱為 "catkin_ws",也可以依據你的實際需求做其他命名。
在 "catkin_ws"中,通常會有 "src"、"build"、"devel"等3個資料夾。我們所撰寫或下載的程式碼都會放在"src"。"build" 是放置編譯過程中的暫存資料 ; "devel" 則是存放編譯完的資料。因此,在開發過程中,開發者僅會使用到 "src" 資料夾,而不會碰觸到 "build" 和 "devel" 資料夾。
本次實作將透過創建工作空間和撰寫讓 Husky Car 隨機駕駛的 Publisher Node,更進一步熟悉關於ROS應用的基本觀念。
順帶一提,實作的系統為 Ubuntu 16.04 和 ROS Kinetic。
二、實作解說
(一)、創建工作空間
工作空間其實就是一個存儲 Package (套件包)的 directories(路徑)。 創建工作空間的步驟如下 :
1.創建工作空間
$ mkdir ~/catkin_ws
2.建立 "src" 資料夾
$ mkdir ~/catkin_ws/src
如同先前所提, "src" 為我們放置開發程式碼的路徑,因此在建立完工作空間後,接這就是建立 "src"。
3.進到 "src",並對工作空間初始化
$ cd ~/catkin_ws/src
$ catkin_init_workspace
(二)、創建Package 和 Publisher Node
建立工作空間後,未來要創建新的套件或撰寫任何程式碼,都記得要先進到 "src"中。我們希望讓 Husky Car 能隨機移動,實現的過程將會藉由建立名為 "random_husky_driver" 套件包,在套件包底下建立一個Publisher Node,再發布移動的資料到 "/husky_velocity_controller/cmd_vel" 的Topic,順利實現讓Husky Car 隨機移動的目的。
接下來,我們從創建套件包開始。
1.進入 "src"
$ cd ~/catkin_ws/src
2.創建package(套件包)
$ catkin_create_pkg <套件包名稱> <相依套件1> <相依套件2> <相依套件3> ...
此處範例為 $ catkin_create_pkg random_husky_driver roscpp std_msgs
如下圖所示 :
套件建立完後,將會在 "random_husky_driver"那層路徑看到屬於該套件的 "src",關於此套件的程式碼將會存放於此 "src" 中,詳細的路徑如下圖所示。
3.編輯名為 random_driver.cpp 的程式文件檔
$ gedit random_driver.cpp
關於程式碼,請見本文第三部份。
4.編譯程式碼
設定 package.xml 和 CMakeLists.txt 內容。
package.xml >>
CMakeLists.txt >>
1.查找相關的CMake套件
2.設定catkin_package
3.設定可執行目標 和 指定連接可執行目標之套件
完成上述檔案編輯後,存檔關閉,回到 catkin_ws,執行編譯。
$ cd ~/catkin_ws
$ catkin_make
5.更新環境變數,執行 Launch 檔,開啟gazebo等相關設定
$ source ~/catkin_ws/devel/setup.bash
$ roslaunch husky_gazebo husky_empty_world.launch
6.執行新建的Publisher node 程式
$ rosrun random_husky_driver random_driver
(如果 terminal 顯示找不到套件,則在下一次更新環境變數的指令,再重新執行)
正常執行後,husky_car將在gazebo中自主移動,如下圖所示。
7.查看message內容
透過以下指令,將可以看到發佈的message,線性的x值和角度的z值呈隨機變化。
$ rostopic echo /husky_velocity_controller/cmd_vel
(三)、程式碼解說
---
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <stdlib.h>
int main(int argc, char **argv){
//initializes ROS, and sets up a node
ros::init(argc, argv, "random_husky_commands");
ros::NodeHandle bh;
//create the publisher, and tells it to publish
//to the husky_velocity_controller/cmd_vel topic, with a queue size of 100
ros::Publisher pub=nh.advertise<geometry_msgs::Twist>("husky_velocity_controller/cmd_vel", 100);
//Sets up the random number generator
srand(time(0));
//sets the loop to publish at a rate of 10Hz
ros::Rate rate(10);
while (ros::ok())
{
//declares the message to be sent
geometry_msgs::Twist msg;
//random x value between -2 and 2
msg.linear.x = 4*double(rand())/double(RAND_MAX)-2;
//random y value between -3 and 3
msg.angular.z = 6*double(rand())/double(RAND_MAX)-3;
//publish the message
pub.publish(msg);
//delays until it is time to send another message
rate.sleep();
}
}
---
1.
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
載入必要的標頭檔
<ros/ros.h>定義了ROS運行的基本功能。<geometry_msgs/Twist.h>定義了所需的訊息型式。
2.
ros::init(argc, argv, "random_husky_commands");
ros::NodeHandle nh;
第一行為初始化這個名為 "random_husky_commands"的節點。第二行的宣告,方便對節點資源的使用與管理。
3.
ros::Publisher pub=nh.advertise<geometry_msgs::Twist>("husky_velocity_controller/cmd_vel", 100);
該行定義發布message的動作,發布的訊息為 "geometry_msga::Twist",Topic為 "husky_velocity_controller/cmd_vel"。
100表示message的佇列大小為100,也就是可存放100單位的message。值越大,訊息的緩存空間越大。
在實際的移動狀況中,我們會設定的較小的值,因為過大的值會增加機器人的移動風險。而對於感測器而言,會使用較大的設定值來降地資料丟失的機率。
4.
ros::Rate rate(10)
...
rate.sleep()
ros::Rate rate(10),控制迴圈執行的頻率,頻率是10Hz。rate.sleep則表示讓節點在一個週期工作後,休息一段時間,10Hz (100 ms)後,再進行下一段循環工作。
5.
while(ros::ok())
該指令表示,除非接收到停止指令,否則程式會繼續執行。
6.
msg.linear.x=4*double(rand())/double(RAND_MAX)-2;
msg.angular.z=6*double(rand())/double(RAND_MAX)-3;
定義發送的訊息資料。
7.
pub.publish(msg)
定義將訊息加入發佈佇列中,進行發佈。
---
參考資料 :
#WORKSPACE #catkin #publisher # node #husky #launch #CMakeList #package
0 留言