Implementation:ARISE Initiative Robosuite JointVelocityController
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Control |
| Last Updated | 2026-02-15 07:00 GMT |
Overview
Concrete tool for controlling robot arm joint velocities via PID control provided by robosuite.
Description
The JointVelocityController class implements velocity-level joint control using a PID controller. It extends the abstract Controller base class and computes joint torques that track desired joint velocity setpoints. The controller uses proportional (P), integral (I), and derivative (D) terms on the velocity error to compute the required torques, with optional gravity compensation.
The PID gains are automatically derived from a single kp parameter. When kp is a scalar, it is scaled by the actuator range width for each joint to account for different joint torque capabilities. The integral gain ki is set to kp * 0.005 and the derivative gain kd is set to kp * 0.001. The controller includes anti-windup logic that freezes the integral accumulator when the output torques are saturated (clipped by actuator limits). A ring buffer is used to smooth the derivative term by averaging the last 5 error differences.
Input actions are interpreted as absolute desired joint velocities, scaled through the input/output range mapping, and optionally clipped to velocity limits. The final torques are clipped to actuator limits, and the controller tracks saturation state to enable the anti-windup mechanism.
Usage
Use the JointVelocityController when you need to command desired joint velocities rather than positions or torques. It is suitable for tasks requiring continuous motion control, teleoperation at the velocity level, or as a building block for higher-level controllers. Instantiate via the controller factory with the name "JOINT_VELOCITY".
Code Reference
Source Location
- Repository: ARISE_Initiative_Robosuite
- File: robosuite/controllers/parts/generic/joint_vel.py
- Lines: 1-223
Signature
class JointVelocityController(Controller):
def __init__(
self,
sim,
joint_indexes,
actuator_range,
ref_name=None,
input_max=1,
input_min=-1,
output_max=1,
output_min=-1,
kp=0.25,
policy_freq=20,
lite_physics=True,
velocity_limits=None,
interpolator=None,
**kwargs,
): ...
def set_goal(self, velocities): ...
def run_controller(self) -> np.array: ...
def reset_goal(self): ...
@property
def name(self) -> str: ... # Returns "JOINT_VELOCITY"
Import
from robosuite.controllers.parts.generic.joint_vel import JointVelocityController
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| sim | MjSim | Yes | MuJoCo simulator instance for reading robot state |
| joint_indexes | dict | Yes | Dictionary with keys 'joints', 'qpos', 'qvel' containing index lists
|
| actuator_range | 2-tuple of array | Yes | (low, high) actuator torque limits |
| ref_name | str | No | End effector reference site name (optional) |
| input_max | float or list | No | Maximum input action clipping value (default: 1) |
| input_min | float or list | No | Minimum input action clipping value (default: -1) |
| output_max | float or list | No | Maximum scaled output velocity (default: 1) |
| output_min | float or list | No | Minimum scaled output velocity (default: -1) |
| kp | float or list | No | Proportional velocity gain (default: 0.25). Scaled by actuator range if scalar |
| policy_freq | int | No | Policy action frequency in Hz (default: 20) |
| lite_physics | bool | No | Whether to optimize MuJoCo forward calls (default: True) |
| velocity_limits | 2-list or None | No | Joint velocity limits for goal clipping |
| interpolator | Interpolator | No | Interpolator for smooth velocity goal transitions |
Outputs
| Name | Type | Description |
|---|---|---|
| torques | np.array | Clipped joint torques from PID velocity control plus optional gravity compensation |
| current_vel | np.array | Current velocity setpoint (interpolated or direct goal) |
| goal_vel | np.array | Desired velocity goal after scaling and clipping |
| name | str | Controller identifier: "JOINT_VELOCITY"
|
Usage Examples
# Typical usage via the controller factory
from robosuite.controllers.parts.controller_factory import arm_controller_factory
import numpy as np
controller_params = {
"sim": sim,
"joint_indexes": {
"joints": [0, 1, 2, 3, 4, 5, 6],
"qpos": [0, 1, 2, 3, 4, 5, 6],
"qvel": [0, 1, 2, 3, 4, 5, 6],
},
"actuator_range": (np.array([-87]*7), np.array([87]*7)),
"policy_freq": 20,
"ndim": 7,
"interpolation": None,
"ramp_ratio": 0.2,
}
controller = arm_controller_factory("JOINT_VELOCITY", controller_params)
# Command desired joint velocities
action = np.array([0.1, 0.0, 0.0, -0.05, 0.0, 0.0, 0.0])
controller.set_goal(action)
# Compute torques via PID control
torques = controller.run_controller()
# Reset to zero velocity
controller.reset_goal()