How to make sRel of AnyRefNode to be time dependent

Hi, i have included a segment representing a bed and defined two AnyRefNode at the bed which acted as the bed contact points of the subjects. The position of these two AnyRefNode will change from time to time. I used AnyFunInterpol to interpolate the data of the positions from the .csv file first, and put in the sRel as shown:

AnySeg Bed={

      r0={ 0.5, 0.55, 2.38}; 
      Mass=0;
      Jii={0,0,0};

      
      AnyDrawSurf DrwBox = {
        
        FileName = "..\..\..\CAD-Files\box";
        RGB = {0,0,1};
        ScaleXYZ={4,0.27,2};
        Opacity =0.5;
        Face=-1;
      };
      
    
        AnyRefNode NodeLeft0={
        
        sRel={..ForceFun(Main.Studies.InverseDynamicStudy.t)[6],..ForceFun(Main.Studies.InverseDynamicStudy.t)[7], ..ForceFun(Main.Studies.InverseDynamicStudy.t)[8]};
        ARel=RotMat(pi,x);
        
        AnyDrawRefFrame drw={
          RGB={1,0,0};
          ScaleXYZ=0.2*{1,1,1};
        }; 
      };
      
      AnyRefNode NodeRight0={
        
        sRel={..ForceFun(Main.Studies.InverseDynamicStudy.t)[9],..ForceFun(Main.Studies.InverseDynamicStudy.t)[10], ..ForceFun(Main.Studies.InverseDynamicStudy.t)[11]};
        ARel=RotMat(pi,x);
        
        AnyDrawRefFrame drw={
          RGB={1,0,0};
          ScaleXYZ=0.2*{1,1,1};
        }; 
      };
    };

However, there is error as shown:

ERROR(SCR.EXP10) : BedReac.any(52) : 'NodeLeft0' : Expression evaluation failed at moment 'DesignVar' :
AnyMocapModel.any(60) : InverseDynamicStudy.t : argument will not be ready for evaluation until moment 'TimeVar'
Model loading skipped

May I know how to solve this issue ?

Hi,

AnyRefNode is a part of the rigid body assumption in the system. The nodes cannot float on the body. Hence, the name - rigid body dynamics. What you probably want is to create an extra segment, potentially massless, which will move wrt to the main segment. Make a segment, add relevant drivers.

Kind regards,
Pavel

Hi, thanks for the suggestions. I have created a segment named ContactLeftNode, then defined AnyKinLinear and AnyKinRotational to measure the relative distance between the frame of the segment and the global frame (act as constraints), and finally used AnyKinEqInterPolDriver. However, i found that the position of the segment is always constant (all the data follow the data in the first row in the CSV file). May I know why this happened?

Below are the details of the coding and the picture showing an overview of the environment model:

Main.EnvironmentModel ={
  AnyFolder modelbedReac={
    
    AnyInputFile readcsv = 
    {
      
      FileName = BedReac_DATA +"/"+ Main.ModelSetup.TrialSpecificData.TrialFileName + ".csv"; //add the extension to the file name here
      
    };
    
    
    
    AnyFloat LBedReacX= readcsv.Data[0];
    AnyFloat LBedReacY= readcsv.Data[1];
    AnyFloat LBedReacZ= readcsv.Data[2];
    AnyFloat RBedReacX= readcsv.Data[3];
    AnyFloat RBedReacY= readcsv.Data[4];
    AnyFloat RBedReacZ= readcsv.Data[5];
    AnyFloat Dx_global_Left= readcsv.Data[6];
    AnyFloat Dy_global_Left=readcsv.Data[7];
    AnyFloat Dz_global_Left=readcsv.Data[8];
    AnyFloat Rot1=readcsv.Data[9];
    AnyFloat Rot2=readcsv.Data[10];
    AnyFloat Rot3=readcsv.Data[11]; 
    AnyFloat time=readcsv.T;
    

    
    AnySeg Bed={
      
      r0={ 0.5, 0.55, 2.38}; 
      Mass=0;
      Jii={0,0,0};
      
      
      AnyDrawSurf DrwBox = {
        
        FileName = "..\..\..\CAD-Files\box";
        RGB = {0,0,1};
        ScaleXYZ={4,0.27,2};
        Opacity =0.5;
        Face=-1;
      };
      
      
    }; 
    
    AnyKinEqSimpleDriver beddriver={
      
      AnyKinLinear trans={
        
        AnyRefFrame &ref0= Main.EnvironmentModel.GlobalRef;
        AnyRefFrame &ref1= Main.EnvironmentModel.modelbedReac.Bed;
        
      };
      AnyKinRotational rot={
        
        AnyRefFrame &ref0= Main.EnvironmentModel.GlobalRef;
        AnyRefFrame &ref1= Main.EnvironmentModel.modelbedReac.Bed;
        Type=RotAxesAngles;
        
        
      };
      
      DriverPos={ 0.500, 0.55, 2.35,0,0,0};
      DriverVel={0,0,0,0,0,0};  
    };
    
    AnySeg ContactLeftNode = {
      Mass = 0;
      Jii = {0,0,0};
      r0={ 0.8, 0.55, 2.08};
      
    };
    
    AnyKinLinear Left_Trans={
      AnyRefFrame &ref0=Main.EnvironmentModel.GlobalRef;
      AnyRefFrame &ref1=Main.EnvironmentModel.modelbedReac.ContactLeftNode;
      Ref = 0; 
      
    };

    
    AnyKinRotational Left_Rot={
      
      AnyRefFrame &ref0=Main.EnvironmentModel.GlobalRef;
      AnyRefFrame &ref1=Main.EnvironmentModel.modelbedReac.ContactLeftNode;
      Type=RotAxesAngles;
    }; 

    
    AnyKinEqInterPolDriver Left_Motion = {
      AnyKinLinear &ref0=.Left_Trans;
      AnyKinRotational &ref1=.Left_Rot;
      Type = PiecewiseLinear;
      T = .time;
      Data = {.Dx_global_Left, .Dy_global_Left, .Dz_global_Left, .Rot1, .Rot2, .Rot3};
    };
    
    AnyFunInterpol ForceFun = {
      Data = {.LBedReacX,.LBedReacY,.LBedReacZ,.RBedReacX,.RBedReacY,.RBedReacZ};
      T = .time; 
      Type=PiecewiseLinear;
      
    };
    
    AnyForce3D LeftBedReac= {          
      AnyRefFrame &ref=Main.EnvironmentModel.modelbedReac.ContactLeftNode;  
      F={.ForceFun(Main.Studies.InverseDynamicStudy.t)[0],.ForceFun(Main.Studies.InverseDynamicStudy.t)[1], -.ForceFun(Main.Studies.InverseDynamicStudy.t)[2]};
      
      AnyDrawVector drF = {
        Vec = .RefFrameOutput.F[0]/100;   // Scale the length down
        Line = {
          Style = Line3DStyleFull;
          Thickness = 0.01;
          RGB = {1, 0, 0};
          End = {
            Style = Line3DCapStyleArrow;  // This specifies the end to be an arrowhead
            RGB = {1, 0, 0};
            Thickness = 0.02;  // The head begins with twice the thickness of the shaft
            Length = 0.05;
          };
        };
        // attach the arrow to the bed
        AnyRefFrame &bedpoint = Main.EnvironmentModel.modelbedReac.ContactLeftNode;
      };
    };
    

  }; 
  
  
  
};

Hi,

Is this block of code / folder included into the relevant study? I suspect it is not and this is why you don't see it working. Could you try including it directly into Main.Studies.InverseDynamicStudy?

Alternatively - could input be the problem? units? wrong values?

Kind regards,
Pavel

Hi Pavel,

I put the code in BedReac.any file, and then included it in the main script as shown below ( commented out line). To include this block of code into Main.Studies.InverseDynamicStudy, is it do as below? I tried this, and the same issue happened. :sweat_smile:

I think the input units and values should be no problem.

// ***************************** AnyMoCap ***********************************
#include "../../../libdef.any"
#path MOCAP_LAB_SPECIFIC_DATA "../../../LabSpecificData.any"
#path MOCAP_SUBJECT_SPECIFIC_DATA "../SubjectSpecificData.any"
#path MOCAP_TRIAL_SPECIFIC_DATA "TrialSpecificData.any"
#path FP_DATA "../../../FPCSV-files"
#path BedReac_DATA "../../../BedReac-files"
#include "<ANYMOCAP_MODEL>"

Main = {
// #include "BedReac.any"

   #include "../../../TextForcePlateData.any"
  
  Main.ModelSetup.BVHFileData.Model.GlobalRef.Origin= {-0.8,-0.04, -0.03};
  
  Main.EnvironmentModel.ForcePlates = {
   
    ForcePlateAutoDetection Plate1(
    PLATE_NO=1,
    LIMB1 = Main.HumanModel.BodyModel.Right.Leg.Seg.Foot,
    LIMB2 = Main.HumanModel.BodyModel.Left.Leg.Seg.Foot,
    HeightTolerance = 0.1,
    VelThreshold = 2.2,
    FORCEPLATE_TYPE = 2,
    ALLOW_MULTI_LIMB_CONTACT = ON         
    
    ) =   {};  
    
    ForcePlateAutoDetection Plate2(
    PLATE_NO=2,
    LIMB1 = Main.HumanModel.BodyModel.Right.Leg.Seg.Foot,
    LIMB2 = Main.HumanModel.BodyModel.Left.Leg.Seg.Foot,
    HeightTolerance = 0.1,
    VelThreshold = 2.2,
    FORCEPLATE_TYPE = 2,
    ALLOW_MULTI_LIMB_CONTACT = ON
    
    
    ) =   {};  
  };

Main.Studies.InverseDynamicStudy={
  
  AnyFolder modelbedReac={.........};
};
};

Yes, something like:

> Main = {...
>  Studies.InverseDynamicStudy = {
>   *// my code here*
>  };
> };

But by the looks of it - it should be included in your study. I would start debugging and looking at the actual values going into the analysis. Could it be that your CSV file contains an offset for the time values? This way you might get an extrapolation of the position, which may be a static value. What do your input arrays look like? What are the tStart, tEnd of the InverseDynamicStudy? Could you check them on loading?

P.

Hi Pavel,

I have checked the files and the number of frames in the BVH file is the same as the CSV file (the number of data read by the AnyBody for both files is also the same). [-->111 frames]. In the trial-specific data, FirstFrame=0 and LastFrame=110.

I also checked that the start time of inverse dynamics is 3 frames after the tStart of the trial-specific file, and the end time is 3 frames before the tEnd.:

 tStart = min({T_START+3*tFrame, T_END}); 
 tEnd = max({T_END-3*tFrame, tStart});
 nStep= max({N_STEP-6, 1});

Not sure whether this is the cause. However, I also tried to reduce 3 frames before and after the actual start and end frames, leaving 105 frames in the CSV file, but the issues remained. Is there any problem in coding which caused only reading a single row instead of the data array in the inverse dynamics?

The input array of CSV is as shown below:

In addition, i found that the Any3D force: F read from the same CSV file also faced the same issue.

Hi Pavel, i managed to solve the problem. :smiley:I changed the T inside AnyKinEqInterPolDriver and AnyFunInterpol to Main.Studies.InverseDynamicStudy.tArray instead of using .time .
Thanks for your guidance last few days!

So yes, it was the interpolation issue. The time of the study needs to be aligned with the data coming into the interpolation functions. Good to hear it is resolved.

Kind regards,
Pavel