4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ROS講座22 リモートでロボットの電源を切る

Last updated at Posted at 2018-06-13

環境

この記事は以下の環境で動いています。

項目
CPU Core i5-8250U
Ubuntu 16.04
ROS Kinetic

インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。

概要

意外と面倒なのがロボットの電源を切ることです。「sudo shutdown now」程度のコマンドなら簡単に行えますが、ロボットには通常時はキーボードやモニタがつながっていないのでこんなことも面倒です。
普通はsshで接続して電源を切るのですが

  1. ssh r_user@robot1
  2. パスワードを入力
  3. sudo shutdown now
  4. パスワードを入力

と意外と手間がかかります。これをroslaunchでリモートlaunchすることでコマンド1つで実行しようというのが今回の趣旨です。今回の記事では以下の2点を説明します。

  • c++でbashコマンドを実行する方法
  • sudoが必要なコマンドを実行する方法

c++でbashコマンド実行

C++のプログラム中からはsystem()関数を使うとbashコマンドを実行できます。system()関数を使うには#include <stdlib.h>のインクルードをする必要があります。例えば以下のようにするとbashコマンドを実行できます。

robot_shutdown.cpp
#include <stdlib.h>
int main(void){
    system(" COMMAND ");
    return 0;
}

sudoコマンドの実行

上記の例を踏まえて以下のようなプログラムを実行すると失敗します。これはsudoを打つことによってパスワードを対話的に要求されてしまうためです。

sudoコマンドの実行:失敗する
#include <stdlib.h>
int main(void){
    system("sudo shutdown now");
    return 0;
}

これを解決する方法としてsudo -Sのオプションを使うという方法です。これはパスワードを標準入力から受け取るというオプションです。例えばパスワードがpasswordだった場合はecho 'password' | sudo -S commandとすると実行できてしまいます。パスワードが直書きなのでセキュリティー的には大変よろしくないのですが、一番簡単な解決策です。

結論

最終的な案を以下に示します。

net_lecture/src/net_shutdown.cpp
#include <stdlib.h>
int main(void){
    system("echo 'password' | sudo -S shutdown now");
    return 0;
}

これを普通のROSのC++プログラムと同じようにCMakeList.txtを書いてコンパイルします。ROSのC++プログラムもただのC++プログラムにROSのライブラリを追加しただけのものです。

net_lecture/CMakeLists.txtに追加
add_executable(net_shutdown src/net_shutdown.cpp)

target_link_libraries(net_shutdown
  ${catkin_LIBRARIES}
)

これをshutdownする対象のロボット上でbuildします。

これをlaunchファイルから起動します。

et_lecture/launch/remote_shutdown.launch
<launch>
  <machine name="robot1" address="192.168.1.20" env-loader="/home/r_user/catkin_ws/devel/env.sh" user="r_user" password="password"/>
  <node machine="robot1" pkg="adv_lecture" type="robot_shutdown" name="robot_shutdown" required="true"/> 
</launch>

<machine>タグではshutdownをする対象のPC(ロボット)を指定します。このROSノードを起動するとPCがシャットダウンするのでROSノードももちろん落ちます。この時にrequired="true"を指定しておくとそのROSノードが落ちた時に自動的にlaunchも停止します。

robot1がshutdownする
roslaunch net_lecture remote_shutdown.launch

上のコマンドでネットワークでつながっている別のPC(ロボット)の電源を切ることができます。
この時robot_shutdownはrobot1側で実行されるのでこのプログラムが入っているROSパッケージであるadv_lectureがrobot1に入っている必要があります。

目次ページへのリンク

ROS講座の目次へのリンク

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?