Repository navigation
Discrepancies between MATLAB and MuJoCo for second-order discrete controllers #3777
IntroHi! I am a graduate student at MIT, I use MuJoCo for my research on robotics. My setupI'm using MuJoCo 4.0 in python 3.15.2, on Ubuntu 22.04.5 LTS My questionI've been using MuJoCo to simulate a DC motor, and comparing the step response of various closed loop position controllers for it to the responses for the equivalent models in MATLAB. The responses match nearly identically for first order controllers, but whenever a second order controller is used, the step response in MuJoCo differs significantly from the MATLAB model, looking significantly more damped. Do you have any idea why this would be, and what I can change in my MuJoCo xml or script to better model these systems? Minimal model and/or code that explain my questionI'm modelling a DC motor with the parameters:
This matches the parameters used in this MATLAB tutorial In MATLAB, this motor is represented by the discrete transfer function: In MuJoCo, I'm using the following xml for the motor: DC motor XML<mujoco>
<option timestep="0.001" integrator="Euler"/>
<worldbody>
<body pos="0 0 0">
<joint name="motor_joint" pos="0 0 0" axis="0 1 0" frictionloss="3.51e-06"/>
<inertial pos="0.0 0.0 0.0" mass="1.00e-12" diaginertia="1.00e-12 1.00e-12 1.00e-12"/>
</body>
</worldbody>
<actuator>
<dcmotor name="motor" joint="motor_joint" resistance="4" inductance="0.00000275"
motorconst="0.0274" armature="0.00000322"/>
</actuator>
<sensor>
<jointpos name="motor_angle" joint="motor_joint" />
</sensor>
</mujoco>
My code for implementing discrete controllers is as follows, where the only change between controllers is the order constant and the difference equation used to update d.ctrl[0] Code: DC motor python simulation
import time
import math
import numpy as np
import mujoco
import mujoco.viewer
from collections import deque
m = mujoco.MjModel.from_xml_path('dc_motor_sim.xml')
d = mujoco.MjData(m)
es = deque()
us = deque()
order = 4
Ref = 1
for i in range(order+1):
es.append(0)
us.append(0)
with mujoco.viewer.launch_passive(m, d) as viewer:
while viewer.is_running() and d.time < 0.5:
step_start = time.time()
mujoco.mj_step(m,d)
p_angle = d.sensor('motor_angle').data.astype(float)[0]
e = Ref - p_angle
u = us[-1] + 0.5306*e - 0.5285*es[-1]
d.ctrl[0] = u
viewer.sync()
print(p_angle)
es.append(e)
us.append(u)
time_until_next_step = m.opt.timestep - (time.time() - step_start)
if time_until_next_step > 0:
time.sleep(time_until_next_step)The above code's difference equation implements the discrete controller: The MuJoCo and MATLAB step responses for the controller match closely, as seen below. This is the case for all first order controllers: But when a second order controller is implemented, such as: The MuJoCo response is markedly different from the MATLAB response, appearing much more damped (see below) Do you have any intuition as to why this behaviour occurs? Confirmations
|
Replies: 1 comment 3 replies
|
Hi @wjnorton, I ran your model with MuJoCo 4.0.0 and compared it against an exact ZOH discretization of the same motor (
So the slow, overdamped response is what this plant does with
Also, while I was at it, two things in the MuJoCo setup (neither explains the gap, both are tiny here):
mujoco.mj_step1(m, d) # positions, velocities, sensors for the current state
e = Ref - d.sensor('motor_angle').data[0]
d.ctrl[0] = ... # your difference equation
mujoco.mj_step2(m, d) # integrate with that controlWith 1 ms steps and this plant, both changes only move the third decimal: with Hope that helps! |



No worries! Found it. It's step 3: the coefficients you copied are the ones MATLAB prints, which are rounded to 4 significant digits. That matters a lot here, because the integral part of the controller is the tiny difference between those numbers.
For a backward-Euler PID over
z² - z, the exact numerator isThe coefficients sum to
Ki*Ts = 0.00175. That's the integral gain. The printed7.257 - 13.97 + 6.717sums to0.004, so the controller you ran in MuJoCo has more than twice the integral gain, and Kp/Kd are a bit off as well.I ran both through the exact discretized motor and through MuJoCo 4.0 with y…