How to set a periodically angular velocity for a bodyNode?

I wish to move a bodyNode rotates left to right and right to left periodically, which works like a fish moving its tail.

I wander if there’s any direct or convenient approach in dart to accomplish this goal .

Currently i just addForce on a BodyNode and set springstiffiness high. But it’s not so much perfectly periodic and will damp as time goes by.

Anybody has any good ideas?

Is the BodyNode attached to any other BodyNodes, or is it floating in free space?

If you’re trying to simulate a fish, then I would recommend having something like a revolute joint attaching the tail to the body and then command the joint to do a periodic motion instead of using BodyNode::addForce(~) to apply an external force.

1 Like

Yeah, i would like to know how to command the joint to do a periodic motion.
Would you please instruct me how to implement this ?

And i have a further question.
If i have two joints(BodyNodes) which form a bone (or a link). and i wish to add a force at certain position on the bone(or the link), what are the resulted forces on either joint(bodyNode) i should apply on?

You can simply do:

// During initialization:
auto* joint = skeleton->getJoint("joint_name");
joint->setActuator(dart::dynamics::Joint::SERVO);
// In your control loop:
double t = world->getTime();
joint->setCommand(0, compute_oscillation_velocity(t));

Where:

  • skeleton is a dart::dynamics::SkeletonPtr
  • "joint_name" is the name of the joint you care about
  • world is a dart::simulation::WorldPtr
  • compute_oscillation_velocity(double) is a function that takes in the current time and gives back what the velocity should be in order to create an oscillation

This will make the joint move at the desired speed while still being responsive to anything that it collides with.

yes, i check the setCommand function, it seems to just set one degree.
but velocity should be 3 dof,right? then shall we use setCommands?
Any further description or explanation on the function setCommand?

Joint::setCommand(std::size_t, double) is able to set a command for each degree of freedom of your joint. A revolute joint has only 1 degree of freedom. A ball joint has 3 degrees of freedom. A “free” joint has 6 degrees of freedom.

If you use the SERVO actuator mode on a Revolute joint, then the “command” is the desired angular velocity of the joint around its axis.

I assume the tail is attached to the body by a revolute joint, so my recommendation was to just set the 0th index to the velocity that you desire, because it wouldn’t have any other degrees of freedom to set. If you actually have a ball joint or some other joint type, then you may need to set commands for more of the degrees of freedom.

The Joint API always requires you to specify the degree of freedom index because DART doesn’t know ahead of time what actual joint type is being used.

Thank you greatly,grey!

grey, currently i face a situation.

I have some formula to calculate the force that fluid may apply to the tail joint (the force shall push the joint forward) , but if set the jointType to revolute, the force may not have any effect.

So i consider what if i use a ball joint ?

Another question is will the setCommand function cause the forces i wish to added have no effect on the joint since it directly enforce the velocity?That is , will setCommand prevent addExtForce to take effect?

The third question, how could i know each dof means for each different joint Type?

Thanks, grey

I can’t really answer all these questions for you since the question of how you apply DART to your specific application goes way beyond just basic help on how the DART API works. I’ll just summarize proper DART usage like this:

Bodies (BodyNode objects) are connected by joints (Joint objects). The Joint class is an abstract base class which is implemented by a variety of specific joint types. The specific joint type that you use to connect two bodies determines how those bodies are able to move relative to each other and what kind of forces they can exert on each other.

You can set joint commands using the Joint::setCommand(std::size_t, double) function. Each joint can take in a number of commands equal to the number of degrees of freedom that the joint allows. Joints also have an actuator mode which determines how the joint responds to the command that you give.

Joint force commands and/or joint velocity commands will determine how the bodies that are connected by that joint will move relative to each other. If you need to actuate some joint mechanism in your robot, like an elbow, to produce an internal force then you probably want to use a joint command.

For example, if you use the FORCE control actuator type with a command of zero, then the joint will be totally passive and freely move about its axis as external forces get applied to either of the bodies attached to it. If you use the SERVO control actuator type with a command of zero, then the joint will try to maintain its velocity at zero, and will remain stiff as external forces get applied to either of the bodies attached to it.

If there are supposed to be external forces acting on your robot, like fluid pressure forces, you can apply those to the bodies in your simulated robot using the BodyNode::addExtForce(~) function.

The third question, how could i know each dof means for each different joint Type?

By best suggestion right now is to look at the header for whatever joint type you’re interested in.

Thanks,grey.
Your explanation helps me figures some bugs in my code