Hi everyone,
I’ve been following the discussion in #293 and found it very helpful. In my work, I’m training a PPO agent that outputs position deltas (Δx, Δy, Δz), which are then fed into a PID controller that finally outputs motor RPMs. This approach (high-level RL + low-level PID) is similar to what @visionofdavinci suggested, and it works reasonably well.
However, to make the control physically consistent with the simulator’s motor model, I want to compute the RPMs using the same thrust‑to‑RPM mapping that gym‑pybullet‑drones uses internally (i.e., the quadratic model: thrust = dw_coeff_1 * rpm² + dw_coeff_2 * rpm + dw_coeff_3). My current code:
- The PID produces a desired acceleration
a_z.
- I compute the required total thrust:
F_total = mass * (g + a_z).
- Required thrust per motor:
F_motor = F_total / 4.
- Then I solve the quadratic
dw_coeff_1 * rpm² + dw_coeff_2 * rpm + dw_coeff_3 - F_motor = 0 for rpm and clip to [0, max_rpm].
I’ve taken the coefficients dw_coeff_1 = 2267.18, dw_coeff_2 = 0.16, dw_coeff_3 = -0.11 from the cf2x.urdf file of the simulator. I also compute the hover RPM by solving the same equation for F_motor = (mass * g) / 4.
My questions are:
-
Is this the correct way to convert desired thrust to motor RPMs given the motor model used in the simulator (Physics.PYB)? Should any additional factors (e.g., propeller direction, torque effects) be considered for the translation from desired thrust to RPM, or does the mixer already handle them?
-
Are the dw_coeff values I extracted from the URDF the ones actually used in the dynamics step? I see they are logged at initialisation, but I want to be sure there is no scaling or unit conversion that I missed.
-
Could you confirm that for a stable hybrid control setup (RL outputs position deltas, PID computes desired acceleration, then RPMs), this thrust‑to‑RPM mapping is the correct way to interface with the simulator’s physics?
I’m happy to share my code snippets if needed. Thank you for the great library and for the lively discussion in #293!
Environment:
- gym-pybullet-drones version: latest (installed via pip)
- Python 3.11
- Physics engine: PYB
- Drone model: CF2X
Hi everyone,
I’ve been following the discussion in #293 and found it very helpful. In my work, I’m training a PPO agent that outputs position deltas (Δx, Δy, Δz), which are then fed into a PID controller that finally outputs motor RPMs. This approach (high-level RL + low-level PID) is similar to what @visionofdavinci suggested, and it works reasonably well.
However, to make the control physically consistent with the simulator’s motor model, I want to compute the RPMs using the same thrust‑to‑RPM mapping that gym‑pybullet‑drones uses internally (i.e., the quadratic model:
thrust = dw_coeff_1 * rpm² + dw_coeff_2 * rpm + dw_coeff_3). My current code:a_z.F_total = mass * (g + a_z).F_motor = F_total / 4.dw_coeff_1 * rpm² + dw_coeff_2 * rpm + dw_coeff_3 - F_motor = 0forrpmand clip to[0, max_rpm].I’ve taken the coefficients
dw_coeff_1 = 2267.18,dw_coeff_2 = 0.16,dw_coeff_3 = -0.11from thecf2x.urdffile of the simulator. I also compute the hover RPM by solving the same equation forF_motor = (mass * g) / 4.My questions are:
Is this the correct way to convert desired thrust to motor RPMs given the motor model used in the simulator (Physics.PYB)? Should any additional factors (e.g., propeller direction, torque effects) be considered for the translation from desired thrust to RPM, or does the mixer already handle them?
Are the
dw_coeffvalues I extracted from the URDF the ones actually used in the dynamics step? I see they are logged at initialisation, but I want to be sure there is no scaling or unit conversion that I missed.Could you confirm that for a stable hybrid control setup (RL outputs position deltas, PID computes desired acceleration, then RPMs), this thrust‑to‑RPM mapping is the correct way to interface with the simulator’s physics?
I’m happy to share my code snippets if needed. Thank you for the great library and for the lively discussion in #293!
Environment: