RUSTでROSパッケージを作る

はじめに

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

概要

これは、Ristの同僚によるA Gentle Introduction to rosrust, and its actionlib SupportとTurtlebot3(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.txt と package.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.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
pub_test.gif

Conclusion

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

广告
将在 10 秒后关闭
bannerAds