Tue Feb 22 09:54:27 PM HKT 2022
61
README.md
@ -45,6 +45,21 @@ ros2 run tutorial publisher
|
|||||||
cd example/subscriber
|
cd example/subscriber
|
||||||
flutter run -d linux
|
flutter run -d linux
|
||||||
```
|
```
|
||||||
|
### Subscribe using roslibdart
|
||||||
|
```
|
||||||
|
ros = Ros(url: 'ws://127.0.0.1:9090');
|
||||||
|
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 {
|
||||||
|
msgReceived = json.encode(msg);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Testing subscriber
|
## Testing subscriber
|
||||||
### Run topic subscriber
|
### Run topic subscriber
|
||||||
```
|
```
|
||||||
@ -54,8 +69,16 @@ ros2 run tutorial subscriber
|
|||||||
```
|
```
|
||||||
cd example/publisher
|
cd example/publisher
|
||||||
flutter run -d linux
|
flutter run -d linux
|
||||||
|
|
||||||
```
|
```
|
||||||
|
### Publish using roslibdart
|
||||||
|
```
|
||||||
|
ros = Ros(url: 'ws://127.0.0.1:9090');
|
||||||
|
chatter = Topic(ros: ros, name: '/topic', type: "std_msgs/String", reconnectOnClose: true, queueLength: 10, queueSize: 10);
|
||||||
|
ros.connect();
|
||||||
|
Map<String, dynamic> json = {"data": msgToPublished.toString()};
|
||||||
|
await chatter.publish(json);
|
||||||
|
```
|
||||||
|
|
||||||
## Testing call
|
## Testing call
|
||||||
### Run tutorial addtwoint service
|
### Run tutorial addtwoint service
|
||||||
```
|
```
|
||||||
@ -65,18 +88,46 @@ ros2 run tutorial service
|
|||||||
cd example/client
|
cd example/client
|
||||||
flutter run -d linux
|
flutter run -d linux
|
||||||
```
|
```
|
||||||
|
### Call a service using roslibdart
|
||||||
|
```
|
||||||
|
ros = Ros(url: 'ws://127.0.0.1:9090');
|
||||||
|
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);
|
||||||
|
msgToPublished = result['sum'];
|
||||||
|
```
|
||||||
## Testing providing service
|
## Testing providing service
|
||||||
### Fire up flutter service
|
### Fire up flutter service
|
||||||
|
```
|
||||||
|
cd example/service
|
||||||
|
flutter run -d linux
|
||||||
|
```
|
||||||
|
### Run tutorial call
|
||||||
|
```
|
||||||
|
ros2 run tutorial client
|
||||||
|
```
|
||||||
|
|
||||||
### Run the client from shell
|
### Run the client from shell
|
||||||
```
|
```
|
||||||
ros2 run tutorial client 2 3
|
ros2 run tutorial client 2 3
|
||||||
```
|
```
|
||||||
|
### Provide service using roslibdart
|
||||||
|
```
|
||||||
|
ros = Ros(url: 'ws://127.0.0.1:9090');
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Links
|
## Links
|
||||||
- [ROSBridge Protocol v2.0](https://github.com/biobotus/rosbridge_suite/blob/master/ROSBRIDGE_PROTOCOL.md).
|
- [ROSBridge Protocol v2.0](https://github.com/biobotus/rosbridge_suite/blob/master/ROSBRIDGE_PROTOCOL.md).
|
||||||
- [Original roslib library from Conrad Heidebrecht](https://github.com/Eternali/roslib)
|
- [Original roslib library from Conrad Heidebrecht](https://github.com/Eternali/roslib)
|
||||||
- [RosBridge server implementation](https://github.com/RobotWebTools/rosbridge_suite)
|
- [RosBridge server implementation](https://github.com/RobotWebTools/rosbridge_suite)
|
||||||
|
- [roslibjs example](https://github.com/RobotWebTools/roslibjs/blob/develop/examples/simple.html)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# client
|
# caller
|
||||||
|
|
||||||
A new Flutter project.
|
A new Flutter project.
|
||||||
|
|
@ -43,7 +43,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.example.client"
|
applicationId "com.example.caller"
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion flutter.minSdkVersion
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
@ -1,5 +1,5 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.client">
|
package="com.example.caller">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
@ -1,7 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.client">
|
package="com.example.caller">
|
||||||
<application
|
<application
|
||||||
android:label="client"
|
android:label="caller"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.client
|
package com.example.caller
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 721 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@ -1,5 +1,5 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.client">
|
package="com.example.caller">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
@ -294,7 +294,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.client;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.caller;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -422,7 +422,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.client;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.caller;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@ -444,7 +444,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.client;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.caller;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 68 B |
@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Client</string>
|
<string>Caller</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>client</string>
|
<string>caller</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
@ -14,11 +14,11 @@ class MyApp extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Roslibdart Client Example',
|
title: 'Roslibdart Caller Example',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
),
|
),
|
||||||
home: const MyHomePage(title: 'Roslibdart Client Example'),
|
home: const MyHomePage(title: 'Roslibdart Caller Example'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,10 +54,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void initConnection() async {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroyConnection() async {
|
void destroyConnection() async {
|
||||||
await ros.close();
|
await ros.close();
|
||||||
setState(() {});
|
setState(() {});
|
@ -1,8 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(runner LANGUAGES CXX)
|
project(runner LANGUAGES CXX)
|
||||||
|
|
||||||
set(BINARY_NAME "client")
|
set(BINARY_NAME "caller")
|
||||||
set(APPLICATION_ID "com.example.client")
|
set(APPLICATION_ID "com.example.caller")
|
||||||
|
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
|
|||||||
if (use_header_bar) {
|
if (use_header_bar) {
|
||||||
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
|
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
|
||||||
gtk_widget_show(GTK_WIDGET(header_bar));
|
gtk_widget_show(GTK_WIDGET(header_bar));
|
||||||
gtk_header_bar_set_title(header_bar, "client");
|
gtk_header_bar_set_title(header_bar, "caller");
|
||||||
gtk_header_bar_set_show_close_button(header_bar, TRUE);
|
gtk_header_bar_set_show_close_button(header_bar, TRUE);
|
||||||
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
|
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
|
||||||
} else {
|
} else {
|
||||||
gtk_window_set_title(window, "client");
|
gtk_window_set_title(window, "caller");
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_window_set_default_size(window, 1280, 720);
|
gtk_window_set_default_size(window, 1280, 720);
|
@ -8,7 +8,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'package:client/main.dart';
|
import 'package:caller/main.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 917 B |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -23,13 +23,13 @@
|
|||||||
<!-- iOS meta tags & icons -->
|
<!-- iOS meta tags & icons -->
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="client">
|
<meta name="apple-mobile-web-app-title" content="caller">
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>client</title>
|
<title>caller</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "client",
|
"name": "caller",
|
||||||
"short_name": "client",
|
"short_name": "caller",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#0175C2",
|
"background_color": "#0175C2",
|
@ -49,10 +49,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void initConnection() async {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroyConnection() async {
|
void destroyConnection() async {
|
||||||
await ros.close();
|
await ros.close();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -81,7 +77,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text('return answer ' + msgToPublished.toString()),
|
Text('Service returns answer ' + msgToPublished.toString()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:roslibdart/roslibdart.dart';
|
import 'package:roslibdart/roslibdart.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const ExampleApp());
|
runApp(const ExampleApp());
|
||||||
@ -37,12 +39,11 @@ class _HomePageState extends State<HomePage> {
|
|||||||
queueLength: 10,
|
queueLength: 10,
|
||||||
queueSize: 10);
|
queueSize: 10);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
|
||||||
|
|
||||||
void initConnection() async {
|
|
||||||
ros.connect();
|
ros.connect();
|
||||||
await chatter.subscribe();
|
Timer(const Duration(seconds: 3), () async {
|
||||||
setState(() {});
|
await chatter.subscribe(subscribeHandler);
|
||||||
|
// await chatter.subscribe();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyConnection() async {
|
void destroyConnection() async {
|
||||||
@ -51,51 +52,28 @@ class _HomePageState extends State<HomePage> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String msgReceived = '';
|
||||||
|
Future<void> subscribeHandler(Map<String, dynamic> msg) async {
|
||||||
|
msgReceived = json.encode(msg);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Roslibdart Subscriber Example'),
|
title: const Text('Roslibdart Subscriber Example'),
|
||||||
),
|
),
|
||||||
body: StreamBuilder<Object>(
|
body: Center(
|
||||||
stream: ros.statusStream,
|
// Center is a layout widget. It takes a single child and positions it
|
||||||
builder: (context, snapshot) {
|
// in the middle of the parent.
|
||||||
return Center(
|
child: Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
children: <Widget>[
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
Text(msgReceived + ' received'),
|
||||||
children: <Widget>[
|
],
|
||||||
StreamBuilder<Map<String, dynamic>>(
|
),
|
||||||
stream: chatter.subscription,
|
),
|
||||||
builder: (BuildContext context2,
|
|
||||||
AsyncSnapshot<Map<String, dynamic>> snapshot2) {
|
|
||||||
if (snapshot2.hasData && snapshot2.data != null) {
|
|
||||||
return Text('${snapshot2.data!['msg']}');
|
|
||||||
} else {
|
|
||||||
return const CircularProgressIndicator();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ActionChip(
|
|
||||||
label: Text(snapshot.data == Status.connected
|
|
||||||
? 'DISCONNECT'
|
|
||||||
: 'CONNECT'),
|
|
||||||
backgroundColor: snapshot.data == Status.connected
|
|
||||||
? Colors.green[300]
|
|
||||||
: Colors.grey[300],
|
|
||||||
onPressed: () {
|
|
||||||
// print(snapshot.data);
|
|
||||||
if (snapshot.data != Status.connected) {
|
|
||||||
initConnection();
|
|
||||||
} else {
|
|
||||||
destroyConnection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ import 'dart:async';
|
|||||||
import 'ros.dart';
|
import 'ros.dart';
|
||||||
import 'request.dart';
|
import 'request.dart';
|
||||||
|
|
||||||
|
// Receiver function to handle requests when the service is advertising.
|
||||||
|
typedef SubscribeHandler = Future<void> Function(Map<String, dynamic> args);
|
||||||
|
|
||||||
/// Wrapper to interact with ROS topics.
|
/// Wrapper to interact with ROS topics.
|
||||||
class Topic {
|
class Topic {
|
||||||
Topic({
|
Topic({
|
||||||
@ -72,7 +75,7 @@ class Topic {
|
|||||||
///
|
///
|
||||||
/// Defaults to true.
|
/// Defaults to true.
|
||||||
bool reconnectOnClose;
|
bool reconnectOnClose;
|
||||||
|
/*
|
||||||
/// Subscribe to the topic if not already subscribed.
|
/// Subscribe to the topic if not already subscribed.
|
||||||
Future<void> subscribe() async {
|
Future<void> subscribe() async {
|
||||||
if (subscribeId == null) {
|
if (subscribeId == null) {
|
||||||
@ -91,6 +94,30 @@ class Topic {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Future<void> subscribe(SubscribeHandler subscribeHandler) async {
|
||||||
|
if (subscribeId == null) {
|
||||||
|
// Create the listenable broadcast subscription stream.
|
||||||
|
subscription = ros.stream;
|
||||||
|
subscribeId = ros.requestSubscriber(name);
|
||||||
|
await safeSend(Request(
|
||||||
|
op: 'subscribe',
|
||||||
|
id: subscribeId,
|
||||||
|
type: type,
|
||||||
|
topic: name,
|
||||||
|
compression: compression,
|
||||||
|
throttleRate: throttleRate,
|
||||||
|
queueLength: queueLength,
|
||||||
|
));
|
||||||
|
subscription!.listen((Map<String, dynamic> message) async {
|
||||||
|
if (message['topic'] != name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await subscribeHandler(message['msg']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unsubscribe from the topic.
|
/// Unsubscribe from the topic.
|
||||||
Future<void> unsubscribe() async {
|
Future<void> unsubscribe() async {
|
||||||
|