Webots Reference Manual - chapter 3 - section 42

Webots Reference Manual


3.42 Servo

Derived from Device.

Servo {
  SFString   type             "rotational"
  SFFloat    maxVelocity      10      # (0,inf)
  SFFloat    maxForce         10      # [0,inf)
  SFFloat    controlP         10      # (0,inf)
  SFFloat    acceleration     -1      # -1 or (0,inf)
  SFFloat    position         0
  SFFloat    minPosition      0       # (-inf,0]
  SFFloat    maxPosition      0       # [0,inf)
  SFFloat    minStop          0       # [-pi,0]
  SFFloat    maxStop          0       # [0,pi]
  SFFloat    springConstant   0       # [0,inf)
  SFFloat    dampingConstant  0       # [0,inf)
}

3.42.1 Description

A Servo node is used to add a joint (1 degree of freedom (DOF)) in a mechanical simulation. The joint can be active or passive; it is placed between the parent and children nodes (.wbt hierarchy) of the Servo and therefore it allows the children to move with respect to the parent. The Servo can be of type "rotational" or "linear". A "rotational" Servo is used to simulate a rotating motion, like an electric motor or a hinge. A "linear" Servo is used to simulate a sliding motion, like a linear motor, a piston, a hydraulic/pneumatic cylinder, a spring, or a damper.

3.42.2 Field Summary

3.42.3 Units

Rotational servos units are expressed in radians while linear servos units are expressed in meters. See table 3.5:

RotationalLinear
Positionrad (radians)m (meters)
Velocityrad/s (radians / second)m/s (meters / second)
Accelerationrad/s2 (radians / second2)m/s2 (meters / second2)
Torque/ForceN*m (Newtons * meters)N (Newtons)

Table 3.5: Servo Units

3.42.4 Initial Transformation and Position

The Servo node inherits the translation and rotation fields from the Transform node. These two fields represent the initial coordinate system transformation between the Servo parent and children.

In a "rotational" Servo, these fields have the following meaning: The translation field specifies the translation of the axis of rotation. The rotation field specifies the orientation of the axis of rotation. See figure 3.24.

rotational_servo

Figure 3.24: Rotational servo

In a "linear" Servo, these fields have the following meaning: The translation field specifies the translation of the sliding axis. The rotation field specifies the direction of the sliding axis. See figure 3.25.

linear_servo

Figure 3.25: Linear servo

The position field represents the current angle difference (in radians) or the current distance (in meters) with respect to the initial translation and rotation of the Servo. If position field is zero then the Servo is at its initial translation and rotation. For example if we have a "rotational" Servo and the value of the position field is 1.5708, this means that this Servo is 90 degrees from its initial rotation. The values passed to the wb_servo_set_position() function are specified with respect to the position zero. The values of the minPosition, maxPosition, minStop and maxStop fields are also defined with respect to the position zero.

3.42.5 Position Control

The standard way of operating a Servo is to control the position directly (position control). The user specifies a target position using the wb_servo_set_position() function, then the P-controller takes into account the desired velocity, acceleration and motor force in order to move the servo to the target position. See table 3.6.

In Webots, position control is carried out in three stages, as depicted in figure 3.26. The first stage is performed by the user-specified controller (1) that decides which position, velocity, acceleration and motor force must be used. The second stage is performed by the servo P-controller (2) that computes the current velocity of the servo Vc. Finally, the third stage (3) is carried out by the physics simulator (ODE joint motors).

servo_control

Figure 3.26: Servo control

At each simulation step, the P-controller (2) recomputes the current velocity Vc according to following algorithm:

Vc = P * (Pt - Pc);
if (abs(Vc) > Vd)
  Vc = sign(Vc) * Vd;
if (A != -1) {
  a = (Vc - Vp) / ts;
  if (abs(a) > A)
    a = sign(a) * A;
  Vc = Vp + a * ts;
}

where Vc is the current servo velocity in rad/s or m/s, P is the P-control parameter specified in controlP field or set with wb_servo_set_control_p(), Pt is the target position of the servo set by the function wb_servo_set_position(), Pc is the current servo position as reflected by the position field, Vd is the desired velocity as specified by the maxVelocity field (default) or set with wb_servo_set_velocity(), a is the acceleration required to reach Vc in one time step, Vp is the motor velocity of the previous time step, ts is the duration of the simulation time step as specified by the basicTimeStep field of the WorldInfo node (converted in seconds), and A is the acceleration of the servo motor as specified by the acceleration field (default) or set with wb_servo_set_acceleration().

3.42.6 Velocity Control

The servos can also be used with velocity control instead of position control. This is obtained with two function calls: first the wb_servo_set_position() function must be called with INFINITY as a position parameter, then the desired velocity, which may be positive or negative, must be specified by calling the wb_servo_set_velocity() function. This will initiate a continuous servo motion at the desired speed, while taking into account the specified acceleration and motor force. Example:

wb_servo_set_position(servo, INFINITY);
wb_servo_set_velocity(servo, 6.28);  // 1 rotation per second

INFINITY is a C macro corresponding to the IEEE 754 floating point standard. It is implemented in the C99 specifications as well as in C++. In Java, this value is defined as Double.POSITIVE_INFINITY. In Python, you should use float('inf'). Finally, in Matlab you should use the inf constant.

3.42.7 Force Control

The position/velocity control described above are performed by the Webots P-controller and ODE's joint motor implementation (see ODE documentation). As an alternative, Webots does also allow the user to directly specify the amount of torque/force that must be applied by a Servo. This is achieved with the wb_servo_set_force() function which specifies the desired amount of torque/forces and switches off the P-controller and motor force. A subsequent call to wb_servo_set_position() restores the original position control. Some care must be taken when using force control. Indeed the torque/force specified with wb_servo_set_force() is applied to the Servo continuously. Hence the Servo will infinitely accelerate its rotational or linear motion and eventually explode unless a functional force control algorithm is used.

position controlvelocity controlforce control
uses P-controlleryesyesno
wb_servo_set_position()* specifies the desired positionshould be set to INFINITYswitches to position/velocity control
wb_servo_set_velocity()specifies the max velocity* specifies the desired velocityis ignored
wb_servo_set_acceleration()specifies the max accelerationspecifies the max accelerationis ignored
wb_servo_set_motor_force()specifies the available forcespecifies the available forcespecifies the max force
wb_servo_set_force()switches to force controlswitches to force control* specifies the desired force

Table 3.6: Servo Control Summary

3.42.8 Servo Limits

The position field is a scalar value that represents the current servo "rotational" or "linear" position. For a rotational servo, position represents the difference (in radians) between the initial and the current angle of its rotation field. For a linear servo, position represents the distance (in meters) between the servo's initial and current translation (translation field).

The minPosition and maxPosition fields define the soft limits of the servo. Soft limits specify the software boundaries beyond which the P-controller will not attempt to move. If the controller calls wb_servo_set_position() with a target position that exceeds the soft limits, the desired target position will be clipped in order to fit into the soft limit range. Since the initial position of the servo is always zero, minPosition must always be negative or zero, and maxPosition must always be positive or zero. When both minPosition and maxPosition are zero (the default), the soft limits are deactivated. Note that the soft limits can be overstepped when an external force which exceeds the motor force is applied to the servo. For example, it is possible that the weight of a robot exceeds the motor force that is required to hold it up.

The minStop and maxStop fields define the hard limits of the servo. Hard limits represent physical (or mechanical) bounds that cannot be overrun by any force. Hard limits can be used, for example, to simulate both end caps of a hydraulic or pneumatic piston or to restrict the range of rotation of a hinge. The value of minStop must be in the range [-π, 0] and maxStop must be in the range [0, π]. When both minStop and maxStop are zero (the default), the hard limits are deactivated. The servo hard limits use ODE joint stops (for more information see the ODE documentation on dParamLoStop and dParamHiStop).

Finally, note that when both soft and hard limits are activated, the range of the soft limits must be included in the range of the hard limits, such that minStop <= minValue and maxStop>= maxValue.

3.42.9 Springs and Dampers

The springConstant field specifies the value of the spring constant (or spring stiffness), usually denoted as K. The springConstant must be positive or zero. If the springConstant is zero (the default), no spring torque/force will be applied to the servo. If the springConstant is greater than zero, then a spring force will be computed and applied to the servo in addition to the other forces (i.e., motor force, damping force). The spring force is calculated according to Hooke's law: F = -Kx, where K is the springConstant and x is the current servo position as represented by the position field. Therefore, the spring force is computed so as to be proportional to the current servo position, and to move the servo back to its initial position. When designing a robot model that uses springs, it is important to remember that the spring's resting position for each servo will correspond to the initial position of the servo.

The dampingConstant field specifies the value of the servo damping constant. The value of dampingConstant must be positive or zero. If dampingConstant is zero (the default), no damping torque/force will be added to the servo. If dampingConstant is greater than zero, a damping torque/force will be applied to the servo in addition to the other forces (i.e., motor force, spring force). This damping torque/force is proportional to the effective servo velocity: F = -Bv, where B is the damping constant, and v = dx/dt is the effective servo velocity computed by the physics simulator.

servo_mechanics

Figure 3.27: Mechanical Diagram of a Servo

As you can see in (see figure 3.27), a Servo creates a joint between two masses m0 and m1. m0 is defined by the Physics node in the parent of the Servo. The mass m1 is defined by the Physics node of the Servo. The value x0 corresponds to the initial translation of the Servo defined by the translation field. The position x corresponds to the current position of the Servo defined by the position field.

3.42.10 Servo Forces

Altogether, three different forces can be applied to a Servo: the motor force, the spring force and the damping force. These three forces are applied in parallel and can be switched on and off independently (by default only the motor force is on). For example, to turn off the motor force and obtain a passive Servo, you can set the maxForce field to zero.

Forcemotor forcespring forcedamping force
Turned on when:maxForce > 0springConstant > 0dampingConstant > 0
Turned off when:maxForce = 0springConstant = 0dampingConstant = 0
regular motor (the default)onoffoff
regular spring & damperoffonon
damper (without spring)offoffon
motor with frictiononoffon
spring without any frictionoffonoff

Table 3.7: Servo Forces

To obtain a spring & damper element, you can set maxForce to zero and springConstant and dampingConstant to non-zero values. A pure spring is obtained when both maxForce and dampingConstant but not springConstant are set to zero. However in this case the spring may oscillate forever because Webots will not simulate the air friction. So it is usually wise to associate some damping to every spring.

3.42.11 Serial Servos

Each instance of a Servo simulates a mechanical system with optional motor, spring and damping elements, mounted in parallel. Sometimes it is necessary to have such elements mounted serially. With Webot, serially mounted elements must be modeled by having Servo nodes used as children of other Servo nodes. For example if you wish to have a system where a motor controls the resting position of a spring, then you will need two Servo nodes, as depicted in figure 3.28. In this example, the parent Servo will have a motor force (maxForce > 0) and the child Servo will have spring and damping forces (springConstant > 0 and dampingConstant > 0).

servo_serial

Figure 3.28: Example of serial connection of two Servo nodes

This is equivalent to this .wbt code, where, as you can notice, Servo2 is a child of Servo1:

DEF Servo1 Servo {
  ...
  children [
    DEF Servo2 Servo {
      ...
      children [
        ...
      ]
      boundingObject ...
      physics Physics {
        mass {m2}
      }
      maxForce 0
      springConstant {K}
      dampingConstant {B}
    }
  ]
  boundingObject ...
  physics Physics {
    mass {m1}
  }
  maxForce {M}
  springConstant 0
  dampingConstant 0
}

Note that it is necessary to specify the Physics and the boundingObject of Servo1. This adds the extra body m1 in the simulation, between the motor and the spring and damper.

3.42.12 Simulating Overlayed Joint Axes

Sometimes it is necessary to simulate a joint with two or three independent but overlayed rotation axes (e.g., a shoulder joint with a pitch axis and a roll axis). As usually with Webots, each axis must be implemented as a separate Servo node. So for two axes you need two Servo nodes, for three axes you need three Servo nodes, etc.

With overlayed axes (or very close axes) the mass and the shape of the body located between these axes is often unknown or negligible. However, Webots requires all the intermediate boundingObject and physics fields to be defined. So the trick is to use dummy values for these fields. Usually the dummy boundingObject can be specified as a Sphere with a radius of 1 millimeter. A Sphere is the preferred choice because this is the cheapest shape for the collision detection. And the physics field can use a Physics node with default values.

This is better explained with an example. Let's assume that we want to build a pan/tilt robot head. For this we need two independent (and perpendicular) rotation axes: pan and tilt. Now let's assume that these axes cross each other but we don't know anything about the shape and the mass of the body that links the two axes. Then this can be modeled like this:

DEF PAN Servo {
  ...
  children [
    DEF TILT Servo {
      translation 0 0 0  # overlayed
      children [
        DEF HEAD_TRANS Transform {
          # head shape
        }
        # head devices
      ]
      boundingObject USE HEAD_TRANS
      physics Physics {
      }
    }
  ]
  boundingObject DEF DUMMY_BO Sphere {
    radius 0.001
  }
  physics DEF DUMMY_PHYSICS Physics {
  }
}

Please note the dummy Physics and the 1 millimeter Sphere as dummy boundingObject.

3.42.13 Servo Functions



NAME

   wb_servo_set_position, wb_servo_set_velocity, wb_servo_set_acceleration, wb_servo_set_motor_force, wb_servo_set_control_p - change the parameters of the P-controller

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/servo.h>

  void wb_servo_set_position(WbDeviceTag tag, double position);
  void wb_servo_set_velocity(WbDeviceTag tag, double velocity);
  void wb_servo_set_acceleration(WbDeviceTag tag, double acceleration);
  void wb_servo_set_motor_force(WbDeviceTag tag, double force);
  void wb_servo_set_control_p(WbDeviceTag tag, double p);

DESCRIPTION

The wb_servo_set_position() function specifies a new target position that the P-controller will attempt to reach using the current velocity, acceleration and motor torque/force parameters. This function returns immediately (asynchronous) while the actual motion is carried out in the background by Webots. The target position will be reached only if the physics simulation allows it, that means, if the specified motor force is sufficient and the motion is not blocked by obstacles, external forces or the servo's own spring force, etc. It is also possible to wait until the Servo reaches the target position (synchronous) like this:

language: C

void servo_set_position_sync(WbDeviceTag tag, double target, int delay) {
  const double DELTA = 0.001;  // max tolerated difference
  wb_servo_set_position(tag, target);
  wb_servo_enable_position(tag, TIME_STEP);
  double effective;  // effective position
  do {
    wb_robot_step(TIME_STEP);
    delay -= TIME_STEP;
    effective = wb_servo_get_position(tag);
  }
  while (fabs(target - effective) > DELTA && delay > 0);
  wb_servo_disable_position(tag);
}

The INFINITY (#include <math.h>) value can be used as the second argument to the wb_servo_set_position() function in order to enable an endless rotational (or linear) motion. The current values for velocity, acceleration and motor torque/force are taken into account. So for example, wb_servo_set_velocity() can be used for controlling the velocity of the endless rotation:

language: C

// velocity control
wb_servo_set_position(tag, INFINITY);
wb_servo_set_velocity(tag, desired_speed);  // rad/s

language: C++
In C++ use std::numeric_limits<double>::infinity() instead of INFINITY
language: Java
In Java use Double.POSITIVE_INFINITY instead of INFINITY
language: Python
In Python use float('+inf') instead of INFINITY
language: Matlab
In MATLAB use inf instead of INFINITY

The wb_servo_set_velocity() function specifies the velocity that servo should reach while moving to the target position. In other words, this means that the servo will accelerate (using the specified acceleration, see below) until the target velocity is reached. The velocity argument passed to this function cannot exceed the limit specified in the maxVelocity field.

The wb_servo_set_acceleration() function specifies the acceleration that the P-controller should use when trying to reach the specified velocity. Note that an infinite acceleration is obtained by passing -1 as the acc argument to this function.

The wb_servo_set_motor_force() function specifies the max torque/force that will be available to the motor to carry out the requested motion. The motor torque/force specified with this function cannot exceed the value specified in the maxForce field.

The wb_servo_set_control_p() function changes the value of the P parameter in the P-controller. P is a parameter used to compute the current servo velocity Vc from the current position Pc and target position Pt, such that Vc = P * (Pt - Pc). With a small P, a long time is needed to reach the target position, while too large a P can make the system unstable. The default value of P is specified by the controlP field of the corresponding Servo node.



NAME

   wb_servo_enable_position, wb_servo_disable_position, wb_servo_get_position_sampling_period, wb_servo_get_position - get the effective position of a servo

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/servo.h>

  void wb_servo_enable_position(WbDeviceTag tag, int ms);
  void wb_servo_disable_position(WbDeviceTag tag);
  int wb_servo_get_position_sampling_period(WbDeviceTag tag);
  double wb_servo_get_position(WbDeviceTag tag);

DESCRIPTION

The wb_servo_enable_position() function activates position measurements for the specified servo. A new position measurement will be performed each ms milliseconds; the result must be obtained with the wb_servo_get_position() function. The returned value corresponds to the most recent measurement of the servo position. The wb_servo_get_position() function measures the effective position of the servo which, under the effect of external forces, is usually different from the target position specified with wb_servo_set_position(). For a rotational servo, the returned value is expressed in radians, for a linear servo, the value is expressed in meters. The returned value is valid only if the corresponding measurement was previously enabled with wb_servo_enable_position().

The wb_servo_disable_position() function deactivates position measurements for the specified servo. After a call to wb_servo_disable_position(), wb_servo_get_position() will return undefined values.

The wb_servo_get_position_sampling_period() function returns the period given into the wb_servo_enable_position() function, or 0 if the device is disabled.



NAME

   wb_servo_enable_motor_force_feedback, wb_servo_get_motor_force_feedback, wb_servo_get_motor_force_feedback_sampling_period, wb_servo_disable_motor_force_feedback - get the motor force currently used by a servo

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/servo.h>

  void wb_servo_enable_motor_force_feedback(WbDeviceTag tag, int ms);
  void wb_servo_disable_motor_force_feedback(WbDeviceTag tag);
  int wb_servo_get_motor_force_feedback_sampling_period(WbDeviceTag tag);
  double wb_servo_get_motor_force_feedback(WbDeviceTag tag);

DESCRIPTION

The wb_servo_enable_motor_force_feedback() function activates torque/force feedback measurements for the specified servo. A new measurement will be performed each ms milliseconds; the result must be retrieved with the wb_servo_get_motor_force_feedback() function.

The wb_servo_get_motor_force_feedback() function returns the most recent motor force measurement. This function measures the amount of motor force that is currently being used by the servo in order to achieve the desired motion or hold the current position. For a "rotational" servo, the returned value is a torque [N*m]; for a "linear" servo, the value is a force [N]. The returned value is an approximation computed by the physics engine, and therefore it may be inaccurate. The returned value normally does not exceed the available motor force specified with wb_servo_set_motor_force() (the default being the value of the maxForce field). Note that this function measures the current motor force exclusively, all other external or internal forces that may apply to the servo are ignored. In particular, wb_servo_get_motor_force_feedback() does not measure:

The wb_servo_get_motor_force_feedback_sampling_period() function returns the period given into the wb_servo_enable_motor_force_feedback() function, or 0 if the device is disabled.

Note that this function applies only to physics-based simulation. Therefore, the physics and boundingObject fields of the Servo node must be defined for this function to work properly.

If wb_servo_get_motor_force_feedback() was not previously enabled, the return value is undefined.



NAME

   wb_servo_set_force - direct force control

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/servo.h>

  void wb_servo_set_force(WbDeviceTag tag, double force);

DESCRIPTION

As an alternative to the P-controller, the wb_servo_set_force() function allows the user to directly specify the amount of torque/force that must be applied by a servo. This function bypasses the P-controller and ODE joint motors; it adds the force to the physics simulation directly. This allows the user to design a custom controller, for example a PID controller. Note that when wb_servo_set_force() is invoked, this automatically resets the force previously added by the P-controller.

In a "rotational" servo, the force parameter specifies the amount of torque that will be applied around the servo rotation axis. In a "linear" servo, the parameter specifies the amount of force [N] that will be applied along the sliding axis. A positive torque/force will move the bodies in the positive direction, which corresponds to the direction of the servo when the position field increases. When invoking wb_servo_set_force(), the specified force parameter cannot exceed the current motor force of the servo (specified with wb_servo_set_motor_force() and defaulting to the value of the maxForce field).

Note that this function applies only to physics-based simulation. Therefore, the physics and boundingObject fields of the Servo node must be defined for this function to work properly.

It is also possible, for example, to use this function to implement springs or dampers with controllable properties. The example in projects/samples/howto/worlds/force_control.wbt demonstrates the usage of wb_servo_set_force() for creating a simple spring and damper system.

release 7.0.2
Copyright © 2012 Cyberbotics Ltd. All right reserved.