LoginSignup
5
3

More than 3 years have passed since last update.

RUSTでROSパッケージを作る (1/2)

Posted at

RUSTでROSパッケージを作る

はじめに

株式会社Ristのロボットチームのプラダンです。ネパール出身ですが、2年前に来日しました。
タイのアジア工科大学大学院でメカトロニクスの修士号を取得。
Ristに入社する前は研究者、機械エンジニアとして働いていました。

概要

これは、Ristの同僚によるA Gentle Introduction to rosrust, and its actionlib SupportTurtlebot3(Burger)をROS BridgeしてRustで動かす準備のフォローアップ記事で、ROSで'.rs'のrustファイルを読み込むROSパッケージを作成し、RUSTを使ってパラメータを作成する方法について書かれています。

Catkin_wsでCargoを使ってパッケージを作成する

パッケージを作るのは簡単な作業ですが、'.rs' ファイルを読み込むパッケージを作るのは、ROS のデフォルトのプログラミング言語が c++ と python であるため、少し面倒です。空のパッケージを作成するには:

$ roscd
$ cd ../ src
$ catkin_create_pkg rust_test

パッケージが作成されたら、catkin_wsのsrcフォルダの中に入って、パッケージを見てください。ROSパッケージには以下のものが含まれているはずです。

catkin_ws
 ├── build
 ├── devel
 └── src
    └── rust_test
        ├── CMakeLists.txt
        └── package.xml

パッケージを作成する前に、catkin_wsのsrcフォルダにあることを確認してください。
次はcargoを使ってcatkin_wsのsrcフォルダ内にRUSTパッケージを作成します。

$ cargo new rust_ws

rust_wsパッケージの中には、以下のように表示されているはずです。


rust_ws
 ├── Cargo.toml
 └── src
    └── main.rs

catkin_wsの中には、ROSパッケージrust_testとカーゴパッケージrust_wsがあります。

ROSでRUSTをコンパイルす

ROSはまだRUSTをサポートしていないので、 rust_ws カーゴパッケージにいくつかの変更を加えなければなりません。
ラストテストフォルダから **CMakeLists.txtpackage.xml をコピーして、rust_wsフォルダに貼り付けてください。新しいパッケージは以下のようになります。

rust_ws
 ├── Cargo.toml
 ├── CMakeLists.txt
 ├── package.xml
 └── src
    └── main.rs

CMakeLists.txt*package.xml*は、現在のパッケージにコピーした別のパッケージのものなので、ROSとRUSTが機能するようにコードを変更する必要があります。

CMakeLists.txtファイルを変更

このファイルには元のパッケージ名、すなわち rust_test が含まれています。
Original CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(rust_test)

find_package(catkin REQUIRED)
include_directories(
# include
# ${catkin_INCLUDE_DIRS}
)

Modified CMakeLists.txt
rust_testを現在のパッケージ名rust_wsに変更し、以下のコードを追加してください。

cmake_minimum_required(VERSION 2.8.3)
project(rust_ws)

find_package(catkin REQUIRED)
include_directories(
# include
# ${catkin_INCLUDE_DIRS}
)
add_custom_target(rust_ws
    ALL
    COMMAND cargo build --release -p rust_ws
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/cargo/release/rust_ws ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/rust_ws
    COMMENT "Building my Rust library"
)

package.xmlファイルを変更

また、package.xmlも修正する必要があります。CMakeLists.txtファイルの修正と同様に、元の名前を現在のパッケージ名に変更します。
Original package.xml file:

<?xml version="1.0"?>
<package format="2">
  <name>rust_test</name>
  <version>0.0.0</version>
  <description>The rust_test package</description>

Modified package.xml file:

<?xml version="1.0"?>
<package format="2">
  <name>rust_ws</name>
  <version>0.0.0</version>
  <description>The rust_ws package</description>

catkin_wsをcargoで作成した新しいパッケージでコンプする

CMakeList.txtファイルとpackage.xmlファイルを修正したら、catkin_wsをコンパイルしてソースを作成する必要があります。しかし、catkin_wsをコンパイルする前に、ROSがRUSTの'.rs'ファイルを読み込めるようにするために、catkin_wsにもう一つ重要な追加をする必要があります。

  • このステップまでは、catkin_wsはこのようになっているはずです。
catkin_ws
 ├── build
 ├── devel
 └── src
    ├── rust_test
    └── rust_ws
        ├── Cargo.toml
        ├── CMakeLists.txt
        ├── package.xml
        └── src
                └── main.rs        
  • 次のステップでは、設定ファイルを格納する .cargo フォルダを隠しフォルダとして作成します。
    • 最も簡単な方法は、cilckを右マウスでクリックして、New Folderを選択することです。
    • .cargoというフォルダ名を付ける前に、フォルダ内にconfigファイルを作成しておくことをお勧めします!config.png
  • 無題のフォルダ名 .cargo を非表示にします。
    • 設定ファイルに以下を追加します。
[build]
target-dir = "build/cargo"
  • カーゴ環境用のCargo.tomlファイルを作成します。
    • Cargo.tomlファイルに、以下を追加します。
[workspace]
members = [ "src/rust_ws" ]

上記の手順を完了すると、catkin_wsは以下のようになるはずです。

catkin_ws
 ├── build
 ├── devel
 ├── src
    ├── rust_test
    └── rust_ws
        ├── Cargo.toml
        ├── CMakeLists.txt
        ├── package.xml
        └── src
                └── main.rs
 └── Cargo.toml    

cargo_lock.png

最後にcatkin_wsをコンパイルします。
※: srcではなくcatkin_wsフォルダにあることを確認してください。

$ catkin_make

エラーが出ないようにコンパイルした後、ソースを出しています。

$ source devel/setup.bash

ソースが作成されると、Cargo.lockファイルがcatkin_wsフォルダに表示されます。これでROSはRUSTの'.rs'スクリプトを読むことができるようになります。

catkin_ws
 ├── build
 ├── devel
 ├── src
    ├── rust_test
    └── rust_ws
        ├── Cargo.toml
        ├── CMakeLists.txt
        ├── package.xml
        └── src
                └── main.rs
 ├── Cargo.lock
 └── Cargo.toml    

シンプルなパブリッシャーノードのテスト

Source後、ROSはRUSTと通信できるようになります。RUSTがROSで動作しているかどうかをテストするには、'main.rs'に書かれた簡単なパブリッシャーコードを使用します。

use env_logger;
use rosrust;

fn main() {

    env_logger::init();

    rosrust::init("topic_publisher");

    //create publisher
    let pubs = rosrust::publish("cmd_vel", 10).unwrap();

    let rate = rosrust::rate(10.0);    

    while rosrust::is_ok(){

        let mut cmd_vel_data = rosrust_msg::geometry_msgs::Twist::default();

        cmd_vel_data.linear.x = 0.5;
        cmd_vel_data.linear.y = 0.0;
        cmd_vel_data.linear.z = 0.0;

        cmd_vel_data.angular.x = 0.0;
        cmd_vel_data.angular.y = 0.0;
        cmd_vel_data.angular.z = 0.5;

        //publish cmd
        pubs.send(cmd_vel_data).unwrap();

    }
    rate.sleep();
    rosrust::spin();

}

次に、簡単なlaunchフォルダとlaunchファイルtest.launchを作成します。
 rust_wsフォルダ内で作成するようご注意ください。**
launch.png

<launch>

    <node name ="test" pkg="rust_ws" type="rust_ws"/>

</launch>

新しいターミナルで rosrcore を起動します。

$ roscore

別の新しいターミナルで起動ファイルを実行してください。

$ roslaunch rust_ws test.launch

rosrust Dependencies

ソーシング後、ROSはRUSTと通信できるようになります。しかし、RUSTはまだROSと通信できず、常にエラーを出します。
これは、RUSTがROSのデフォルト言語ではないため、'.rs'ファイルを実行できるようにするためには、いくつかの小さな、しかし重要な依存関係が必要だからです。
rust_ws*フォルダに戻って、以下の依存関係をrust_wsのCargo.toml*ファイルに追加する必要があります。

依存関係を追加する前に:

[package]
name = "rust_ws"
version = "0.1.0"
authors = ["Praveshkp <pravesh.k.pradhan@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

依存関係を追加した後:

[package]
name = "rust_ws"
version = "0.1.0"
authors = ["Praveshkp <pravesh.k.pradhan@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
env_logger = "0.7.1"
rosrust = "0.9"
rosrust_msg = "0.1"

要件に応じて、依存関係を追加することができます。
依存関係を追加したら、カーゴビルドで依存関係をダウンロードします。

$ cargo build

 cargo buildを rust_ws パッケージの src フォルダで行っていることを確認してください。

cargoが必要な[dependencies]のダウンロードを終えた後、新しいターミナルで rostopic echo を実行してください。

$ rostopic echo /cmd_vel

そして、launchファイルを実行します。

$ roslaunch rust_ws test.launch

roslaunch.png

これは、/cmd_velというトピックと値をpublishするだけのプログラムなので、rostopic echoが値をpublishしてくれます。
pub_test.gif

Conclusion

上記の手順を踏むことで、RUST付きのROSパッケージを作成することができます。欠点は、新しい ROS with RUST パッケージを作成しようとすると、毎回同じ処理をしなければならないことです。私と 株式会社Rist の同僚は現在、このプロセスを自律的にするための作業を行っています。

5
3
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
5
3