I am trying to connect to and subscribe to Topics on ROSbridge using the ros-sharp project. It works fine if i specify the Type of message upon subscribing as per the code example in the Test Client:
rosSocket = new RosSocket(new RosBridgeClient.Protocols.WebSocketNetProtocol(uri), RosSocket.SerializerEnum.Newtonsoft_JSON);
string subscription_id = rosSocket.Subscribe<JointState>("/joint_states", SubscriptionHandler);
Where this is the Subscribe method:
public string Subscribe<T>(string topic, SubscriptionHandler<T> subscriptionHandler, int throttle_rate = 0, int queue_length = 1, int fragment_size = int.MaxValue, string compression = "none") where T : Message
{
string id;
lock (SubscriberLock)
{
id = GetUnusedCounterID(Subscribers, topic);
Subscription subscription;
Subscribers.Add(id, new Subscriber<T>(id, topic, subscriptionHandler, out subscription, throttle_rate, queue_length, fragment_size, compression));
Send(subscription);
}
return id;
}
And the Subscription Handler is as follows:
private static void SubscriptionHandler(object message)
{
string msg = JsonConvert.SerializeObject((Message)message, Formatting.None);
Console.WriteLine(msg);
}
however I wish to be able to specify the topic and message type by string and find that type and call the subscribe method.
I know I can do it with an exhaustive Switch e.g.:
public static string SubscribeSwitch(string type, string topic)
{
switch (type)
{
case "sensor_msgs/JointState":
return rosSocket.Subscribe<JointState>(topic, SubscriptionHandler);
break;
case "actionlib_msgs/GoalID":
return rosSocket.Subscribe<GoalID>(topic, SubscriptionHandler);
break;
}
return "";
}
But this will get pretty long and unmanageable especially if i add new Message types for different robots. I have therefore spent some time trying to use reflection to get the type to invoke the Subscribe call, but I seem to be falling over when trying to pass in the Subscription handler which has a non generic delegate type. Has anyone done similar, or provide an example of how to do this - many thanks. The following code for exmaple falls over at var subscribe: InvalidCastException: Unable to cast object of type 'System.RuntimeType' to type 'RosSharp.RosBridgeClient.Message'.
Type msgType = Type.GetType("RosSharp.RosBridgeClient.MessageTypes.Sensor.JointState,RosBridgeClient");
var mi = typeof(RosSocket).GetMethod("Subscribe");
Type[] aparams = new Type[1];
aparams[0] = msgType;
var fooRef = mi.MakeGenericMethod(aparams);
object[] test2 = new object[1];
test2[0] = msgType;
object[] test = new object[6];
test[0] = "/joint_states";
// get subscribe method info
var subscribe = typeof(RosSocketConsole).GetMethod(nameof(SubscriptionHandler), BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, test2);
test[1] = subscribe;
test[2] = 0;
test[3] = 1;
test[4] = int.MaxValue;
test[5] = "none";
string subscription_id = (string)fooRef.Invoke(rosSocket, test);
Thanks for any assistance
Aucun commentaire:
Enregistrer un commentaire