Page 1 of 1

Missing sockets when adding PointToPointSpring to ForceSet

Posted: Wed May 26, 2021 6:05 am
by edooley
Hello,

I am trying to add a PointToPointSpring between the hand and the handle of a device in my model and keep this force active when performing RRA. Currently, I can use Matlab to add the springs to the OSIM model just fine, but I cannot get the sockets to print to the XML file being used to replace the forceset for RRA. Below is a copy of what is happening. Any suggestions would be appreciated.

In Matlab I can add to the spring to the OSIM model as such:

Code: Select all

hand2handleL = PointToPointSpring();
hand2handleL.setName('L_Hand2Handle');
hand2handleL.set_appliesForce(true);
hand2handleL.setBody1(pfr_Lhandle); % handle
hand2handleL.setBody2(pfr_Lhand); % hand
hand2handleL.setPoint1(HAND_L.getMassCenter()); %coming in as Vec3; handle CoM
hand2handleL.setPoint2(HANDLE_L.getMassCenter()); %coming in as Vec3; hand CoM
hand2handleL.setStiffness(20000); % in N/m; just a guess
hand2handleL.setRestlength(length_L); % in meters, start @ zero --> reset from first walking frame
model.addForce(hand2handleL);
This adds this object to the force set in the model file, where all the needed information appears:
<PointToPointSpring name="L_Hand2Handle">
<!--Flag indicating whether the force is applied or not. If true the forceis applied to the MultibodySystem otherwise the force is not applied.NOTE: Prior to OpenSim 4.0, this behavior was controlled by the 'isDisabled' property, where 'true' meant that force was not being applied. Thus, if 'isDisabled' is true, then 'appliesForce` is false.-->
<appliesForce>true</appliesForce>
<!--Path to a Component that satisfies the Socket 'body1' of type PhysicalFrame (description: A frame on the first body that this spring connects to.).-->
<socket_body1>/bodyset/LHandle</socket_body1>
<!--Path to a Component that satisfies the Socket 'body2' of type PhysicalFrame (description: A frame on the second body that this spring connects to.).-->
<socket_body2>/bodyset/hand_l</socket_body2>
<!--Spring attachment point on body1.-->
<point1>0 -0.068095000000000003 0</point1>
<!--Spring attachment point on body2.-->
<point2>0 0.019900000000000001 -0.0071999999999999998</point2>
<!--Spring stiffness (N/m).-->
<stiffness>20000</stiffness>
<!--Spring resting length (m).-->
<rest_length>0.11847819597001483</rest_length>
</PointToPointSpring>
If I do something similar as I create the ForceSet to use when replacing all of the joints with actuators for RRA, I am running this in Matlab:

Code: Select all

hand2handleL = PointToPointSpring();
hand2handleL.setName('L_Hand2Handle');
hand2handleL.set_appliesForce(true);
hand2handleL.setBody1(pfr_Lhandle); % handle
hand2handleL.setBody2(pfr_Lhand); % hand
hand2handleL.setPoint1(L_hand.getMassCenter()); %coming in as Vec3; handle CoM
hand2handleL.setPoint2(lhandle.getMassCenter()); %coming in as Vec3; hand CoM
hand2handleL.setStiffness(20000); % in N/m; just a guess
hand2handleL.setRestlength(length_L); % in meters, start @ zero --> reset from first walking frame
forceSet.cloneAndAppend(hand2handleL);
This runs, but while the sockets for Body1 and Body2 are set in the Matlab script, they do not print to the XML to create the actuator set:
<PointToPointSpring name="L_Hand2Handle">
<!--Flag indicating whether the force is applied or not. If true the forceis applied to the MultibodySystem otherwise the force is not applied.NOTE: Prior to OpenSim 4.0, this behavior was controlled by the 'isDisabled' property, where 'true' meant that force was not being applied. Thus, if 'isDisabled' is true, then 'appliesForce` is false.-->
<appliesForce>true</appliesForce>
<!--Spring attachment point on body1.-->
<point1>0 -0.068095000000000003 0</point1>
<!--Spring attachment point on body2.-->
<point2>0 0.019900000000000001 -0.0071999999999999998</point2>
<!--Spring stiffness (N/m).-->
<stiffness>20000</stiffness>
<!--Spring resting length (m).-->
<rest_length>0.11847819597001483</rest_length>
</PointToPointSpring>
If I copy the "socket_body" objects from the model to the actuators XML, RRA runs and the springs at the hands behave as expected. I cannot find any info on why this is working in the model force set, but not when printing the XML. Does anyone have any ideas on how to solve this? It would be really useful to be able to generate the XML completely programatically.

Thanks for your help,
Evan

Re: Missing sockets when adding PointToPointSpring to ForceSet

Posted: Wed May 26, 2021 12:05 pm
by aymanh
Hi Evan,

After making changes that affect "connections" between model parts/components you need to call

Code: Select all

model.finalizeConnections()
so that the sockets XML representation is populated and can be written/serialized.

Please let us know if that works for you,
-Ayman

Re: Missing sockets when adding PointToPointSpring to ForceSet

Posted: Thu May 27, 2021 5:13 am
by edooley
Hello Ayman,

I have tried to finalize the connections on the model and the force set:

Code: Select all

%% finalize connections
model.finalizeConnections();
forceSet.finalizeFromProperties();
And I still get the same result when I print the file:

Code: Select all

%% Print file to use in RRA
forceSet.print('checkForSockets.xml');
<PointToPointSpring name="L_Hand2Handle">
<!--Flag indicating whether the force is applied or not. If true the force is applied to the MultibodySystem otherwise the force is not applied.NOTE: Prior to OpenSim 4.0, this behavior was controlled by the 'isDisabled' property, where 'true' meant that force was not being applied. Thus, if 'isDisabled' is true, then 'appliesForce` is false.-->
<appliesForce>true</appliesForce>
<!--Spring attachment point on body1.-->
<point1>0 -0.068095000000000003 0</point1>
<!--Spring attachment point on body2.-->
<point2>0 0.019900000000000001 -0.0071999999999999998</point2>
<!--Spring stiffness (N/m).-->
<stiffness>20000</stiffness>
<!--Spring resting length (m).-->
<rest_length>0.11847819597001483</rest_length>
</PointToPointSpring>
I have tried it in both orders and that does not seem to matter. The "model.finalizeConnections();" command does work when adding the forces to the model and printing the OSIM model file.

Is there something else I need to be doing in order to make sure it is in the "ForceSet" in the XML that only contains the ForceSet. This is the file that I am calling to run RRA, where RRA asks to "Replace the model's force set" and allows you to read in "Additional force set files".

Here is the full chunk of code in case I'm missing something about order:

Code: Select all

%% Add point to point spring for hands to walker
% Pull needed components into Matlab variables
% Get left hand & handle
L_hand = model.getBodySet().get('hand_l');
lhandle = model.getBodySet().get('LHandle');
pfr_Lhand = PhysicalFrame.safeDownCast(L_hand); % get "PhysicalFrame" object for setting up spring
pfr_Lhandle = PhysicalFrame.safeDownCast(lhandle);
% Get right hand
R_hand = model.getBodySet().get('hand_r');
rhandle = model.getBodySet().get('RHandle');
pfr_Rhand = PhysicalFrame.safeDownCast(R_hand); % get "PhysicalFrame" object for setting up spring
pfr_Rhandle = PhysicalFrame.safeDownCast(rhandle);

% load resting lengths that were calculated in setSpringRestLength
load('springLengths.mat')

% LEFT
hand2handleL = PointToPointSpring();
hand2handleL.setName('L_Hand2Handle');
hand2handleL.set_appliesForce(true);
hand2handleL.setBody1(pfr_Lhandle); % handle
hand2handleL.setBody2(pfr_Lhand); % hand
hand2handleL.setPoint1(L_hand.getMassCenter()); %coming in as Vec3; handle CoM
hand2handleL.setPoint2(lhandle.getMassCenter()); %coming in as Vec3; hand CoM
hand2handleL.setStiffness(20000); % in N/m; just a guess
hand2handleL.setRestlength(length_L); % in meters, start @ zero --> reset from first walking frame
forceSet.cloneAndAppend(hand2handleL);
model.addForce(hand2handleL);
% RIGHT
hand2handleR = PointToPointSpring(); 
hand2handleR.setName('R_Hand2Handle');
hand2handleR.set_appliesForce(true);
hand2handleR.setBody1(pfr_Rhandle); % handle
hand2handleR.setBody2(pfr_Rhand); % hand
hand2handleR.setPoint1(R_hand.getMassCenter()); %coming in as Vec3; handle CoM
hand2handleR.setPoint2(rhandle.getMassCenter()); %coming in as Vec3; hand CoM
hand2handleR.setStiffness(20000); % in N/m; just a guess
hand2handleR.setRestlength(length_R); %  in meters, start @ zero --> reset from first walking frame
forceSet.cloneAndAppend(hand2handleR);
model.addForce(hand2handleR);

%% finalize connections
forceSet.finalizeFromProperties();
model.finalizeConnections();


%% Print file to use in RRA
forceSet.print('checkForSockets.xml');
Thanks for your help,
Evan