-
Notifications
You must be signed in to change notification settings - Fork 5
/
RosBridgeFactory.cs
131 lines (114 loc) · 6.37 KB
/
RosBridgeFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Copyright (c) 2019-2021 LG Electronics, Inc.
*
* This software contains code licensed as described in LICENSE.
*
*/
using System;
using Simulator.Bridge.Data;
// NOTE: DO NOT add using "Ros.Ros", "Ros.Apollo" or "Ros.Lgsvl" namespaces here to avoid
// NOTE: confusion between types. Keep them fully qualified in this file.
namespace Simulator.Bridge.Ros
{
[BridgeName("ROS", "ROS")]
public class RosBridgeFactory : IBridgeFactory
{
public IBridgeInstance CreateInstance() => new ROS();
public RosBridgeFactory()
{
}
public void Register(IBridgePlugin plugin)
{
// point cloud is special, as we use special writer for performance reasons
plugin.AddType<PointCloudData>(RosUtils.GetMessageType<Ros.PointCloud2>());
plugin.AddPublisherCreator<PointCloudData>(
(instance, topic) =>
{
var rosInstance = instance as ROS;
rosInstance.AddPublisher<Ros.PointCloud2>(topic);
var writer = new RosPointCloudWriter(rosInstance, topic);
return new Publisher<PointCloudData>((data, completed) => writer.Write(data, completed));
}
);
RegPublisher<ImageData, Ros.CompressedImage>(plugin, Conversions.ConvertFrom);
RegPublisher<LaserScanData, Ros.LaserScan>(plugin, Conversions.ConvertFrom);
RegPublisher<CameraInfoData, Ros.CameraInfo>(plugin, Conversions.ConvertFrom);
RegPublisher<Detected2DObjectData, Lgsvl.Detection2DArray>(plugin, Conversions.ConvertFrom);
RegPublisher<ClockData, Ros.Clock>(plugin, Conversions.ConvertFrom);
RegSubscriber<VehicleStateData, Lgsvl.VehicleStateDataRos>(plugin, Conversions.ConvertTo);
RegSubscriber<Detected2DObjectArray, Lgsvl.Detection2DArray>(plugin, Conversions.ConvertTo);
RegSubscriber<Detected3DObjectArray, Lgsvl.Detection3DArray>(plugin, Conversions.ConvertTo);
// std_srvs/Empty
RegService<EmptySrv, Ros.Empty, EmptySrv, Ros.Empty>(plugin, Conversions.ConvertTo, Conversions.ConvertFrom);
// std_srvs/SetBool
RegService<SetBoolSrv, Ros.SetBool, SetBoolSrv, Ros.SetBoolResponse>(plugin, Conversions.ConvertTo, Conversions.ConvertFrom);
// std_srvs/Trigger
RegService<EmptySrv, Ros.Empty, TriggerSrv, Ros.Trigger>(plugin, Conversions.ConvertTo, Conversions.ConvertFrom);
// gps data is special, because it actually sends two Ros.Sentence messages for each data point from simulator
plugin.AddType<GpsData>(RosUtils.GetMessageType<Ros.Sentence>());
plugin.AddPublisherCreator(
(instance, topic) =>
{
var rosInstance = instance as ROS;
rosInstance.AddPublisher<Ros.Sentence>(topic);
var writer = new RosNmeaWriter(rosInstance, topic);
return new Publisher<GpsData>((data, completed) => writer.Write(data, completed));
}
);
RegPublisher<CanBusData, Lgsvl.CanBusDataRos>(plugin, Conversions.RosConvertFrom);
RegPublisher<DetectedRadarObjectData, Lgsvl.DetectedRadarObjectArray>(plugin, Conversions.RosConvertFrom);
RegPublisher<GpsOdometryData, Ros.Odometry>(plugin, Conversions.ConvertFrom);
RegPublisher<ImuData, Ros.Imu>(plugin, Conversions.ConvertFrom);
RegPublisher<Detected3DObjectData, Lgsvl.Detection3DArray>(plugin, Conversions.ConvertFrom);
RegPublisher<SignalDataArray, Lgsvl.SignalArray>(plugin, Conversions.ConvertFrom);
RegPublisher<UltrasonicData, Lgsvl.Ultrasonic>(plugin, Conversions.ConvertFrom);
RegPublisher<VehicleOdometryData, Lgsvl.VehicleOdometry>(plugin, Conversions.ConvertFrom);
RegSubscriber<VehicleControlData, Lgsvl.VehicleControlDataRos>(plugin, Conversions.ConvertTo);
}
public void RegPublisher<DataType, BridgeType>(IBridgePlugin plugin, Func<DataType, BridgeType> converter)
{
plugin.AddType<DataType>(RosUtils.GetMessageType<BridgeType>());
plugin.AddPublisherCreator<DataType>(
(instance, topic) =>
{
var rosInstance = instance as ROS;
rosInstance.AddPublisher<BridgeType>(topic);
var writer = new RosWriter<BridgeType>(rosInstance, topic);
return new Publisher<DataType>((data, completed) => writer.Write(converter(data), completed));
}
);
}
public void RegSubscriber<DataType, BridgeType>(IBridgePlugin plugin, Func<BridgeType, DataType> converter)
{
plugin.AddType<DataType>(RosUtils.GetMessageType<BridgeType>());
plugin.AddSubscriberCreator< DataType>(
(instance, topic, callback) => (instance as ROS).AddSubscriber<BridgeType>(topic,
rawData => callback(converter(RosSerialization.Unserialize<BridgeType>(rawData)))
)
);
}
public void RegService<ArgDataType, ArgBridgeType, ResDataType, ResBridgeType>(IBridgePlugin plugin, Func<ArgBridgeType, ArgDataType> argConverter, Func<ResDataType, ResBridgeType> resConverter)
{
plugin.AddServiceCreator<ArgDataType, ResDataType>(
(instance, topic, service) =>
{
// this callback is called every time sensor registers service on different topic
(instance as ROS).AddService<ArgBridgeType>(topic,
(rawArg, resultCb) =>
{
// this callback is called every time websocket receives message from rosbridge
var arg = RosSerialization.Unserialize<ArgBridgeType>(rawArg);
var argData = argConverter(arg);
service(argData, resData =>
{
// this callback is called from sensor service callback to return result data back to rosbridge
var res = resConverter(resData);
resultCb(res);
});
}
);
}
);
}
}
}