RobotecAI / ros2-for-unity

High-performance ROS2 solution for Unity3D
Apache License 2.0
446 stars 58 forks source link

Some variables are read-only in ros2cs message class #66

Closed chenjunnn closed 1 year ago

chenjunnn commented 1 year ago

Describe the bug I want to publish camera info from Unity to ROS2, then I found the K variable in sensor_msgs.msg.CameraInfo is read-only and there is no constructor which can change the value of K. Also the P and R are read-only, too.

public double[] P { get; }
public double[] R { get; }
public double[] K { get; }

The original type in raw sensor_msgs CameraInfo message definition is float64 array with specified length of 9, and all the arrays of specified length in csharp are read-only.

float64[9]  K # 3x3 row-major matrix

So is there a solution to change the value of K in csharp script?

adamdbrw commented 1 year ago

I believe that having the getter for the array only means you can't set the entire array, but you can set them by index. Have you tried P[0] = x?

IIRC the reason for dynamic memory fields to be read only is that assigning another array would require freeing up native memory while we garbage collect - this is not something that is going to work without some gimmicks and a performance overhead.

chenjunnn commented 1 year ago

@adamdbrw Thanks for your help! I have tried setting the value by index last time but I forget to initialize camInfoMsg itself 🤣

private sensor_msgs.msg.CameraInfo camInfoMsg;
...
camInfoMsg = new sensor_msgs.msg.CameraInfo(); // I forgot to initialize last time
camInfoMsg.K[0] = fx;
camInfoMsg.K[2] = cx;
camInfoMsg.K[4] = fy;
camInfoMsg.K[5] = cy;
camInfoMsg.K[8] = 1;

The above method is totally fine.

adamdbrw commented 1 year ago

Glad this works for you! Different memory models of C# and C++ can be confusing and require some design choices when mixing :D