Page 1 of 1

Linear Movement of a Ball

Posted: Sat Jan 11, 2025 3:21 am
by kardelen
Hi all,
I am new to OpenSim and trying to update the OpenSim model using Python. I am trying to add a ball and move it linearly. I can successfully add a ball to the model, but I am having difficulty moving it linearly. While I can add the ball, it remains stationary. I have checked various sources and examples, but I still can't find the answer to my question. Any help would be appreciated.
You can find the related code below:


# Add Ball to the Model
ball = opensim.Body('target', 0.0010 , opensim.Vec3(0), opensim.Inertia(1,1,.0001,0,0,0) );
ball.setName('Ball');
ball.setMass(1);
ball.setInertia( opensim.Inertia(1,1,1,0,0,0) );
ballGeometry = opensim.Ellipsoid(0.1, 0.1, 0.1);
ballGeometry.setColor( opensim.Vec3(0.8, 0.1, 0.1) );

target_joint = opensim.PlanarJoint('target-joint',
model.getGround(), # PhysicalFrame
opensim.Vec3(3, 0.1, 0),
opensim.Vec3(0, 0, 0),
ball, # PhysicalFrame
opensim.Vec3(0, 0, -0.1),#Vec3(0, 0, -0.25)
opensim.Vec3(0, 0, 0))

ball.attachGeometry(ballGeometry);
model.addJoint(target_joint)
model.addBody(ball)

model.addController(brain)#Add a Controller to the Model.
model_state = model.initSystem()
BallLocation = ball.getPositionInGround(model_state)

target_joint.getCoordinate(0).setLocked(state, False)
target_joint.getCoordinate(1).setLocked(state, False)
target_joint.getCoordinate(2).setLocked(state, True)

istep = 0
stepsize = 0.01
def set_state(state):
state = state
istep = int(state.getTime() / stepsize)

i = 3


while i >= 0:
#model.getStateVariableValue(state, "target-joint")
state = opensim.State(state)
target_joint.getCoordinate(1).setLocked(state, False)
target_joint.getCoordinate(1).setValue(state, -i, False)
target_joint.getCoordinate(1).setLocked(state, True)
set_state(state)
i -= 1;


NOTE: I am getting error when I add "model.getStateVariableValue(state, "target-joint")" code and couldn't find how to use it.

Re: Linear Movement of a Ball

Posted: Tue Jan 14, 2025 12:07 pm
by nicos1993
Hello Kardelen,

What are you exactly trying to do? You want to apply a force with a controller to a rigid body and move it along a particular coordinate? Have you tried looking at the C++ examples for optimizing the controls of the arm_26.osim model? You could potentially also take some inspiration from the Moco exampleSlidingMass.

Thanks,

Nicos

Re: Linear Movement of a Ball

Posted: Tue Jan 14, 2025 2:13 pm
by kardelen
Hi Nicos,
Thank you for your response. I want to apply a force with a controller to a rigid body and move it along a particular coordinate, that is true. I checked the "Moco exampleSlidingMass," but it appears to be focused on an optimization problem. My goal is to move the ball just once. Additionally, I am working on an OpenSim model that includes a human body and tried to integrate the Moco sample code into my project. However, it seems to be trying to optimize something related to the muscles and other parameters.


Thank you

Re: Linear Movement of a Ball

Posted: Wed Jan 15, 2025 12:48 pm
by kardelen
I think I need to update the state to move the ball, however, I can't. I defined a slider joint for the ball and tried to get state of it by "model.getStateVariableValue(state,'/target-joint/position/value')", but I got below error.Can you help me please to properly call getStateVariableValue and setStateVariableValue functions?

Error:
RuntimeError: std::exception in 'double OpenSim::Component::getStateVariableValue(SimTK::State const &,std::string const &) const': Component::getStateVariableValue: ERR- state named '/target-joint/position/value' not found in 3DGaitModel2392 of type Model

Re: Linear Movement of a Ball

Posted: Wed Jan 15, 2025 4:26 pm
by nicos1993
Hello Kardelen,

To set the state variables for a coordinate you would do something as follows (roughly):

model = Model();
state = model.initSystem();

X = [1 0];

% getting the 0th coordinate in the model, setting its value and speed
model.getCoordinateSet.get(0).setValue(state,X(1));
model.getCoordinateSet.get(0).setSpeed(state,X(2));

% apply whatever forces you wish to apply, and then integrate accordingly - see the C++ optimizationExample_Arm26 you will of course have to adapt it slightly for your use case.

Thanks,

Nicos