Merge branch 'main' of http://git.mcxa.cn:88/LiXiaoqi/roslib_dart
This commit is contained in:
commit
ba2369623b
@ -38,14 +38,16 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
int msgToPublished = 0;
|
||||
@override
|
||||
void initState() {
|
||||
ros = Ros(url: 'ws://127.0.0.1:9090');
|
||||
ros = Ros(url: 'ws://192.168.1.149:9090');
|
||||
service = Service(
|
||||
name: 'add_two_ints', ros: ros, type: "tutorial_interfaces/AddTwoInts");
|
||||
name: '/add_two_ints', ros: ros, type: "/tutorial_interfaces/AddTwoInts");
|
||||
|
||||
super.initState();
|
||||
ros.connect();
|
||||
Timer(const Duration(seconds: 3), () async {
|
||||
await service.advertise(serviceHandler);
|
||||
// await service.advertise(serviceHandler);
|
||||
var res = await service.call({'a': 1, 'b': 2});
|
||||
print(res);
|
||||
});
|
||||
}
|
||||
|
||||
|
128
lib/core/action.dart
Normal file
128
lib/core/action.dart
Normal file
@ -0,0 +1,128 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'ros.dart';
|
||||
import 'request.dart';
|
||||
import 'dart:math';
|
||||
|
||||
typedef ActionHandler = void Function(Map<String, dynamic> response);
|
||||
typedef UUID = List;
|
||||
class GoalHandle {
|
||||
ActionHandler onSendGoal;
|
||||
ActionHandler onFeedback;
|
||||
ActionHandler onResult;
|
||||
|
||||
GoalHandle({
|
||||
required this.onSendGoal,
|
||||
required this.onFeedback,
|
||||
required this.onResult,
|
||||
});
|
||||
}
|
||||
// 每次发送goal都要构造Action
|
||||
class Action {
|
||||
Ros ros;
|
||||
String name;
|
||||
String type;
|
||||
// 每次发送goal时,都会生成唯一一个uuid,不能出现重复,用于后续发送cancel_goal,
|
||||
Map<String, List<num>> uuids = {};
|
||||
|
||||
StreamSubscription? goalListener;
|
||||
StreamSubscription? feedbackListener;
|
||||
StreamSubscription? resultListener;
|
||||
|
||||
StreamSubscription? cancelListener;
|
||||
|
||||
GoalHandle goalHandle;
|
||||
|
||||
Action({
|
||||
required this.name,
|
||||
required this.ros,
|
||||
required this.type,
|
||||
required this.goalHandle,
|
||||
});
|
||||
List<num> generateRandomString(int length) {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
Random random = Random();
|
||||
return List.generate(length, (index) {
|
||||
return characters[random.nextInt(characters.length)].codeUnitAt(0);
|
||||
});
|
||||
}
|
||||
void _bindFeedbackAndResult(String callId) {
|
||||
final feedbackLis = ros.stream;
|
||||
feedbackLis.listen((message) {
|
||||
goalHandle.onFeedback(message);
|
||||
});
|
||||
|
||||
final resultReceiver = ros.stream.where((message) => message['op'] == 'action_result' && message['id'] == callId)
|
||||
.map((Map<String, dynamic> message) => message['result'] == null
|
||||
? message['values']!
|
||||
: message['values']);
|
||||
|
||||
resultListener = resultReceiver.listen((d) {
|
||||
goalHandle.onResult(d);
|
||||
resultListener!.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
String sendGoal(dynamic req) {
|
||||
final callId = ros.requestServiceCaller(name);
|
||||
final completer = Completer<List>();
|
||||
final uuid = generateRandomString(16);
|
||||
var reqObj = Request(
|
||||
op: 'send_action_goal',
|
||||
id: callId,
|
||||
action: req['action'],
|
||||
type: req['type'],
|
||||
args: {
|
||||
"goal_id" : {
|
||||
"uuid": uuid,
|
||||
},
|
||||
"goal": req['args'],
|
||||
},
|
||||
);
|
||||
if (uuids.containsKey(callId)) {
|
||||
uuids[callId] = uuid;
|
||||
} else {
|
||||
uuids.addAll({callId: uuid});
|
||||
}
|
||||
ros.send(reqObj);
|
||||
|
||||
final receiver = ros.stream.where((message) {
|
||||
return message['id'] == callId && message['op'] != 'cancel_goal_response';
|
||||
} );
|
||||
goalListener = receiver.listen((d) {
|
||||
if (d["op"] == "action_result") {
|
||||
goalHandle.onResult(d);
|
||||
goalListener!.cancel();
|
||||
} else if (d["op"] == "action_feedback") {
|
||||
goalHandle.onFeedback(d);
|
||||
} else if (d["op"] == 'send_goal_response') {
|
||||
completer.complete(uuids[callId]);
|
||||
goalHandle.onSendGoal(d);
|
||||
}
|
||||
});
|
||||
|
||||
return callId;
|
||||
}
|
||||
|
||||
Future cancelGoal(dynamic req, String callId, ActionHandler onCancel) {
|
||||
final completer = Completer();
|
||||
var cancelReq = Request(
|
||||
op: 'cancel_action_goal',
|
||||
id: callId,
|
||||
action: req['action'],
|
||||
);
|
||||
print("cancelReq: ${cancelReq.toJson()}");
|
||||
ros.send(cancelReq);
|
||||
final receiver = ros.stream.where(
|
||||
(message) => message['id'] == callId && message['op'] == 'cancel_goal_response'
|
||||
);
|
||||
cancelListener = receiver.listen((d) {
|
||||
onCancel(d);
|
||||
completer.complete();
|
||||
cancelListener!.cancel();
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
@ -5,3 +5,4 @@ export 'request.dart';
|
||||
export 'service.dart';
|
||||
export 'topic.dart';
|
||||
export 'param.dart';
|
||||
export 'action.dart';
|
@ -16,6 +16,7 @@ class Request {
|
||||
this.queueLength,
|
||||
this.queueSize,
|
||||
this.service,
|
||||
this.action,
|
||||
this.args,
|
||||
this.values,
|
||||
this.result,
|
||||
@ -54,6 +55,9 @@ class Request {
|
||||
/// Service name operating on.
|
||||
String? service;
|
||||
|
||||
/// action name operating on.
|
||||
String? action;
|
||||
|
||||
/// Arguments of the request (JSON).
|
||||
Map<String, dynamic>? args;
|
||||
|
||||
@ -66,10 +70,12 @@ class Request {
|
||||
factory Request.fromJson(dynamic jsonData) {
|
||||
return Request(
|
||||
op: jsonData['op'],
|
||||
// type: jsonData['type'],
|
||||
id: jsonData['id'],
|
||||
type: jsonData['type'],
|
||||
topic: jsonData['topic'],
|
||||
msg: jsonData['msg'],
|
||||
action: jsonData['action'],
|
||||
latch: jsonData['latch'],
|
||||
compression: jsonData['compression'],
|
||||
throttleRate: jsonData['throttle_rate'],
|
||||
@ -99,6 +105,7 @@ class Request {
|
||||
if (queueLength != null) 'queue_length': queueLength,
|
||||
if (queueSize != null) 'queue_size': queueSize,
|
||||
if (service != null) 'service': service,
|
||||
if (action != null) 'action': action,
|
||||
if (args != null) 'args': args,
|
||||
if (values != null) 'values': values,
|
||||
if (result != null) 'result': result,
|
||||
|
Loading…
Reference in New Issue
Block a user