jjshoots / PyFlyt

UAV Flight Simulator for Reinforcement Learning Research
https://taijunjet.com/PyFlyt/documentation.html
MIT License
95 stars 17 forks source link

Determining Realistic Motor and Control Params #22

Closed Jgunde closed 6 months ago

Jgunde commented 7 months ago

I have a quadcopter with a flight controller running ArduPilot. I'm looking to use PyFlyt to train an RL policy to complete different maneuvers with a simulated quadcopter. I then plan to transfer this policy to my actual quadcopter.

Do you have any recommendations on calculating or measuring the motor and control params that will most accurately model real life? I plan to use the primitive_drone example as a starting point. Would it be useful to incorporate the actual PID values from ArduPilot at all?

jjshoots commented 7 months ago

Calculating motor params is a fairly easy task that can be done using simple motor thrust and torque stands. You will also need to obtain inertia and mass values which can be done using a simple scale and trifilar pendulum test. As for PID values, I do believe that copying the values over directly would not work since Ardupilot's params may incorporate a different scaling and saturation regime. That said, comverting the PID values over should not be an impossible task. I am willing to help with this if you can describe your goals in a bit more detail.

Jgunde commented 7 months ago

I plan to modify the hover and waypoint demos. My goal is to have the primitive_drone quadcopter dodge incoming projectiles. Its default state will be to hover in place. Then as a projectile approaches (I'm planning to use those green orbs from the waypoint demo), the quad will do some sort of flip or maneuver to avoid the projectile. Then it will return to hovering at the home position.

Creating this environment will be a task of its own. I'll probably spend most of the time tuning the reward function to achieve the behavior I desire.

But after the drone can dodge projectiles in simulation, I want to transfer the RL model to an FPV racing drone (Holybro Kopsis). I'm running ArduPilot on the flight controller and I will use a Linux companion computer to send it commands. I will most likely use the default flight mode 0 in PyFlyt (angular velocities and thrust). And so I'd send angular velocity and thrust commands to the ArduPilot flight controller as well.

At first glance, I can tell that the primitive_drone model is much more sluggish than an FPV racing drone. I'm going to try to tune the params to make it more agile so it can dodge faster projectiles. I think the hardest part of this project will be accurately simulating the FPV racing drone. Specifically finding appropriate PID values will be a challenge. One reason I plan to use the angular velocity and thrust commands is that it allows the flight controller to handle the lower level control. I won't need to account for propeller pitch and diameter, motor sizing, battery voltage... It will just use its PID values to maintain the requested angular velocities and thrust. As long as the angular acceleration and maximum thrust match between the simulator and real life, I think I should be able to transfer the learned maneuvers to the real FPV racing drone.

jjshoots commented 7 months ago

That's a very cool application, and one that I was hoping to see PyFlyt being used for eventually - happy to see that you're taking up this mantle. Let me know if there's anything that we can help with, and whether there are any physics inconsistencies between your system identification parameters and PyFlyt. We will be happy to accomodate any suggested changes.

Yes, the primitive drone is way more sluggish because it's model was based on an F450 class drone - complete with the crappy flight characteristics and noise.

I'm not sure what your proposed process is, but here is what I imagine. For system identification, I would actually recommend that you use mode -1 in the quadcopter. Disable gravity in the simulation, then send it manual step rotation commands and record the angular position response. Do the same with the real world UAV by pinning it on one axis and probably actuating the motors using a small Arduino nano so the PID loop doesn't affect things. This would get you very close to inertia and motor thrust and torque constants. After that you'll just have to tweak with mass and the PID settings.

I'm fairly excited to see where this goes, if you'd like, you can keep me updated on Discord under the username @jjshoots . Or post a link here anywhere for us to follow your progress. :)