1
0

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 1 year has passed since last update.

ZenohのLaunchをつくりたかった記事

Posted at

はじめに

関係ありませんが、今年初の投稿です。
最近Zenohの開発をしていてROS2のLaunchみたいなことできないかなと思い、奮闘した記録です。

どのようにしたか

はじめはコマンドラインツールによる実装を考え作ろうとしてみたのですが、うまくいかず挫折しました。
そこでROS2みたいな実装を思い出しcomponent.cppとnode.cppに分ける感じでつくればいいのではと考えました。(説明下手でスミマセン...)

成果

ノード実装例

適当なコードを実装しました

ファイル構造はリポジトリをご確認ください。
まずlib.rsでメインの機能を定義します。

lib.rs
use zenoh::{
    Error,
    config::Config,
    prelude::r#async::*,
};

use std::time::Duration;

pub async fn pub_test(node_name:&str)->Result<(), Error>
{
    let session = zenoh::open(Config::default()).res().await.unwrap();

    let topic = "test_topic";

    let publisher = session.declare_publisher(topic).res().await.unwrap();

    let mut count = 0;

    println!("Start {}", node_name);

    loop {
        let msg = format!("Hello {}", count);
        publisher.put(msg).res().await.unwrap();

        count += 1;

        std::thread::sleep(Duration::from_millis(1000));
    }
}

pub async fn sub_test(node_name:&str)->Result<(), Error>
{
    let session = zenoh::open(Config::default()).res().await.unwrap();

    let topic = "test_topic";

    let subscriber = session.declare_subscriber(topic).res().await.unwrap();

    println!("Start {}", node_name);

    loop {
        let sample = subscriber.recv_async().await.unwrap();

        println!("Recv:{}", sample.value.to_string());
    }
}

適当なPubSubですね
引数でノード名を指定できるようにしました。(ROS2でいうRemapとかできそうですね)

Launchしてみる

それでは別のパッケージから呼び出してみます。
Cargo.tomlでは今回呼び出すパッケージを指定しています。

Cargo.toml
[dependencies]
async-std = "1.0"
zenoh = "0.7.0-rc"

zenoh_pubsub = {git = "https://github.com/motii8128/zenoh_pubsub.git"}

Githubのリポジトリのリンク貼っただけですね

メインコードです

src/main.rs
use async_std;
use zenoh::Error;
use zenoh_pubsub::pub_test;

#[async_std::main]
async fn main()->Result<(), Error>
{
    let pub_task = async_std::task::spawn(pub_test("PUBLISHER_A"));

    pub_task.await?;

    Ok(())
}

実行したところ以下のようなログになりました。

user@laptop:~/test_launch$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/test_launch`
Start PUBLISHER_A

指定したノード名で起動できていますね。
ではここでSubscriberの方も同時に呼び出しましょう。
先程のコードに加えます。

src/main.rs
use async_std;
use zenoh::Error;
use zenoh_pubsub::{pub_test, sub_test};

#[async_std::main]
async fn main()->Result<(), Error>
{
    let pub_task = async_std::task::spawn(pub_test("PUBLISHER_A"));
    let sub_task = async_std::task::spawn(sub_test("SUBSCRIBER_B"));

    pub_task.await?;
    sub_task.await?;

    Ok(())
}

実行すると

user@Laptop:~/test_launch$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/test_launch`
Start SUBSCRIBER_B
Start PUBLISHER_A
Recv:Hello 0
Recv:Hello 1
Recv:Hello 2
Recv:Hello 3
Recv:Hello 4
Recv:Hello 5
Recv:Hello 6
Recv:Hello 7
Recv:Hello 8

どちらも呼び出せました。

おわりに

最適解かわかりませんが、一応目的は達成できたと思います。
yamlのパスを引数にした関数にすれば、パラメーターをyamlから取得するみたいにできることは色々ありそうですね。今から色々つくっておいて、ロボコンの時にはつなぐだけみたいな形が理想です。
また、以下のように純粋なRustで動くロボットのソフトウェアを開発中です。issue等お待ちしております。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?