Inverted Pendulum
To finish Neil's maths class and to walk myself through some control basics, I'm going to try to control an inverted pendulum system.
The Simulation
One first step is building an ODE simulation of a pendulum, and rendering that. I can do this pretty easily by pulling code from my earlier javascript pendulum, just moving the platform left/right instead of up/down. I should hope to build an understanding also for simulation time / weight / units relate to world units, so that I can match it against the world.
The Stepper Driver
I want to build a new stepper driver (code) for this. Currently, my driver & hardware pair has these settings, maxed:
Setting | Units | Value | Alt Units | Value |
---|---|---|---|---|
steps / mm | - | 231 | ||
acceleration | mm/s^2 | 30 | m/s^2 | 0.03 |
top speed | mm/s | 20 | m/s | 0.02 |
Although it would seem as though I've made some mistakes in implementation, because this seems pitifully small in terms of 'Gs' - but observed acceleration seems to be near or beyond 1G.
- first, cleanup existing code
- steps/unit as a float,
- underlying state / operation same as current, but understand and document limits
- stepper becomes responsible for acceleration, watch world units, timers
- stepper should become responsible for limits: I want to bake safety into hardware. as a result, it will also be master of its own absolute position.
- to start down the new path, I'll roll it up to accept acceleration commands, in world units
m/s^2
- eventually I'll want to bundle data packets... RIP msegs
The Pendulum Hardware
I'm planning on using this axis type as the 'cart' for the pendulum project. This is part of a larger machine project I am working on in the mean time.
This might prove to have some limits: these are designed to accelerate at a decent clip, but not hit huge top speeds. The 6.5:1 reduction there really kills and speed desires. I think I'll get through the simulation, get a sense of what kinds of accelerations and speeds are required, and revisit this if it's necessary.
There's some CAD and sensor reading here, as well - I'll need to make / print a pendulum bearing / encoder situation, write an encoder driver, and then very likely should filter that encoder data to build a state estimator for its current position.
Software Architecture
One of the real puzzles here - and I hope this will unlock some secrets for future, more general purpose control of machines - is how to handle the relationship between realtime-worlds (embedded code and genuine physics) and asynchronous worlds - like the javascript / networked runtime and simulation.
My suspicion is that sourcing time from the lower levels is the move, i.e. track state / time advancements from the bottom, and somehow trickle those up.
The Actual Control
Here's where I know the least... again, starting point is certainly the simulation, with keyboard inputs to play with. I hope to learn from the simulation:
- what accels, what speeds are necesssary for success (human controller)
- above, w/ relationships to pendulum weight / length,
From there, I'd also like to plot the phase space of the system. I have some idea that one control strategy would be to run a kind of 'path planning' inside of this space... if any point in the space represents a particular state, plot a course to the state we are interested in being at.
I should also do some lit review, that should start here.
Swing Up and Balancing
I imagine I'll start with balancing, as swing up seems to require some next level magic. In the first video above, these are two distinct controllers!
Learning
The idea is to craft a best-practices-and-all-the-priors model and controller first, and then start cutting pieces out to replace them with learning / search.
Log
2020 04 05
I've turned all of my hardware and frameworks back on after ~ 1 mo away from code, so I'm just note taking on what my steps are for this thing, and some other observations.
I figure I should first build this virtually, in simulation, and then attach that to hardware. Since it's appropriate, I'll also try to take this opportunity to break explore some of the architecture decisions I made while I was building squidworks, which I am ready and excited to revisit.
I should keep things simple and move fast, so as much as possible I'll retain most of squidworks' function. To start, this should just mean (1) writing ahn hunk that runs the simulation, and does control, and (2) writing a new stepper driver.
- current acceleration control is not cool enough for this project. also, limits for the same should be found downstream at the motors. motors have no guarantee that they have a faithful master, should protect themselves. how to find and auto config all of this?
- current stepping code is also sort of limited. I figure I should roll new, simple codes that begin with running accleration, and maybe even track position state at the endpoint as well - lets build from the bottom up here, since remote states are always a PITA. I like the thought that in the future, states are queried-only, so we can put heavy stuff like position in these areas
I am into this last point. I want a stepper driver that knows (1) where it is, (2) what its limits are, and then (3) can accept accelerations as inputs. It should be dampening; when there is no requested accel, or it's not near an edge (that it cannot deccel into), it deccelerates. This will put enough intelligence into the motor that I can build other APIs on top of it, which hopefully will end up looking like some kind of bussed - and - timestamped - moves to make... ?
I have some code cleanup to run first, I think. First would be rebasing scuttlefish into cuttlefish. Then, since I'm going to break the stepper otherwise, I should branch ponyo.
OK, done with that... and notes here... I suppose the simulation is my first order, as it's a javascript world for me for a few minutes, some chance that I might wrap on new protocol stuff before I get too far into this, it would be cool to use this to push all of that.