rosrustの紹介2019

# rosrustとは

rosrustは `adnanademovic`さんによって開発されているpure rustによるROS（ROS1)クライアントです。

https://github.com/adnanademovic/rosrust

Rustは次世代のC++と目されていたり、Linux/Mac/Windowsで動作します。
ロボットと相性の良い言語です。

二年前にRustとRoboticsの相性を語った記事

https://qiita.com/OTL/items/297451e88a99e7bcc929

# 開発状況

基本的な機能はすべて実装済みで、**実用的に利用出来る状態**にあると思います。
ただし、TFの扱い、sensor_msgs/Imageの変換等が簡単には出来ないのでRustでプログラムする上で困ることは正直あると思います。

試したことないですがactionlibは対応しているようです。
https://github.com/adnanademovic/rosrust/tree/master/rosrust_actionlib


以前調査した[ros2_rust](https://github.com/ros2-rust/ros2_rust)はPub/Subしか出来ておらず、作ってみた感が強いですが、rosrustは実用レベルにあると思います。

rosrustは２年前から存在していて、しかも今も開発が継続されています。
個人管理リポジトリにしてはなかなか素晴らしいのではないでしょうか？

# サンプル

以下にexamplesがありますので、これを参照するのがいいと思います。

https://github.com/adnanademovic/rosrust/tree/master/rosrust/examples

一応転載しておきます。

## Publisher

```rust

use env_logger;
use rosrust;

mod msg {
    rosrust::rosmsg_include!(std_msgs / String);
}

fn main() {
    env_logger::init();

    // Initialize node
    rosrust::init("talker");

    // Create publisher
    let chatter_pub = rosrust::publish("chatter", 2).unwrap();

    let log_names = rosrust::param("~log_names").unwrap().get().unwrap_or(false);

    let mut count = 0;

    // Create object that maintains 10Hz between sleep requests
    let rate = rosrust::rate(10.0);

    // Breaks when a shutdown signal is sent
    while rosrust::is_ok() {
        // Create string message
        let mut msg = msg::std_msgs::String::default();
        msg.data = format!("hello world from rosrust {}", count);

        // Log event
        rosrust::ros_info!("Publishing: {}", msg.data);

        // Send string message to topic via publisher
        chatter_pub.send(msg).unwrap();

        if log_names {
            rosrust::ros_info!("Subscriber names: {:?}", chatter_pub.subscriber_names());
        }

        // Sleep to maintain 10Hz rate
        rate.sleep();

        count += 1;
    }
}
```

## Subscriber

```rust
use env_logger;
use rosrust;

mod msg {
    rosrust::rosmsg_include!(std_msgs / String);
}

fn main() {
    env_logger::init();

    // Initialize node
    rosrust::init("listener");

    // Create subscriber
    // The subscriber is stopped when the returned object is destroyed
    let subscriber_info = rosrust::subscribe("chatter", 2, |v: msg::std_msgs::String| {
        // Callback for handling received messages
        rosrust::ros_info!("Received: {}", v.data);
    })
    .unwrap();

    let log_names = rosrust::param("~log_names").unwrap().get().unwrap_or(false);

    if log_names {
        let rate = rosrust::rate(1.0);
        while rosrust::is_ok() {
            rosrust::ros_info!("Publisher uris: {:?}", subscriber_info.publisher_uris());
            rate.sleep();
        }
    } else {
        // Block the thread until a shutdown signal is received
        rosrust::spin();
    }
}
```

## 解説
非常に直感的にかけているのであまり解説は不要な気がしますが、いくつかポイントだけ。

### メッセージ生成

```
rosrust::rosmsg_include!(std_msgs / String);
```
ここでマクロを使って`std_msgs/String`をRustに変換しています。

### SubscriberのCallbackについて

subscriberのコールバックが以下のように定義されています。

```rust
|v: msg::std_msgs::String| {
        // Callback for handling received messages
        rosrust::ros_info!("Received: {}", v.data);
    }
```

これはC++11でいうと、

```c++
[](std_msgs::String::ConstPtr &v) {
  ROS_INFO("Received: %s", v.data.c_str());
}
```

と同じなのですが、`{}`の中は別スレッドで実行されるのでデータのやり取りをする場合にはしっかり排他制御してやる必要があります。Rustのありがたいところは排他制御しないとコンパイルエラーになるため、実行時にわけの分からないバグが発生する余地がないところです。

## ライセンス表記

一応

```
The MIT License (MIT)

Copyright (c) 2016 Adnan Ademovic

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

# 最後に

というわけでrosrustは結構実用レベルなのでぜひ使ってみてはどうでしょうか。
ros2もなんとかしてほしいところではあります・・・。