0. ROSの基本
# 2018-04-12 YMD
正確な情報はhttp://wiki.ros.org/ja/ROS/Tutorialsを参照すること.
ワークスペース
ROSはcatkinというビルドシステムを使っている.
catkinを使うことによって,パッケージの依存関係などの管理が簡単になる.
ワークスペースの作成
以下のコマンドでワークスペースを作成する.(一度だけ行う.端末を立ち上げ直しても再び行う必要はない)
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace
~/.bashrcの一番下に下記を追加する。
source ~/catkin_ws/devel/setup.bash
一度端末を閉じて,開き直して,.bashrcの変更を反映する.
cd ~/catkin_ws/ catkin_make
環境変数
ROSは環境変数をパッケージの検索などに使っているので, 環境変数を操作できるとデバッグなどで便利なことがある.
環境変数の表示
env # 全ての環境変数を表示 env | grep ROS # ROS関連の環境変数を表示 echo $PATH # 環境変数PATHを表示
ROS_PACKAGE_PATHの中に/home/USERNAME/catkin_ws/srcと/opt/ros/kinetic/shareが表示されていて,PATHの中に/opt/ros/kinetic/binが含まれていれば,正しくセットアップできている.
パッケージ(catkin形式)
パッケージを作る
例として,ros_studyというパッケージを作る.
cd ~/catkin_ws/src catkin_create_pkg ros_study std_msgs sensor_msgs nav_msgs geometry_msgs roscpp
std_msgs以降の引数は依存パッケージを指定している.
roscore
roscore
(ROSを使うときに最初に実行するコマンド,rosout,rosmaster,ros parameter serverが起動する)
roscore
roscoreを行っている間はその端末では他のコマンドが実行できないので,別の端末を起動する.
(terminatorを使っている場合にはCtrl+Shift+eやCtrl+Shift+oを使う)
ノード
rosにおけるプロセスのこと
ノードを作る
~/catkin_ws/src/ros_study/src/にros_study_node.cppを作成する
/** * inから読み取った最新のメッセージを1回~/outに出力するノード. * パラメータ~/nameで指定された名前を最初に付与する. */ #include "ros/ros.h" #include "std_msgs/String.h" #include <iostream> #include <sstream> #include <deque> static std_msgs::String::ConstPtr latest_listened_msg_ptr = nullptr; void listenCallback(const std_msgs::String::ConstPtr& msg) { latest_listened_msg_ptr = msg; } int main(int argc, char **argv) { ros::init(argc, argv, "ros_study_node"); ros::NodeHandle private_nh("~"); ros::NodeHandle nh; ros::Duration loop_duration(0.1); std::string name; ros::Publisher out_pub(private_nh.advertise<std_msgs::String>("out", 1000)); // "~/out" ros::Subscriber in_sub = nh.subscribe("in", 1000, listenCallback); // "/in" private_nh.param<std::string>("name", name, "anonymous"); // "~/name" while (ros::ok()) { if (latest_listened_msg_ptr) { std_msgs::String out_msg; std::stringstream out_ss; out_ss << name << ": "; // set name name out_ss << latest_listened_msg_ptr->data; // append listened string latest_listened_msg_ptr = nullptr; // delete message out_msg.data = out_ss.str(); // set data out_pub.publish(out_msg); // send message } ros::spinOnce(); // check topic loop_duration.sleep(); // sleep for 0.1 sec } return 0; }
ビルド設定を編集する
CMakeLists.txtから以下の行を探してコメント(# )を解除する.
# add_compile_options(-std=c++11)
# add_executable(${PROJECT_NAME}_node src/ros_study_node.cpp)
# target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # )
ビルド
cd ~/catkin_ws catkin_make
rosrun
rosrun ros_study ros_study_node # 実行しても何も表示はされない
でros_studyという名前のパッケージにあるros_study_nodeという名前のノードを実行する.
後で使うので実行したまま,別の端末を起動する.
実行中のノード一覧表示
rosnode list
topic
ノード間で非同期的にやり取りされるデータをメッセージと呼ぶ.
メッセージの送信先の指定はtopicによって行われる.
topicはwebサービスにおけるアドレスに似ている.
topic一覧の表示
rostopic list
topicに送られたデータの表示
例としてros_study_node/outのデータを表示する
rostopic echo ros_study_node/out # 現時点では何も表示されない
後で使うので実行したまま,別の端末を起動する.
topicにメッセージを配信する
例としてstd_msgs/String型の“hello”というデータをトピック“in”に配信する
rostopic pub in std_msgs/String "hello"
rostopic echoを行った端末に,data: “anonymous: hello”と表示される.
グラフの表示
インストール
sudo apt-get install ros-kinetic-rqt-graph
実行
rosrun rqt_graph rqt_graph
パラメータ
パラメータ一覧を表示する
rosparam list
パラメータを取得・設定する
例としてros_study_node/nameというパラメータを取得・設定する
rosparam get ros_study_node/name # setしていない場合には存在しないのでエラーメッセージが出る rosparam set ros_study_node/name john
セットした後で
rosrun ros_study ros_study_node
すると,パラメータros_study_node/nameを読み込ませることができる.
(ノード内部の値を動的に更新したいときにはdynamic_reconfigureを使う必要がある)
このとき
rostopic pub in std_msgs/String "hello"
を実行すると,rostopic echoを行った端末に,data: “john: hello”と表示される.
roslaunch
ノードをまとめて実行するときに使う
launchファイル
例えば,以下のようなファイルを作る.
~/catkin_ws/src/ros_study/launch/apple.launchに配置する.
<launch> <node pkg="ros_study" type="ros_study_node" name="john_node"> <param name="name" value="john"/> <remap from="/in" to="~/in"/> <remap from="~/out" to="/paul_node/in"/> </node> <node pkg="ros_study" type="ros_study_node" name="paul_node"> <param name="name" value="paul"/> <remap from="/in" to="~/in"/> <remap from="~/out" to="/george_node/in"/> </node> <node pkg="ros_study" type="ros_study_node" name="george_node"> <param name="name" value="george"/> <remap from="/in" to="~/in"/> <remap from="~/out" to="/ringo_node/in"/> </node> <node pkg="ros_study" type="ros_study_node" name="ringo_node"> <param name="name" value="ringo"/> <remap from="/in" to="~/in"/> </node> </launch>
pkgにはパッケージ名,
nameには適当に理解しやすい固有名(ノード名と同じでも可),
typeにはノード名を指定する.
paramタグを使ってパラメータを指定する.
remapタグを使ってトピック名を変更する.
launchファイルを実行する
roslaunch ros_study apple.launch
別の端末で
rostopic echo ringo_node/out
さらに別の端末で
rostopic pub john_node/in std_msgs/String "hello"
すると,data: “ringo: george: paul: john: hello”と表示される.
rosrun rqt_graph rqt_graph
すると,メッセージが受け渡される流れを確認できる.