Unity-Robotics-Hub
Unity-Robotics-Hub copied to clipboard
InvalidCastException: Specified cast is not valid
Hello,
I am trying to connect ROS with the Kart Microgame provided by unity. I have added the assembly to the project but I get the error InvalidCastException: Specified cast is not valid within the file ROSConnection.cs in the callback((T)msg);
line:
public void Subscribe<T>(string topic, Action<T> callback) where T : Message
{
string rosMessageName = MessageRegistry.GetRosMessageName<T>();
AddSubscriberInternal(topic, rosMessageName, (Message msg) =>
{
if (msg.RosMessageName == rosMessageName)
{
callback((T)msg);
}
else
{
Debug.LogError($"Subscriber to '{topic}' expected '{rosMessageName}' but received '{msg.RosMessageName}'!?");
}
});
}
I tested this in other projects and worked fine. I suspect that the problem might be in using namespaces in the original project. Yet I do not know how to solve it after trying for several hours. I modified the script KeyboardInput.cs from the Kart Micrograme template provided by unity:
using UnityEngine;
using System;
using Unity.Robotics.ROSTCPConnector;
using Float64array = RosMessageTypes.Std.Float64MultiArrayMsg;
namespace KartGame.KartSystems {
public class KeyboardInput : BaseInput
{
public string TurnInputName = "Horizontal";
public string AccelerateButtonName = "Accelerate";
public string BrakeButtonName = "Brake";
private float[] handRotation = new float[3];
void Start(){
ROSConnection.GetOrCreateInstance().Subscribe<Float64array>("/hand/rotation",handRotationCallback);
}
void handRotationCallback(Float64array msg)
{
//Debug.Log(msg);
Debug.Log("Hello");
//handRotation[0] = (float) msg.data[0];
//handRotation[1] = (float) msg.data[1];
//handRotation[2] = (float) msg.data[2];
}
public override InputData GenerateInput() {
//Debug.Log("0: "+handRotation[0]+" 1: "+handRotation[1]+" 2: "+handRotation[2]);
return new InputData
{
Accelerate = Convert.ToSingle(Input.GetButton(AccelerateButtonName)),
Brake = Input.GetButton(BrakeButtonName),
TurnInput = Input.GetAxis("Horizontal")
};
}
}
}
Any help/hint would be greatly appreciated, thank you!
Hi, thanks for the report! I've created an internal ticket to investigate the issue. We'll get back to you with any updates.
In the meantime, can you clarify the following:
- how are you constructing the messages sent on
/hand/rotation
? - how and where are you publishing the
/hand/rotation
messages?
[Ticket#: AIRO-1662]
Hi, thanks for the report! I've created an internal ticket to investigate the issue. We'll get back to you with any updates.
In the meantime, can you clarify the following:
* how are you constructing the messages sent on `/hand/rotation`? * how and where are you publishing the `/hand/rotation` messages?
[Ticket#: AIRO-1662]
Hi Thank you for your fast answer.
- I have a node running that publishes an Float64MultyArrayMsg of size 3 with three different floats.
- This node is publishing correctly, is seen by Unity and in simpler projects it can be subscribed to by the unity project
Hey @yunacu, I believe the standard size for a float in C# is 32 bits, so the invalid cast you are seeing is in attempting to cast a 64 bit value into a 32 bit type. Try using (double)
instead and see if that resolves the error.
edit: After re-reading I just wanted to clarify: Are you seeing the "Hello" debug print you've put in? If you see "Hello" printed to console, then the issue is likely in casting the array values to float
. If you don't see that message, then you should double-check that the fully-qualified type you're passing to the Subscriber class matches your callback type, and we should include some additional logic to enforce that constraint.
Hey @yunacu, I believe the standard size for a float in C# is 32 bits, so the invalid cast you are seeing is in attempting to cast a 64 bit value into a 32 bit type. Try using
(double)
instead and see if that resolves the error.edit: After re-reading I just wanted to clarify: Are you seeing the "Hello" debug print you've put in? If you see "Hello" printed to console, then the issue is likely in casting the array values to
float
. If you don't see that message, then you should double-check that the fully-qualified type you're passing to the Subscriber class matches your callback type, and we should include some additional logic to enforce that constraint.
I am not seeing the "hello" message. With a simpler project, I subscribed with the same type of message and it worked well. Any reason why it would not work in this project? I am not sure what you mean for a fully-qualified type, how can I test this? I think this is not the reason of the error since it worked with the same topic on a different unity project
If you are getting an invalid cast on callback invocation then whatever is getting passed to callback must not be a RosMessageTypes.Std.Float64MultiArrayMsg
. Can you use a breakpoint to stop execution and examine the type of the message being passed to the callback?
If you are getting an invalid cast on callback invocation then whatever is getting passed to callback must not be a
RosMessageTypes.Std.Float64MultiArrayMsg
. Can you use a breakpoint to stop execution and examine the type of the message being passed to the callback?
I cannot execute it because the error prevents me from playing. I tried again with another simple project and it works without problem:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using Float64array = RosMessageTypes.Std.Float64MultiArrayMsg;
public class MovePlatform : MonoBehaviour
{
public Rigidbody2D rb;
private float[] handRotation = new float[3];
// Start is called before the first frame update
void Start()
{
ROSConnection.GetOrCreateInstance().Subscribe<Float64array>("/hand/rotation",handRotationCallback);
}
void handRotationCallback(Float64array msg)
{
Debug.Log(handRotation[0]);
//Debug.Log("Hello");
handRotation[0] = (float) msg.data[0];
handRotation[1] = (float) msg.data[1];
handRotation[2] = (float) msg.data[2];
}
// Update is called once per frame
private void FixedUpdate()
{
//Debug.Log(Input.GetAxis("Vertical"));
//rb.rotation += Input.GetAxis("Vertical");
//rb.AddTorque(Input.GetAxis("Vertical"));
rb.AddTorque(handRotation[0]/100);
}
}
I believe this problem can be reproduced by downloading the Kart Microgame, adding the ROS package to the project and the assembly and subscribing to any topic. It does not need to be a float array
This issue has been marked stale because it has been open for 14 days with no activity. Please remove the stale label or comment on this issue, or the issue will be automatically closed in the next 14 days.
The issue has not been solved yet
Can you upload the project into a repo and share it here ?
This issue has been marked stale because it has been open for 14 days with no activity. Please remove the stale label or comment on this issue, or the issue will be automatically closed in the next 14 days.