Question on how to make Joint move relatively to the segment

Hi Anybody workteam,
I want to ask a question about how to make the joint move relatively to the segment in Anybody sofeware.
For example,I definite a revolute joint as follows,
AnyRevoluteJoint Joint={
AnyRefFrame &Ground=.GlobalRef.Ground;
AnyRefFrame &Upperjoint=.UpperArm.Joint;
};
I want the revolute joint move relatively to the UpperArm.But the Joint node is definited in the UpperArm segment,rigidly attached to it. Thus, the Joint node’s position and orientation are specified relatively to its owner.So the revolute joint is fixed relatively to the UpperArm.In the Anybody sofeware,I can not find a good way to make the revolute joint move relatively to the segment.
I would be very grateful if you tell me how to deal with this problem.
Besh wishes,
Xiaopeng Zhang

Hi Xioapeng,

Please try to switch around the sequence of the nodes in the joint so the upper-arm node is the first node listed, as i understand the problem this will be the solution.

Best regards
Søren

Hi Søren,
Thank you for your answer very much.But that is not what I want.I am very sorry for that I did not illustrate my question clearly.
I know your solution can make the revolute joint revolve on the Frame of the UpperArm segment.But what I want to do is that making the AnyRefNode,.UpperArm.Joint move relatively to the UpperArm segment. So the revolute joint can move relatively to the UpperArm segment,not revolve on the frame of it.

Best regards
Xiaopeng

Hi Xiaopeng,

This type of joint can be done using a combination of AnyKinLinear and AnyKinRotational, this is the two ingredients used in all joints such as the revolute joint.

Please see this example

//constrain y and x rotations... leave z free
AnyKinEq RotConstraints ={
AnyKinRotational rot={
AnyRefFrame &Ground=.GlobalRef.Ground;
AnyRefFrame &Upperjoint=.UpperArm.Joint;
Type=RotAxesAngles;
};

MeasureOrganizer={1,2};
DriverPos={0,0};
DriverVel={0,0};
};


AnyKinEqSimpleDriver LinDriver ={

//drive the linear position between the two nodes using the coordinate system of the upperarm node.

AnyKinSimpleEq Lindriver={
AnyKinLinear lin={
Ref=0;
AnyRefFrame &Upperjoint=.UpperArm.Joint;
AnyRefFrame &Ground=.GlobalRef.Ground;
};

DriverPos={?,?,?};
DriverVel={?,?,?};
};

Best regards
Søren

Hi Søren,

Thanks for your reply.I tried your method,but when I started analysis,there was an error,
ERROR(OBJ.MCH.KIN3) : D:/program/A…y/example/demo.lesson5.any : ArmStudy.InitialConditions : Kinematic analysis failed in time step 0.

Here is my code,

Main = {
AnyFolder ArmModel = {
AnyFixedRefFrame GlobalRef = {
AnyDrawRefFrame DrwGlobalRef = {
ScaleXYZ = {0.1, 0.1, 0.1};
RGB = {0,1,0};
};
AnyRefNode Shoulder = {
sRel = {0,0,0};
};
AnyRefNode DeltodeusA = {
sRel = {0.05,0,0};
};
AnyRefNode DeltodeusB = {
sRel = {-0.05,0,0};
};
AnyRefNode BicepsLong = {
sRel = {0.1,0,0};
};
AnyRefNode TricepsLong = {
sRel = {-0.1,0,0};
};
}; // Global reference frame
AnyFolder Segs = {
AnySeg UpperArm = {
r0 = {0, 0.3, 0};
Axes0 =RotMat(-90pi/180, z);
Mass = 2;
Jii = {0.001, 0.01, 0.01};
AnyDrawSeg drw = {};
AnyRefNode ShoulderNode = {
sRel = {-0.2,0,0};
};
AnyRefNode ElbowNode = {
sRel = {0.2,0,0};
};
AnyRefNode DeltodeusA = {
sRel = {-0.1,0,0.02};
};
AnyRefNode DeltodeusB = {
sRel = {-0.1,0,-0.02};
};
AnyRefNode Brachialis = {
sRel = {0.1,0,0.01};
};
AnyRefNode BicepsShort = {
sRel = {-0.1,0,0.03};
};
AnyRefNode Brachioradialis = {
sRel = {0.05,0,0.02};
};
AnyRefNode TricepsShort = {
sRel = {-0.1,0,-0.01};
};
}; // UpperArm
AnySeg ForeArm = {
r0 = {0.3, 0, 0};
Mass = 2.0;
Jii = {0.001,0.01,0.01};
AnyRefNode ElbowNode = {
sRel = {-0.2,0,0};
};
AnyRefNode HandNode = {
sRel = {0.2,0,0};
};
AnyRefNode Brachialis = {
sRel = {-0.1,0,0.02};
};
AnyRefNode Brachioradialis = {
sRel = {0.0,0,0.02};
};
AnyRefNode Biceps = {
sRel = {-0.15,0,0.01};
};
AnyRefNode Triceps = {
sRel = {-0.25,0,-0.05};
};
AnyDrawSeg DrwSeg = {};
}; // ForeArm
}; // Segs folder
AnyFolder Jnts = {
AnyRevoluteJoint Shoulder = {
Axis = z;
AnyRefNode &GroundNode = …GlobalRef.Shoulder;
AnyRefNode &UpperArmNode = …Segs.UpperArm.ShoulderNode;
}; // Shoulder joint
AnyRevoluteJoint Elbow = {
Axis = z;
AnyRefNode &UpperArmNode = Main.ArmModel.Segs.UpperArm.ElbowNode;
AnyRefNode &ForeArmNode = Main.ArmModel.Segs.ForeArm.ElbowNode;
}; // Elbow joint
}; // Jnts folder
AnyFolder Drivers = {
AnyKinEqSimpleDriver ShoulderMotion = {
AnyRevoluteJoint &Jnt = …Jnts.Shoulder;
DriverPos = {-100
pi/180};
DriverVel = {30pi/180};
}; // Shoulder driver
AnyKinEqSimpleDriver ElbowMotion = {
AnyRevoluteJoint &Jnt = …Jnts.Elbow;
DriverPos = {90
pi/180};
DriverVel = {45*pi/180};
}; // Elbow driver
AnyKinEq RotConstraints ={
AnyKinRotational rot={
AnyRefFrame &GroundNode = …GlobalRef.Shoulder;
AnyRefFrame &Jnt = Main.ArmModel.Segs.UpperArm.ElbowNode;
Type=RotAxesAngles;
};
MeasureOrganizer={1,2};
};
AnyKinEqSimpleDriver LinDriver ={
AnyKinLinear lin={
Ref=0;
AnyRefFrame &Jnt = Main.ArmModel.Segs.UpperArm.ElbowNode;
AnyRefFrame &GroundNode = …GlobalRef.Shoulder;
};
DriverPos={0,0,0};
DriverVel={0.001,0,0};
};
}; // Driver folder
}; // MyModel
AnyBodyStudy ArmStudy = {
AnyFolder &Model = .ArmModel;
InverseDynamics.Criterion.Type = MR_MinMaxStrict;
Gravity = {0.0, -9.81, 0.0};
InitialConditions.SolverType = KinSolOverDeterminate;
Kinematics.SolverType = KinSolOverDeterminate;
};
}; // Main

I want to change the position of AnyRevoluteJoint Elbow on the Shoulder segment.But it looks like that Study ‘Main.ArmStudy’ contains more reaction forces than rigid-body degrees of freedom of the segments. There are 17 reactions and only 12 rigid body degrees of freedom. What should I deal with this problem?

Best regards,
Xiaopeng

Hi Xiaopeng,

The reason why the model does not work is that you did not remove the revolute joint… so you had both the new joint and the revolute joint acting on the same dof…

I also shifted the shoulder driver to point at the free rotational dof of the joint.

I have modified to the script a bit


// Todo: Write a small description of your model here

Main = {
  AnyFolder ArmModel = {    
    AnyFixedRefFrame GlobalRef = {      
      AnyDrawRefFrame DrwGlobalRef = {
        ScaleXYZ = {0.1, 0.1, 0.1};
        RGB = {0,1,0};
      };
      AnyRefNode Shoulder = { 
        sRel = {0,0,0}; 
      };
      AnyRefNode DeltodeusA = { 
        sRel = {0.05,0,0}; 
      };
      AnyRefNode DeltodeusB = { 
        sRel = {-0.05,0,0}; 
      };
      AnyRefNode BicepsLong = { 
        sRel = {0.1,0,0}; 
      };
      AnyRefNode TricepsLong = { 
        sRel = {-0.1,0,0}; 
      };
    };  // Global reference frame
    AnyFolder Segs = {
      AnySeg UpperArm = {
        r0 = {0, 0.3, 0};
        Axes0 =RotMat(-90*pi/180, z);
        Mass = 2;
        Jii = {0.001, 0.01, 0.01};
        AnyDrawSeg drw = {};        
        AnyRefNode ShoulderNode = {
          sRel = {-0.2,0,0}; 
        };
        AnyRefNode ElbowNode = {
          sRel = {0.2,0,0}; 
        };
        AnyRefNode DeltodeusA = { 
          sRel = {-0.1,0,0.02}; 
        };
        AnyRefNode DeltodeusB = { 
          sRel = {-0.1,0,-0.02}; 
        };
        AnyRefNode Brachialis = { 
          sRel = {0.1,0,0.01}; 
        };
        AnyRefNode BicepsShort = { 
          sRel = {-0.1,0,0.03}; 
        };
        AnyRefNode Brachioradialis = { 
          sRel = {0.05,0,0.02}; 
        };
        AnyRefNode TricepsShort = { 
          sRel = {-0.1,0,-0.01}; 
        }; 
      };  // UpperArm      
      AnySeg ForeArm = {
        r0 = {0.3, 0, 0};        
        Mass = 2.0;
        Jii = {0.001,0.01,0.01};
        AnyRefNode ElbowNode = {
          sRel = {-0.2,0,0};
        };
        AnyRefNode HandNode = {
          sRel = {0.2,0,0};
        };
        AnyRefNode Brachialis = { 
          sRel = {-0.1,0,0.02}; 
        };
        AnyRefNode Brachioradialis = { 
          sRel = {0.0,0,0.02}; 
        };
        AnyRefNode Biceps = { 
          sRel = {-0.15,0,0.01}; 
        };
        AnyRefNode Triceps = { 
          sRel = {-0.25,0,-0.05}; 
        };
        AnyDrawSeg DrwSeg = {};
      }; // ForeArm      
    }; // Segs folder    
    AnyFolder Jnts = {      
      //      AnyRevoluteJoint Shoulder = {
      //        Axis = z;
      //        AnyRefNode &GroundNode = ..GlobalRef.Shoulder;
      //        AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode;
      //      }; // Shoulder joint      
      AnyRevoluteJoint Elbow = {
        Axis = z;
        AnyRefNode &UpperArmNode = Main.ArmModel.Segs.UpperArm.ElbowNode;
        AnyRefNode &ForeArmNode = Main.ArmModel.Segs.ForeArm.ElbowNode;
      }; // Elbow joint      
    }; // Jnts folder    
    AnyFolder Drivers = {
      AnyKinEqSimpleDriver ShoulderMotion = {
        //AnyRevoluteJoint &Jnt = ..Jnts.Shoulder;
        AnyKinMeasureOrg Shoulder={
          AnyKinRotational &rot=..RotConstraints.rot;
          MeasureOrganizer={0};
          
        };
        
        DriverPos = {-100*pi/180};
        DriverVel = {30*pi/180};
      }; // Shoulder driver
      AnyKinEqSimpleDriver ElbowMotion = {
        AnyRevoluteJoint &Jnt = ..Jnts.Elbow;
        DriverPos = {90*pi/180};
        DriverVel = {45*pi/180};
      }; // Elbow driver      
      AnyKinEq RotConstraints ={
        AnyKinRotational rot={
          AnyRefFrame &GroundNode = ...GlobalRef.Shoulder;
          AnyRefFrame &Jnt = Main.ArmModel.Segs.UpperArm.ElbowNode;
          Type=RotAxesAngles;
        };
        MeasureOrganizer={1,2};
      };
      AnyKinEqSimpleDriver LinDriver ={
        AnyKinLinear lin={
          Ref=0;
          AnyRefFrame &Jnt = Main.ArmModel.Segs.UpperArm.ElbowNode;
          AnyRefFrame &GroundNode = ...GlobalRef.Shoulder;
        };        
        DriverPos={0,0,0};
        DriverVel={0.03,0.02,0.02};        
      };      
    }; // Driver folder    
  }; // MyModel  
  AnyBodyStudy ArmStudy = {
    AnyFolder &Model = .ArmModel;
    InverseDynamics.Criterion.Type = MR_MinMaxStrict;
    Gravity = {0.0, -9.81, 0.0};
    InitialConditions.SolverType = KinSolOverDeterminate;
    Kinematics.SolverType = KinSolOverDeterminate;
  };  
};  // Main




Best regards
Søren

Hi Søren,

Thank you for your reply.The model now runs well.While I have anothe question that whether the position of AnyRevoluteJoint Elbow can be changed in the coordinate frame of Shoulder segment.I would be very grateful for you if you give me the answer.

Best regards,
Xiaopeng

Hi Xiaopeng,

If i understand you correctly,

You want to change the revolute joint so that it no longer use the node :

AnyRefNode &UpperArmNode = Main.ArmModel.Segs.UpperArm.ElbowNode;

as the reference frame but the shoulder node

GlobalRef.Shoulder ?

Please note that this would require the elbownode to rotate with respect to its own segment? If this is what you want you will need an extra segment.

Best regards
Søren

Hi Søren,

Thank you for your attention.Yes,I want to change the position of Elbow joint in the reference frame of shoulder segment,not in the reference frame of GlobalRef.You say that I need an extra segment.But I still don’t know how to definite the Elbow joint and its drivers.Please tell me how to deal with this problem.

Best regards,
Xiaopeng

Hi Xiaopeng,

This can be done in this way

AnyKinEqSimpleDriver LinDriver ={
AnyKinLinear lin={
Ref=0;
AnyRefFrame &Jnt = Main.ArmModel.Segs.UpperArm.ShoulderNode;
AnyRefFrame &GroundNode = …GlobalRef.Shoulder;
};
DriverPos=Main.ArmModel.Segs.UpperArm.ShoulderNode.sRel;
DriverVel={0.03,0.02,0.02};
};

Best regards
Søren

Hi Søren,

Thank you for your answer.Actually,I want to verify the movement of knee joint in anybody resposite.We know that the movement of knee joint is three-dimensional.The knee joint moves with three rotational and three translational degrees of freedom.So the knee joint’s flexion and extension progresses as a combination of rolling,glidling and rotation about the longitudinal axis of the femural condyles.
The three rotational movements are easily definited in the anybody,by changing the revolute joint to the spherical joint.But I don’t know how to definite the three translational movements of knee joint.I would be very grateful if you could give me some advice.

Best regards,
Xiaopeng

Hi Søren,

Thank you for your answer.Actually,I want to verify the movement of knee joint in anybody resposite.We know that the movement of knee joint is three-dimensional.The knee joint moves with three rotational and three translational degrees of freedom.So the knee joint’s flexion and extension progresses as a combination of rolling,glidling and rotation about the longitudinal axis of the femural condyles.
The three rotational movements are easily definited in the anybody,by changing the revolute joint to the spherical joint.But I don’t know how to definite the three translational movements of knee joint.I would be very grateful if you could give me some advice.

Best regards,
Xiaopeng

Hi Xiaopeng,
this is a more complex topic. In order to model the knee in the right way you need to define ligaments, contact between femur and tibia/patella. The tools to do so are available in Version 5.0 but this is can be a tricky part. If you want to know more about how to define contact and how to apply force dependent kinematics have a look at the SpineFixationWithForceDependentKinematics application in the AMMRV1.3. A more complex knee model itself is currently under development.
If you have detailed measurements or want to test some hypotheses on knee motion you can use the combination of AnyKinLinear and AnyKinRotatioal again and set up you “custom” joint that can bascially be driven in three translations and three rotations.
Best regards,
Sebastian