More complex vector/matrix algebra in AnyScript

Hello,

I would like to create an orientation driver in AnyBody based on angular velocities. For this purpose I’m trying to write some quaternion algebra in AnyScript. However, unsurprisingly I run into some problems:

1\ The first problem I encounter is an element-wise multiplication of two equal length vectors to get a vector with the same length (in Matlab this would be: v3 = v1.*v2). I would think this should be possible, but I cant get it to work.

2\ Even if this is solved I think I will get more problems to apply the actual quaternion multiplications. A for-loop would help me a lot, but I cannot find this possibility in the reference manual. Is there any way I could use a for-loop?

3\ Another option would be a way to do the calculations externally each time (for example in Matlab) and import the results, but as the calculation is part of an optimization it should be done automatically. Is that an option?

Thank you for any help (and Merry Christmas).

Kind regards,

Bart Koning

I may have of solved it myself.

I put the construction of the driver in a separate AnyBody study, which solved point 1 and hopefully point 2 (not completely finished yet).

Now I still have to figure out if I can use the the result of calculations in one AnyBody study as kinematic input for a second and then use that second as ‘Analysis’-operation for the optimization study. It seems so if I use an operation sequence. I’ll get back to that when I succeed (or not).

Point 3 remains though, just for the future.

Kind regards,

Bart Koning

Hi Bart,
just a comment. You could run the AMS in batch mode called from Matlab. This would give you all the freedom in defining equations.
Best regards,
Sebastian

Hi Sebastian,

Thanks for your comment. Actually I have been using the AnyBody console version from Matlab already. However, as I want to use an optimization study with angular velocities as design variables I think I have to stick within AnyBody for all my calculations.

I’m almost there, though I wonder how ‘fast’ my solution will be in the end.

Hello,

I could use some help after all. The only thing I still need to work out (and I hope it’s possible at all) is to obtain the quaternion that I have calculated the previous time step. I’ve tried many things, but none worked so far:

1\ Using AnyVar, AnyOutputFun or just refer to the value at the previous time-step straight away (e.g Quaternion[iStep-1] ). Most of these ‘solutions’ end up in circular references or other errors.

2\ Storing the calculated value in a txt-file and read it. But it seems the file is only read once just before the simulations start.

3\ Define a separate study (Study 1) to perform the quaternion multiplication and call this study each time step from a second study (Study 2) and store the Quaternion value there. I succeeded somewhat at this last point, but only using a parameter study as Study 2 (with Analysis = Study1.Kinematics). But it’s slow and not working properly.


Now I’m trying use the calculated quaternions stored in an output function after all. Then in the next time step I refer to last calculated quaternion q[iStep-1], so I need an if statement to use the initial quaternion in the first time step (see below). However, for the if-function to work, ‘q1[0-1]’ needs to exist even though it will not be used, as in that case …t = min(…tArray)).

iffun(eqfun(…t,min(…tArray)),.InitialValues.q1_i,q1[iStep-1])

After solving this (see below), I get the all to familiar ‘circular dependence’ error during loading:

Code to prevent reference to q[-1]:
// Make sure ther is no reference to q[-1]
AnyInt iStep = iffun(eqfun(…t,min(…tArray)),…iStep,…iStep-1);
AnyFloat Test = .NextQ.Q1out()[iStep][0];
// Current quaternion seg 1 (initial value at 1st timestep)
AnyFloat q1_1 = iffun(eqfun(…t,min(…tArray)),.InitialValues.q1_i[0],Test);

Error:
ERROR(SCR.PRS7) : D:/AnyBody/P…m/OmegaDriven/TryIteration.any : ‘Test’ : Circular dependency in expression

Hope my attempts are clear ;). Is there any way to solve my problem within AnyBody (because I’m running out of ideas and really starting to thing it is not possible at all)?

Kind regards,

Hi Bart,

I am not sure it will be possible to run it within AMS with an approach where you base the previous time step on an analysis done in another study, if you want do this on a time-step to time-step basis without any reloads.

You will either end up with circular references or problems with evaluation moments.

I think there are two options:
[ol]
[li]Use an approach like in the GaitLoweExtremity models where one study drives the model with markers then save the resultant joint angles in a file. Then a second model drives the model using these angles… a load of the second model is needed.
[/li]
[li]Running it in Matlab or similar, then it can be done on a step by step basis.
[/li][/ol]

If i get an idea on how to do this in another way i will let you know, but right now these are the possibilities i see.

Merry Christmas

Best regards
Søren

“I am not sure it will be possible to run it within AMS with an approach where you base the previous time step on an analysis done in another study, if you want do this on a time-step to time-step basis without any reloads.”

This is not exactly what I would like to do. I just want to have an optimization study where the design variables are the input kinematics (like in the inverse-inverse approach). I already succeeded at this, by applying some weighted variation (of the same length) to the input orientations, create an Interpol function based on the sum of original values and variations to these values. This means that the whole driver input for the ‘MotionForParameterOptimization’ study is ‘recreated’ before it runs as part of the optimization study. Using the optimization study I then determine the optimal weight parameters for the variations.

However, I would rather vary the angular velocities and reconstruct the input orientations based on these ‘recreated’ angular velocities using the quaternion algebra. So the ‘MotionForParameterOptimization’ study input can be created before it runs, but it does mean I need a step-by-step construction of the orientations as each orientation can be calculated in two ways:

1\ Multiplication of the quaternion with the difference quaternion (based on the angular velocities) at each sample.
=> i.e. incremental change in orientation for each time sample

2\ Create a difference quaternion between the first and current orientation for each sample.
=> i.e. change in orientation with respect to the first sample for each time sample.

However, in both methods I need in some way to obtain the previous value of a quaternion (method 1: orientation quaternion, method 2: difference quaternion). But it is not strictly necessary for the calculations to be part of a study.

In Matlab I used a for-loop using method 1, but as there is no such thing in AMS (yet?) I tried to create an artificial for loop by defining a study solely for the construction of the input. This additional study only contains quaternion vectors and such and no model at all. But this is where I get into problems with the circular references.

Hope this sheds some light on what I’m trying to do. It would be nice if I can run it completely within AMS, but it seems I need to put the optimization in Matlab and only use AMS for the ‘MotionForParameterOptimization’ study (i.e. run the study and export the resulting objective function value to Matlab).

Thanks for the help and maybe we will find a solution within AMS after all.

Merry Christmas to you all as well!

Kind regards,

Bart

Hi Bart,

I have tried to create a small model which contains the following:

[ol]
[li]Small kinematic study
[/li][li]Parameter study which contains an output function which is calculated as a difference between position values of two time steps.
[/li][/ol]

Please run the MyStudy1.Kinematics operation and then the parameter study.

I hope this will help you move on, otherwise please describe which data you have as input to the model and what you are trying to obtain from the model, since i am not sure i have fully understood this yet.

Best regards
Søren

Hi Soren,

Thank you for your help, however it still doesn’t do the trick for me. I still cannot have an iterative procedure where the kinematics are ‘created’ during the simulation (they are predefined in MyStudy1).

The problem:
What I basically need is a way to construct a ‘segment orientation time interpolation function’ to be used as a kinematic driver, that is based on angular velocities. I usually do this by multiplying the global to local segment orientation matrix of a previous time stet (or quaternion in my case) with a rotation matrix (or quaternion) that is based on the angular velocities using a for-loop, i.e. R(t) = R(t-1)*dR(t-1,omega(t)). The problem I encounter within AMS is that there is no for-loop available and if I would create this using a Study, I get circular references; i.e. it does not (seem) to make the distinction between the rotation matrix of the current, R(t), and previous time step, R(t-1). To be fully clear, the angular velocities over time are defined beforehand using an interpolation function.

The final goal:
When I succeed in the creation of this ‘segment orientation time function’ based on angular velocities, I want to use it as the driver in a kinematic analysis. This kinematic analysis (with holonomic drivers, i.e. segment orientations) will be used in a parameter study, where the (non-holonomic) angular velocities will be the design variables.

I hope this is more clear than my previous explanations.

Kind regards,

Bart

Hi Bart,

I think it is not possible to do this for each step in an elegant way inside AMS, it may be possible to run a parameter study that would step through the timesteps, but for each step it would start with the initial pos again and then jump to the current timestep.

Even if you could calculate the orientation matrices I do not understand how you drive the model directly whit these since there is no measure in AMS that would allow you to drive this directly. The only way i can see it be done is to use the orientation matrix as an Axes value for a FixedRefFrame and then drive the rotaion between this an the seg to zero, but this would only be possible for one time step at the time.

Please describe the input you have to the model in more detail, since there might be entirely different ways to solve this.

I can think of the following solution:

[ol]
[li]Create a model with interpolation drivers for each joint angle
[/li][li]Create a number of control points to parametrize the motion
[/li][li]Setup an objective function that measures difference between the velocity you have measured and the velocity of the model
[/li][li] Create an optimization study in AMS that has control points as design variables and the objective function defined above as objective function.
[/li][/ol]

Best regards
Søren