0
Beantwortet

Read the position of the free state drive or joint

Ahmo vor 1 Monat in General Questions aktualisiert von Support vor 2 Wochen 5

Hello. I need a quick response if possible.

I am using the RealVirtual Professional version.

How can I achieve the desired goal in the image? Should I use a Joint or Drive?

For Drive, you have Drive_MeasureSpeedPosition, and that’s great.

Is it possible to disable the Drive so it can rotate freely?

Image 1277

Wird überprüft

Hi, for free joints you should use Unity Physic Joints, for fixed position controlled drive you should use our Drives - which are not using Physics. It is not possible to add our Drive to the Encoder you are showing. 

I tested this with Articulation Bodies. I used Python and ROS2 as a bridge between Unity and the PLC. All works well.
The reason I purchased your package is that it offers various interfaces.
I need a script similar to 'DriveMeasureSpeedPosition.cs' but for Articulation Body.
Here is the code that works. Can I implement PLC IO (Speed PLC Input Float) into my script?
Of course, I need to get rid of ROS2.
I want to achieve same, but related to Articulation Body.
We have already agreed on the project with the customer, so we are in a hurry.


using UnityEngine;
using ROS2;
using System;
using std_msgs.msg;

public class Encoder : Ros2TopicComponent
{
private ArticulationBody articulationBody;
public char axisDrive = 'x'; // Default axis ('x', 'y', or 'z')
public bool publish = true;
public float distanceTraveled = 0f;
public float encoderDiameter = 0.1f; // Encoder diameter in meters (0.1m = 100mm)
private float lastAngle = 0f; // Last recorded angle in radians

private const float FullCircle = 2 * Mathf.PI;

void Start()
{
articulationBody = GetComponent();

if (articulationBody == null)
{
Debug.LogError("ArticulationBody not assigned to " + this.name);
return;
}
if (publish)
{
CreatePub(articulationBody.name, new Float32());
}

// Initialize lastAngle with the starting angle
lastAngle = GetCurrentAngle();
}

void FixedUpdate()
{
float currentAngle = GetCurrentAngle();
float angleDelta = currentAngle - lastAngle;

// Account for overflow if the angle wraps around (360 degrees or 2π radians)
if (angleDelta > Mathf.PI)
{
angleDelta -= FullCircle;
}
else if (angleDelta < -Mathf.PI)
{
angleDelta += FullCircle;
}

// Calculate distance traveled based on angle delta
distanceTraveled += (angleDelta / FullCircle) * (encoderDiameter * Mathf.PI);
lastAngle = currentAngle;
// Publish distance traveled
if (publish)
{
Float32 msg = new Float32();
msg.Data = distanceTraveled;
Float32Publisher(msg);
}
}

// Helper method to get the current angle based on the selected axis
private float GetCurrentAngle()
{
switch (axisDrive)
{
case 'x':
return articulationBody.jointPosition[0];
case 'y':
return articulationBody.jointPosition[1];
case 'z':
return articulationBody.jointPosition[2];
default:
Debug.LogError("Invalid axisDrive character. Use 'x', 'y', or 'z'.");
return 0f;
}
}
}

Image 1284

Hi, you could implement your own "Behavior Model" for the Articulated body with a public PLCInputFloat.


In the fixedupdate of your code you write MyPlcInputFloat.Value = ArticulatedBody.Rotation .


This is just dummy code but I think you know how to get the correct rotation of your articulated body.

Hi! Thanks for PLCInputFloat :)

I managed to connect the ArticulationBody

using realvirtual;

public PLCInputFloat Position;

Position.Value = ArticulatedBody.Rotation;


Image 1286