I am trying using MotionCap from Vicon C3D in AnyBody for an UpperLimb Model. My goal actually is to auto position and auto scale from the c3d data. Autoposition is working, I modified your AutoPelvPos function for my need, so it can function with different c3d files. My model have 4 markers on thorax, 3 on shoulder,
6 on humeral, 2 on elbow, 2 on ulna, 2 on radius, 2 on wrist, 3 on hand
Like in this topic UpperLimb MoCap I used softdrivers to run my models. And disabled the drivers for segments I have markers on.
// Softdrivers fuer Segmente (Pelvis, Kopf), die keine Marker besitzen
#define BM_MANNEQUIN_DRIVER_DEFAULT ON
// Oberarm
#define BM_MANNEQUIN_DRIVER_GLENOHUMERAL_ABDUCTION_RIGHT OFF
#define BM_MANNEQUIN_DRIVER_GLENOHUMERAL_FLEXION_RIGHT OFF
#define BM_MANNEQUIN_DRIVER_GLENOHUMERAL_EXTERNAL_ROTATION_RIGHT OFF
// Ellbogengelenk
#define BM_MANNEQUIN_DRIVER_ELBOW_FLEXION_RIGHT OFF
#define BM_MANNEQUIN_DRIVER_ELBOW_PRONATION_RIGHT OFF
// Handgelenk
#define BM_MANNEQUIN_DRIVER_WRIST_FLEXION_RIGHT OFF
#define BM_MANNEQUIN_DRIVER_WRIST_ABDUCTION_RIGHT OFF
#define BM_MANNEQUIN_DRIVER_HAND_RIGHT OFF
Its working but right now is that the pelvis and thorax are slightly rotating when i run analysis. It seems I am missing some drivers for that. I tried to fixed it to a ground point, but that would only worked with some of the c3d files.
For scaling I read your tutorial and it seems I cant use SCALING_XYZ because I don't have lower body (foot) and it have (in the new repository) dependency to scaling. I have the mass and height and the c3d markers. I use SCALING_LENGTHMASS instead.
I activated ConstructModelOnOff = On; to have the scaling with the c3d. If I change the mass it change the scaling too, but if I change the height nothing happens. Is it because I use SCALING_LENGTHMASS? Would you recommend another scaling system?
And I have another 2 questions:
Is it possible to create an IF-function to switch between left and right handed people with the same model? i have some c3d with right and with left handed persons. Or is it better to do 2 AnyBody models for left and right handed persons?
I read about using python with AnyBody. Is it possible to program an UI for loading the c3d model and giving out the diagrams for joint angle and show the model view too? I am not sure how good the framework from AnyBody for python is. It is just a thought myself.
I would like to upload my model, but it seems I can't because I am a new member.
As i understand the marker configuration you have no makers from thorax and below.
In this case please ensure that the PelvisPos XYZ PelvisRot XYZ are all off, but you already did this as far as i understand. Please also ensure that PelvisThorax DOF are ON.
I do not see why XYZ scaling should not work, but you will not be able to optimize trunkheight due to missing markers so this you have to disable in the labspecific.any file.
You can use define statements in such situation.
#define RightHanded
#ifdef RightHanded
//Define you right hand markers here
#endif
#ifdef LeftHanded
//Define you left hand markers here
#endif
The python hook can be used to send information to python from AnyBody and then receive the data again. So if you are missing mathematical functionality in the script you can use python as a function call, the ModelView can not be displayed in python. AnyBody will automatically ensure the functions is called when it is needed depending on the dependencies in the model.
The PelvisPos XYZ PelvisRot XYZ are all off. I am looking at the PelvisThorax DOF right now.
The lower body is already disabled. Luckily this is the easier part.
Scaling with XYZ is not working. I am getting the following Error:
ERROR(SCR.PRS9) : C:/U..s/b..b/D..s/A..x/A..d/Body/A..n/HumanModel.any(43) : Defined at : C:/U..s/b..b/D..s/A..x/A..d/Body/A..n/B..s/G..l/AnyMan.ClassTemplates.any(181) : 'Height' : Unresolved object
I looked at the Errors and it seems the defined part at AnyMan.ClassTemplates.any(181) was changed in the newer repositories. In the old repository AnyFloat DepthScale was definied as
So that i disabled lower body scaling with XYZ does not work anymore for me.
Right now I am trying the IF condition for left and right handed persons, but i am not sure how the trigger for the if condition should be. Because the markers for RIGHT side and LEFT side are named the same. They only change position. Only the thorax markers remain the same. I am trying right now to define the condition in dependency of my thorax markers. The markers are
Right Hand | CS_2 CS_3 | Left Hand
markers right | CS_1 CS_4 | marker left
and if the marker for example SA_2 on my should is near CS_2 then its right hand else its left hand. But I am not sure how to solve it in AnyBody. Here is my model from Google Drive. I hope it is understandable.
With TrialFileName = "C024_20200625_19"; the pelvis starts to rotate with the arm around step ~350. It seems I need more drivers to have my pelvis stops from rotating. I don't know why it happens in this c3d. In other c3d the pelvis moves only a little bit.
Just to be sure is my question understandable or should i rephrase it?
I could define with Vicon Nexus the "DominantHand" (right- or lefthanded). Is it possible to read it with an IF-function in AnyBodyTech and switch between my MarkerSets? Or should I create two modells and switch it with an other programm like Python? But second choice is possible but doesn't feel elegant.
I thought something about:
#define DominantHand
#ifdef DominantHand == 1
// define marker right arm
#endif
#ifdef DominanHand == 0
// define markers left arm
#endif
Edit: my pelvis is still rotating like in the reply above, I would appreciate any tipps
Best Regards
I am very sorry for the slow response somehow this tread was overlooked.
I will try answer your questions one by one.
DominantHand:
Concerning the switch you can do it more or less like you suggest so :
Main ={
#ifndef
#define DominantHand "R"
#endif
#if DominantHand == "R"
// define marker right arm
#endif
#if DominantHand == "L"
// define markers left arm
#endif
};
In this code dominant hand can optionally be set from somewhere else e.g. if the model is loaded in console application the "DominantHand" can be part of the load and in this way controlled from outside, without changing the model.
Pelvis rotation:
The rotations must be caused by the four marker cluster on thorax.. please try to review the movement of these markers... with the drivers you have the spine will be stiff.
ScalingXYZ:
In the AnyMan.any file please ensure the Height variable is defined, i think the error indicates that could be missing.
Thank you for your reply. Just to be sure: I can define in BodyModelConfig.any in Main following
Main = {
#ifndef DominantHand
#define DominantHand "Main.ModelSetup.C3DFileData.Groups.PROCESSING.DominantHand.Data"
#endif
// RightHand = 1.0 / LeftHand = 0.0
#if DominantHand == "1.0"
#define BM_ARM_RIGHT ON
#define BM_ARM_LEFT OFF
#endif
#if DominantHand == "0.0"
#define BM_ARM_LEFT ON
#define BM_ARM_RIGHT OFF
#endif
#define BM_SCALING _SCALING_LENGTHMASS_
#define BM_TRUNK_RHYTHM ON
#define BM_LEG_LEFT OFF
#define BM_LEG_RIGHT OFF
};
Because if I try it, it sets on default mode and enable both arms. I tried it without quotation marks because I thought it is a float data type like in the description:
#ifndef DominantHand
#define DominantHand Main.ModelSetup.C3DFileData.Groups.PROCESSING.DominantHand.Data
#endif
// RightHand = 1.0 / LeftHand = 0.0
#if DominantHand == 1.0
#define BM_ARM_RIGHT ON
#define BM_ARM_LEFT OFF
#endif
#if DominantHand == 0.0
#define BM_ARM_LEFT ON
#define BM_ARM_RIGHT OFF
#endif
but after that I am getting an error: ERROR(SCR.SCN6) : C:/U..s/b..b/D..s/A..x/A..d/A..n/M..s/P..e/S..p/BodyModelConfig.any(19) : 'Main' : Unexpected character.
It seems I call a wrong value type.
will set DominantHand equal to "Main.ModelSetup.C3DFileData.Groups.PROCESSING.DominantHand.Data"
and not either 0 or 1.
It is not possible to read a number in the C3D file structure and set a define with this it would have to be through a define statement passed to a console application.
So in your code it simply never reads the sections switching in and out arms.
i could define everything with python and the modell is function.
I have still sometimes the problem with the rotation of pelvis. I know its because i am missing markers on pelvis but I am trying to freeze ThroaxSegment and PelvisSegment after AutoPosition it to my markers. It still not working 100%
I am not getting the last driver you have this could be in conflict with the pelvis/throrax + thorax/skull driver.
The LateralBendDriver sets the linear measure y direction to zero, but this is the y direction of the global ref system, since the "Ref" property in the AnyKinLinear object has not been set meaning it is "-1" so global y direction in this case.
As i see the markers and the code, you a four markers on the sternum this should be enough to drive thorax since the other two drivers will make the spine stiff, then you do not need the last driver it will only cause trouble,
// This is an etsimation of the upper body motion it will enforce that the head is kept above the pelvis medial/laterally
AnyKinEqSimpleDriver LateralBendDriver ={
AnyKinLinear lin ={
AnySeg &ref1= Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg;
AnySeg &ref2= Main.HumanModel.BodyModel.Trunk.SegmentsThorax.SkullSeg;
};
DriverPos={0};
DriverVel={0};
MeasureOrganizer={1};
};
The pelvis will start to tilt like in the picture below, that's why I am using this. Normally the person stands straight on the floor and is not moving its pelvis, only upper limb (arm, shoulders and hands) is moving. I am just trying to constraints the thorax and the pelvis in its position, so only the upper limb is moving after AutoPosition it. I wanted to ask if my solution is good or if there are more optimization I could use for it.
What about driving two rotations between pelvis and global so that the pelvis was always upright wrt to the floor but free to do axial rotations.
Then free up pelvic/thorax flexion + lat bend.
If you decide to keep the AnyKinLinear be careful , the model will behave differently if the subject is pointing in a different direction, because Ref=-1 (Global) in the linear measure.
Would it be possible to provide an example so I can use it in my model? I am happy that is is working right now and am afraid of getting new errors
Thank you in advance
AnyKinEqSimpleDriver LateralBendDriver ={
AnyKinLinear rot ={
AnyFixedRefFrame &ref0=Main.EnvironmentModel.GlobalRef ; //???reference my be incorrect
AnySeg &ref1= Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg;
TypeRotAxedAngles;
};
DriverPos={0.0,0}; //may need adjustments...
DriverVel={0,0};
MeasureOrganizer={1,2}; // drive y and x rotations leave z open (default rot sequence is zyx)
};
Keep the PelvisThoraxDriver