Hello everyone,
I am currently working on a prototype model in AnyScript where I modified the knee joint by adding 2 additional degrees of freedom (DOFs). I am using Force-Dependent Kinematics (FDK) to solve for the joint kinematics.I've run into an issue regarding the spring force sign convention. Here is what I am observing. with negative spring force,the tibia moves in the anterior direction during gait.with positive spring force, the tibia moves in the posterior direction.
My Confusion is based on standard mechanics, a spring force should act against the displacement/motion. However, making the force positive moves the tibia posteriorly.Tibia should move in posterior direction but, force sign confused me. Could someone clarify how Anybody's FDK handles spring force signs and coordinate directions in custom DOFs? Am I defining the spring incorrectly, or is this behavior tied to the local coordinate system orientation of the joint?
relevant code :
/*
AP + SI FDK feasibility test for the RIGHT knee in an AnyMoCap study.
Requirements:
- The active Jnt.any contains APDifference, APTranslation,
SIDifference, SITranslation, APCoupling, and SICoupling. - Keep the working APScale = 0 in the active joint file.
In the trial's Main.any, place this immediately AFTER:
#include "<ANYMOCAP_MODEL>"
by adding:
#include "KneeAP_FDK_StudyOverlay.any"
This is a numerical spring test, not a validated ligament or knee contact
model. Do not copy the spring stiffness into a physiological model.
*/
// The included file is parsed at the top level: reopen Main first.
Main = {
Studies.InverseDynamicStudy = {
// Release right-knee AP and SI only in inverse dynamics. MarkerTracking
// and the left knee retain their existing hard constraints.
AnyMechObjectExcluder ExcludeRightAPCoupling = {
Objects = ObjSearch(
"Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.APCoupling",
"AnyKinEq"
);
};
AnyMechObjectExcluder ExcludeRightSICoupling = {
Objects = ObjSearch(
"Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.SICoupling",
"AnyKinEq"
);
};
ModelEnvironmentConnection = {
// APDifference = actual AP - APScale * prescribedAP(flexion).
// DriverPos is an initial estimate for the force-dependent coordinate.
AnyKinEqSimpleDriver RightAPFDK = {
AnyKinMeasure &APDifference =
Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.APDifference;
DriverPos = {0};
DriverVel = {0};
CType = {ForceDep};
Reaction.Type = {Off};
};
// Keep the user's working AP spring, including its force sign.
AnyForce RightAPDiagnosticSpring = {
AnyKinMeasure &APTranslation =
Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.APTranslation;
AnyFloat Stiffness = DesignVar(2e5); // N/m
F = {-Stiffness * APTranslation.Pos[0]};
};
// Force-dependent SI coordinate and an independently adjustable
// // SI spring with its rest position at zero. y is in the thigh frame.
AnyKinEqSimpleDriver RightSIFDK = {
AnyKinMeasure &SIDifference =
Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.SIDifference;
DriverPos = {0};
DriverVel = {0};
CType = {ForceDep};
Reaction.Type = {Off};
};
AnyForce RightSIDiagnosticSpring = {
AnyKinMeasure &SITranslation =
Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.SITranslation;
AnyFloat Stiffness = DesignVar(9e4); // N/m; tune separately from AP
F = {-Stiffness * SITranslation.Pos[0]};
};
// Optional probe: run once at 0 N and again at +50 N to check that
// the AP position responds to a known load. Remove after the test.
// AnyForce RightAPProbe = {
// AnyKinMeasure &APTranslation =
// Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.APTranslation;
// AnyFloat ProbeLoad = 0; // N; try 50 for a second diagnostic run
// F = {ProbeLoad};
// };
};
InverseDynamics.ForceDepKinOnOff = On;
};
};