Flutter ROS通信插件roslibdart的使用

Flutter ROS通信插件roslibdart的使用

roslibdart 是一个用于通过 websocket 与 ROS 节点进行通信的库。它受到 roslibjs 的启发,并遵循类似的结构。该库由 Eternali Conrad Heidebrecht (@Eternali),Artur Rymarz (@artrmz) 和 TimWhiting Tim Whiting (@TimWhiting) 创建。该库的这一版本是为了更新并使其兼容 Dart 2 和 ROS 2。

功能实现状态列表(基本上是一系列功能以达到 roslibjs 水平所需的功能)

  • 核心功能
    • ✅ ROS 连接对象
    • ✅ 主题对象(订阅、取消订阅、发布、广告、取消广告)
    • ✅ 服务对象(调用、广告、取消广告)
    • ✅ 请求对象(为任何潜在的 ROS 请求提供类型和命名)
    • ✅ 参数对象(获取、设置、删除)

使用方法

安装 rosbridge

你可以通过以下方式安装 rosbridge

# 通过 apt-get 安装
sudo apt-get install ros-foxy-rosbridge-server
# 或者从 GitHub 克隆
cd ros_ws/src
git clone https://github.com/RobotWebTools/rosbridge_suite
cd ..
colcon build

运行 ros bridge

cd ros_ws
source install/local_setup.bash
ros2 launch rosbridge_server rosbridge_websocket_launch.xml

测试发布者

演示:运行 ROS 发布者和 roslibdart 订阅者

# 假设 ros_ws 是你的工作空间
cp -r rospackage/* ~/ros_ws/src/
cd ~/ros_ws
colcon build
source install/local_setup.bash
ros2 run tutorial publisher
cd example/subscriber
flutter run -d linux

使用 roslibdart 订阅的例子代码

import 'package:roslibdart/roslibdart.dart';
import 'dart:convert';

void main() async {
  var ros = Ros(url: 'ws://127.0.0.1:9090');
  var chatter = Topic(
    ros: ros,
    name: '/topic',
    type: "std_msgs/String",
    reconnectOnClose: true,
    queueLength: 10,
    queueSize: 10,
  );
  ros.connect();
  await chatter.subscribe(subscribeHandler);

  Future<void> subscribeHandler(Map<String, dynamic> msg) async {
    String msgReceived = json.encode(msg);
    // 更新 UI 状态
    setState(() {});
  }
}

测试订阅者

演示:运行 ROS 订阅者和 roslibdart 发布者

ros2 run tutorial subscriber
cd example/publisher
flutter run -d linux

使用 roslibdart 发布的例子代码

import 'package:roslibdart/roslibdart.dart';
import 'dart:convert';

void main() async {
  var ros = Ros(url: 'ws://127.0.0.1:9090');
  var chatter = Topic(
    ros: ros,
    name: '/topic',
    type: "std_msgs/String",
    reconnectOnClose: true,
    queueLength: 10,
    queueSize: 10,
  );
  ros.connect();

  Map<String, dynamic> json = {"data": "Hello, ROS!"};
  await chatter.publish(json);
}

测试调用

演示:运行 roslibdart 调用者和 ROS 服务

ros2 run tutorial service
cd example/caller
flutter run -d linux

使用 roslibdart 调用服务的例子代码

import 'package:roslibdart/roslibdart.dart';
import 'dart:convert';

void main() async {
  var ros = Ros(url: 'ws://127.0.0.1:9090');
  var service = Service(
    name: 'add_two_ints',
    ros: ros,
    type: "tutorial_interfaces/AddTwoInts",
  );
  ros.connect();

  Map<String, dynamic> json = {"a": 1, "b": 2};
  Map<String, dynamic> result = await service.call(json);
  int sum = result['sum'];
}

测试提供服务

演示:运行 roslibdart 服务和 ROS 调用者

cd example/service
flutter run -d linux
ros2 run tutorial caller 2 3

使用 roslibdart 提供服务的例子代码

import 'package:roslibdart/roslibdart.dart';
import 'dart:convert';

void main() async {
  var ros = Ros(url: 'ws://127.0.0.1:9090');
  var service = Service(
    name: 'add_two_ints',
    ros: ros,
    type: "tutorial_interfaces/AddTwoInts",
  );
  ros.connect();

  await service.advertise(serviceHandler);

  Future<Map<String, dynamic>>? serviceHandler(Map<String, dynamic> args) async {
    Map<String, dynamic> response = {};
    response['sum'] = args['a'] + args['b'];
    return response;
  }
}

更多关于Flutter ROS通信插件roslibdart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter ROS通信插件roslibdart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


roslibdart 是一个用于在 Flutter 应用中与 ROS (Robot Operating System) 进行通信的 Dart 包。它允许你在 Flutter 应用中订阅 ROS 话题、发布消息以及调用 ROS 服务。以下是如何在 Flutter 项目中使用 roslibdart 的基本步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 roslibdart 依赖:

dependencies:
  flutter:
    sdk: flutter
  roslibdart: ^0.1.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入包

在你的 Dart 文件中导入 roslibdart

import 'package:roslibdart/roslibdart.dart';

3. 连接到 ROS Master

要连接到 ROS Master,你需要创建一个 Ros 对象并连接到指定的 URI:

void connectToRos() async {
  Ros ros = Ros(url: 'ws://localhost:9090'); // 替换为你的 ROS Master 的 WebSocket URL
  await ros.connect();

  ros.onConnectionChanged.listen((bool connected) {
    if (connected) {
      print('Connected to ROS');
    } else {
      print('Disconnected from ROS');
    }
  });
}

4. 订阅 ROS 话题

要订阅一个 ROS 话题,你可以使用 Topic 类:

void subscribeToTopic(Ros ros) {
  Topic topic = Topic(
    ros: ros,
    name: '/chatter',  // 替换为你要订阅的话题名称
    type: 'std_msgs/String',  // 替换为话题的消息类型
  );

  topic.subscribe((dynamic message) {
    print('Received message: $message');
  });
}

5. 发布到 ROS 话题

要发布消息到一个 ROS 话题,你可以使用 Topic 类的 publish 方法:

void publishToTopic(Ros ros) {
  Topic topic = Topic(
    ros: ros,
    name: '/chatter',  // 替换为你要发布的话题名称
    type: 'std_msgs/String',  // 替换为话题的消息类型
  );

  Map<String, dynamic> message = {'data': 'Hello, ROS!'};
  topic.publish(message);
}

6. 调用 ROS 服务

要调用一个 ROS 服务,你可以使用 Service 类:

void callService(Ros ros) async {
  Service service = Service(
    ros: ros,
    name: '/my_service',  // 替换为你要调用的服务名称
    type: 'my_package/MyService',  // 替换为服务的类型
  );

  Map<String, dynamic> request = {'data': 'Request data'};
  dynamic response = await service.call(request);
  print('Service response: $response');
}

7. 断开连接

当你不再需要与 ROS 通信时,可以断开连接:

void disconnectFromRos(Ros ros) async {
  await ros.dispose();
}

完整示例

以下是一个完整的示例,展示了如何连接到 ROS、订阅话题、发布消息以及调用服务:

import 'package:roslibdart/roslibdart.dart';

void main() async {
  Ros ros = Ros(url: 'ws://localhost:9090');
  await ros.connect();

  ros.onConnectionChanged.listen((bool connected) {
    if (connected) {
      print('Connected to ROS');
      subscribeToTopic(ros);
      publishToTopic(ros);
      callService(ros);
    } else {
      print('Disconnected from ROS');
    }
  });

  // 保持连接一段时间
  await Future.delayed(Duration(seconds: 10));

  await ros.dispose();
}

void subscribeToTopic(Ros ros) {
  Topic topic = Topic(
    ros: ros,
    name: '/chatter',
    type: 'std_msgs/String',
  );

  topic.subscribe((dynamic message) {
    print('Received message: $message');
  });
}

void publishToTopic(Ros ros) {
  Topic topic = Topic(
    ros: ros,
    name: '/chatter',
    type: 'std_msgs/String',
  );

  Map<String, dynamic> message = {'data': 'Hello, ROS!'};
  topic.publish(message);
}

void callService(Ros ros) async {
  Service service = Service(
    ros: ros,
    name: '/my_service',
    type: 'my_package/MyService',
  );

  Map<String, dynamic> request = {'data': 'Request data'};
  dynamic response = await service.call(request);
  print('Service response: $response');
}
回到顶部