このドキュメントの内容

ROSを触り始めたが、pythonもC++もあまり得意ではないので、RustでNodeを書きたくやり方を調べた。
rosrustを利用すればできることはすぐわかったし、わかりやすい記事も紹介されていたが、これらのページだけではcatkinで管理する方法がわからなかったので調べた結果をメモする。

以下の内容は基本的に公式サイトのチュートリアルとrosrustのリポジトリに立っていたissueの内容である。

手順

まずRustのプロジェクトを作る。プロジェクト名は適宜変更する。

$cd ~/catkin_ws/src
$cargo new --bin rust_test

作られたRustのプロジェクトをROSパッケージとして認識させるためには、package.xmlとCMakeLists.txtを含まなければならない(公式サイトのチュートリアル参照)ので、この2つを作る。

CMakeファイルはissueに neachdainnさんが記載されていた内容ほぼそのままであるが、オリジナルではcargoのpオプションでmy-projectとしているのに、copyの行ではmy-project-binaryと書かれており、コピーに失敗するので注意が必要である。
project名はRustのプロジェクト名と合わせて変更する。

(これでも動くけど変更箇所が多いので、修正参照)

cmake_minimum_required(VERSION 3.0)
project(rust_test)

find_package(catkin REQUIRED)
catkin_package()

add_custom_target(rust_test
    ALL
    COMMAND cargo build --release -p rust_test
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/cargo/release/rust_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/rust_test
    COMMENT "Building my Rust library"
)

package.xmlはC++のときと同じ容量で書き換える。これもプロジェクト名を合わせる

<?xml version="1.0"?>
<package format="2">
  <name>rust_test</name>
  <version>0.0.0</version>
  <description>my 1st rosrust package</description>
//以下略

これでROSのパッケージとして認識され、catkin_makeのビルド対象として扱われる。
但しこのままだとまだビルドがうまく行かないので、Rust側で設定をいくつか行う。

まず~/catkin_ws/Cargo.tomlに、ビルド対象となるRustリポジトリの場所を記載する。

[workspace]
members = [ "src/rust_test" ]

次に~/catkin_ws/.cargo/configに以下の設定を入れる。

[build]
target-dir = "build/cargo"

こうしておくと、cargoでビルドされたファイルが~/catkin_ws/build/cargo内に収まるので、C++で書かれたパッケージと混じらない。

これでビルド環境自体はできたので、実際のコードを記載する。これは元記事やrosrustにある通りで、Rustがかける人には問題にならないので割愛。
(但し、rosrustのトップページに有るpub/subの例は、talkerがStringで送っているのにlistenerがUInt64で待ち受けているので通信に失敗する。何かしら間違っているのかと思って三度見したので注意が必要。)

最終的にディレクトリ構成はこうなる

catkin_ws
|--- Cargo.toml
|--- .cargo
|    |--- config
|--- src
     |--- rust_test
     |     |--- Cargo.toml
     |     |--- CMakeLists.txt
     |     |--- package.xml
     |     |--- src
     |           |--- main.rs

この状態で

$cd ~/catkin_ws
$catkin_make
$rosrun rust_test rust_test 

するとRustで書いたROSパッケージが起動する。roslaunchも大丈夫だった。C++を書く必要はなくなりそうで一安心。

修正(2020/10/5)

CMakefileで何箇所もプロジェクト名を書かないといけないのは面倒なので、変数化した。


cmake_minimum_required(VERSION 3.0)
# add_custom_targetでコマンドを叩くので環境変数として定義しておく
set (ENV{PROJECT_NAME} rust_test)
project($ENV{PROJECT_NAME})


find_package(catkin REQUIRED COMPONENTS
                std_msgs
                message_generation
)

add_message_files(
                FILES
                Orientation.msg
)

catkin_package(
                CATKIN_DEPENDS std_msgs message_runtime
)

add_custom_target($ENV{PROJECT_NAME}
        ALL
        COMMAND cargo build --release -p $ENV{PROJECT_NAME}
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/cargo/release/$ENV{PROJECT_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$ENV{PROJECT_NAME}
        COMMENT "Building my Rust library"
)

# セットした環境変数をクリアしておく
unset (ENV{PROJECT_NAME})                          

あと、当然だがCMakefileやpackage.xmlで記載しているプロジェクト名と、Cargo.toml内のプロジェクト名が一致していないと動かないので注意。
(今日別のリポジトリをコピーしてハマった)

bannerAds