Page 1 of 2

Maximize Velocity of a Body Segment

Posted: Tue Jan 04, 2022 3:49 pm
by tnt845
Hi everyone,

I would like to use Moco to maximize the velocity of a certain body segment using MocoOutputGoal.

I am currently adding this as a goal to a tracking simulation with the following lines of code:

Code: Select all

study = track.initialize()
problem = study.updProblem()

bodySet = model.getBodySet()
hand = bodySet.get('hand_r')
hand_vel = hand.getOutput('velocity')
outputGoal = osim.MocoOutputGoal("hand_vel",1)
outputGoal.setOutputPath(hand_vel.getPathName())
problem.addGoal(outputGoal)

solution = study.solve()
     
When I run it I get an error message saying:
"RuntimeError: std::exception in 'OpenSim::MocoSolution OpenSim::MocoStudy::solve() const': Bad dynamic_cast!"

However, if I do not add the MocoOutputGoal it runs just fine.

Any suggestions for how to fix this?

In addition, is it possible to specify a direction of velocity to maximize (i.e. the x component)?

Thanks!

Ty

Re: Maximize Velocity of a Body Segment

Posted: Wed Jan 05, 2022 2:36 am
by pvb
Hi Tylan,

About your error: MocoOutputGoal accepts a scalar (or double) output, which means that it doesn't accept outputs which are represented as vectors. Body inherits its outputs (including velocity) from Frame, where you can see that Velocity is output as a SpatialVec (two 3-element vectors representing angular and linear velocity). I don't think using non-scalar outputs as goals is currently supported.
Cheers,
Pasha

Re: Maximize Velocity of a Body Segment

Posted: Wed Jan 05, 2022 5:10 am
by rosshm
Hi Tylan,

Even if you manage to get this working (I think Pasha is correct concerning SpatialVec), I think MocoOutputGoal attempts to minimize (not maximize) the specified quantity.

It doesn't square the output or anything like that, so you could maybe trick Moco into maximization by setting up the problem such that a "good" solution has velocities in the negative direction.

Alternatively, setting the problem up as a tracking problem with an impossibly-fast target velocity may work.

I haven't tried either of those things, just speculating!

Ross

Re: Maximize Velocity of a Body Segment

Posted: Sun Jan 09, 2022 3:43 pm
by aafox
Hi Tylan,

Just to add a basic point on top of what Ross mentions, it's been Mentioned by Nick/Chris that giving a goal that minimises a negative weight will result it in maximising the property - which might help in this situation.

Aaron

Re: Maximize Velocity of a Body Segment

Posted: Mon Jan 10, 2022 12:09 pm
by nbianco
Setting a negative weight should work, but I actually like Ross' suggesting to using a tracking goal with a very large reference velocity. I have a hunch this might work well.

Re: Maximize Velocity of a Body Segment

Posted: Mon Jan 10, 2022 1:19 pm
by tnt845
Thank you for the helpful suggestions! I have a couple of follow up questions:

1. Thank you Pasha for pointing me to the outputs of Frame. I am now using 'linear_velocity' which is a Vec3 instead of a SpatialVec. This still doesn't eliminate the problem of being a non-scalar, but does get one step closer. Is there a way to select a specific component of the Output (i.e. the 'X' component) and then negate that value as a workaround for maximization? I have tried:

Code: Select all

hand_vel = hand.getOutput('linear_velocity')
hand_vel_x_neg = hand_vel.get(0)*-1
But get an error "AttributeError: 'AbstractOutput' object has no attribute 'get' "

2. With the alternative approach, I am unsure how to setup the tracking goal to have an excessively large hand velocity. I know you can set the end state of a particular degree of freedom in the model using something like:

Code: Select all

problem.setStateInfo('/jointset/hand_r/wrist_flex_r/speed', [0, 10000], 0 , 10000)

But that would only "maximize" wrist flexion speed not necessarily the linear velocity of the hand. Can you do something similar with a body rather than a joint? Any other thoughts or suggestions for how to approach the problem?

Thanks again!

Ty

Re: Maximize Velocity of a Body Segment

Posted: Tue Jan 11, 2022 12:04 pm
by nbianco
Hi Tylan,

With the current implementation of MocoOutputGoal, you won't be able to minimize/maximum the 'linear_velocity' output since, as you've noted, it's a Vec3 type. We're hoping to add support for Vector types soon.

The setStateInfo() interface can only set bounds and boundary constraints, so if the model can't reach that max speed, the problem will fail. Rather, you can use MocoStateTrackingGoal, and provide a trajectory with a constant, large speed across the entire time range for the coordinate you want to maximum speed for. You could also use MocoTranslationTrackingGoal to specify a Vec3 position trajectory for a body segment; since that requires position trajectory, to maximum speed, you would need to provide a position trajectory with a large slope with an intercept at the body's known initial position.

Re: Maximize Velocity of a Body Segment

Posted: Tue Jan 11, 2022 3:22 pm
by tnt845
Thanks Nick!

I believe I would need to use MocoTranslationTrackingGoal since I am trying to maximize the velocity of a body instead of a specific coordinate. However, it seems that to do so I would have to provide a guess for the trajectory for the entire motion. I would like to avoid this so I don't have to make any assumptions about the best way to achieve maximum velocity at the end of the movement. For example, a linear fit wouldn't really be ideal because it is possible that even negative velocities early in the motion would help produce maximum velocity at the end of the motion.

Is there any way in Moco to maximize the end velocity of a body segment? Or would I need a custom goal to do so?

Best,

Ty

Re: Maximize Velocity of a Body Segment

Posted: Thu Jan 13, 2022 3:35 pm
by nbianco
Hey Tylan,

Sorry, but I think that's the best option I can come up with for now. As you suggest, you would need a new goal to specifically minimize/maximum the final velocity of a body segment in the way you're looking for.

We're aiming for new updates to MocoOutputGoal and add new MocoGoals in the near future that could be more suited to what you're trying to do.

Best,
Nick

Re: Maximize Velocity of a Body Segment

Posted: Fri Mar 04, 2022 3:45 pm
by tnt845
Hi everyone,

I am now trying to write a custom goal for this objective and I have been able to do so by modifying the example in
"opensim-moco-0.4.0-win\Resources\Code\CPP\Plugins\exampleMocoCustomEffortGoal" with the help from this forum post: viewtopicPhpbb.php?f=1815&t=12844&p=0&s ... 4ba939e34c.

However, doing so maximizes the integral of the hand velocity over the entire motion. This is a good first step but my intention is to maximize the maximum hand velocity (which may not necessarily be at the end of the motion).

In the "MocoCustomEffortGoal.cpp" file lines 35-37 are:

Code: Select all

void MocoCustomEffortGoal::calcGoalImpl(
        const GoalInput& input, SimTK::Vector& cost) const {
    cost[0] = input.integral;
}
I would like be be able to do something along the lines of:

Code: Select all

void MocoCustomEffortGoal::calcGoalImpl(
        const GoalInput& input, SimTK::Vector& cost) const {
    //cost[0] = input.integral;
      cost[0] = input.max_element; //where this line returns the max element in the integrand rather than integrating it
}
This seems like it should be relatively straightforward but I am not entirely sure how to do it. Would appreciate any suggestions!

Thanks!

Ty