Lesson 4: Kinetics

Having persuaded the model to move correctly we shall proceed to the task of imposing external forces and computing muscle and joint forces in the system.

The AnyBody Modeling System allows you to distinguish clearly between kinematics and kinetics, which is a huge advantage when creating models like this one. In the real world, the muscles would be pulling on the bones, which causes the arms to exert forces on the handles, which subsequently creates the movement of the wheel. The distinction between kinematics and kinetics in AnyBody allows you to let the wheel rotation impose the kinematics of the entire system, i.e. reversely of how it happens in the real world, while the forces flow the correct way from the muscles to the handles.

To make this happen, we must make a couple of additions to the model. Both concern the definition of the wheel in the Environment.any file. When you open the file you can find the definition of the driver that makes the wheel revolve. To this driver we must add the following setting:

AnyKinEqSimpleDriver WheelTurn = {
  AnyRevoluteJoint &Hub = .WheelHub;
  DriverVel = {-pi};
  Reaction.Type = {Off};   // No motor in the driver
};

This setting ensures that the driver does not provide any torque to the wheel, and it is separation of kinematics and kinetics in a nutshell: The driver provides the wheel rotation, which further down the kinematic chain causes the arms to move too, but it does not provide any sort of torque, so other elements in the system must do the work. We have to set everything up so that those "other elements" are the muscles. Right now the muscles would not have a very difficult time providing the work because there wheel still has no resistance to work against. This we can provide by means of an applied torque. We shall presume that the arms are driving the wheel against a constant torque, which we can apply as an AnyForce to the hub:

AnyKinEqSimpleDriver WheelTurn = {
  AnyRevoluteJoint &Hub = .WheelHub;
  DriverVel = {-pi};
  Reaction.Type = {Off};   // No motor in the driver
};

AnyForce WheelTorque = {
  AnyRevoluteJoint &Hub = .WheelHub;
  F = {30};
};

AnyForce is a generic force object that imposes an external load on whatever kinematic measure you apply it to. If the measure is linear in nature, then the load is a force. If the measure is rotational as in the case of the revolute joint in the wheel, then the load becomes a torque. In the present case we are applying 30 torque units of load to the wheel, and because the wheel driver has no motor, this torque must be balanced by the muscles in the system.

There are just a couple of things to do to ice the cake. The first thing issue is that the original standing model has its forward/backward posture driven to maintain balance. This makes sense for a freely standing model, but probably not for a model holding on to a wheel. A more reasonable way to do it would be to control the distance between the thorax and the wheel hub. Let us initially remove the Center of Mass driver that is responsible for the balancing condition. This takes place in the JointAndDrivers.any file:

//Constrain the collective CoM to be right above the GlobalRef
//  AnyKinEqSimpleDriver CoMDriver = {
//    AnyKinCoM CoM = {
//      AnyFolder &Body = Main.Model.HumanModel;
//    };
//    MeasureOrganizer = {0,2};  // Only the x and z directions
//    DriverPos = {0,0};
//    DriverVel = {0,0};
//    Reaction.Type = {Off,Off};
//  };

This driver we replace by another driver that controls the two horizontal positions of the thorax with respect to the wheel hub. As you can see, this is pretty much a copy of the CoM driver that we just removed with the exception of the changed measure inside the driver. You can use the tree view to insert the long references to the wheel hub node and the thorax segment.

//Constrain thorax with respect to the wheel hub
AnyKinEqSimpleDriver WheelThorax = {
  AnyKinLinear Lin = {
    AnyRefFrame &Hub = Main.Model.EnvironmentModel.GlobalRef.Hub;
    AnyRefFrame &Thorax = Main.Model.HumanModel.Trunk.SegmentsThorax.ThoraxSeg;
  };
  MeasureOrganizer = {0,2};  // Only the x and z directions
  DriverPos = {-0.4, 0};
  DriverVel = {0,0};
  Reaction.Type = {Off,Off};
};

The DriverPos specification in this driver allows you to control how far the body should be from the wheel. Obvously the body cannot be so close that it touches the wheel and it cannot be so far away that it cannot reach the handles. The value of -0.4 will make the body roughly vertical. If you load the model and run the kinematic analysis, you will see the result. Try experimenting a bit with the distance if you like.

Closer investigation will reveal that the forearm pronation is a bit unrealistic for a hand wheel.

The simple way to remedy this situation is to change the forearm pronation in the mannequin.any file:

AnyFolder Right = {
  //Arm
  AnyVar SternoClavicularProtraction=-23;   //This value is not used for initial position
  AnyVar SternoClavicularElevation=11.5;    //This value is not used for initial position
  AnyVar SternoClavicularAxialRotation=-20; //This value is not used for initial position

  AnyVar GlenohumeralFlexion = 50;
  AnyVar GlenohumeralAbduction = 0;
  AnyVar GlenohumeralExternalRotation = 0;

  AnyVar ElbowFlexion = 40.0;
  AnyVar ElbowPronation = 50.0;

Finally, to not have too large time steps, let us define a slightly higher resolution in the AnyBodyStudy in the main file:

AnyBodyStudy Study = {
  AnyFolder &Model = .Model;
  RecruitmentSolver = MinMaxNRSimplex;
  tEnd = 2.0;
  Gravity = {0.001, -9.81, 0.001};
  nStep = 20;
  MuscleEliminationTol = 1e-7;
}; // End of study

With this completed, we are ready to attempt an inverse dynamic analysis. For this we need muscles in the model, so we switch the muscles back in by changing two lines in the main file:

AnyFolder HumanModel={

  //This model should be used when playing around with the model in the
  //initial modelling phase since leaving the normal muscles out, makes the
  //model run much faster. The model uses artificial muscles on each dof. in
  //the joints which makes it possible also to run the inverse analysis.
  //#include  "../../../BRep/Aalborg/BodyModels/FullBodyModel/BodyModel_NoMuscles.any"

  //This model uses the simple constant force muscles
  #include  "../../../BRep/Aalborg/BodyModels/FullBodyModel/BodyModel.any"

This type of loading of the model causes a torsional moment along the length axis of the body because one hand is pushing on the pedal while the other is pulling. This turns out to make it difficult for the fully extended knees as they are in the current model to carry the load, so it is advisable to flex the knees slightly by the knee flexion setting in the mannequin file:

AnyVar KneeFlexion = 5.0;


With these changes performed, please click the InverseDynamicAnalysis operation in the study tree and hit the run button. You should see the model turning the wheel against the imposed crank torque. Please beware that with more than 500 muscles in the model each step takes a considerable time.

That is pretty much all there is to it. You should now be able to load the model and run the InverseDynamicAnalysis to investigate the muscle actions, joint forces and so on.

Here's a set of files that work in case the model is giving you trouble: HandPump.4.zip.

Modifications like these from an existing application to a new one probably accounts for 90% of the model development of AnyBody users. However, in some cases it is not possible to find a good existing application, and it can be advantageous to build your own model from the body parts in the repository.

The next lessons, starting with Lesson 5, deal with such a case.

AnyBody Technology A/S · Niels Jernes Vej 10 · DK-9220 Aalborg Ø · Denmark · Tel. +45 9635 4286 · Fax. +45 9635 4599
Copyright (c) AnyBody Technology A/S · 2006 · All rights reserved · Email webmaster@anybodytech.com