Tuesday, April 25, 2017

Q1 2017 Rocket active stabilization system update; Finally have working PID for positional control of a DC motor! New gear, livestreams and the first program sponsor!

After nearly 4 and a half months of late nights, caffeine fueled jam sessions, one livestream(more on that later!) and more frustration than anticipated I FINALLY figured out implementation of PID for positional control of a DC motor with an encoder. More details after the break including a breakdown of problems I ran into, some shiny response graphs and most importantly; SOURCE CODE!?!?!
Motor control testbed using TB6612FNG motor driver

In working towards a positional control system, the first order of business was to go for the most basic of controllers; Bang-Bang. Dead simple to implement but not without numerous shortcomings. Several of these removed it from even consideration of the flight unit due to possibility of overcontrol or destructive airframe resonance. Airframe resonance would start as a flutter in the fins but spread to the stabilizer oscillating on the front of the rocket before finally leading to a full half of the body wobbling about the split for parachute deployment and snapping the rocket in half mid-flight. Another nightmare scenario is overcontrol, where the system attempts to correct course changes but turns itself into a kinetic hazard as it passes the +- 5 degrees off vertical allowable range for safe flight or worse goes sideways and WAY off course.
The core of the Bang-Bang control plant
A Bang-Bang control system is dead simple, if the value is not reached, keep going until it's passed at which point you go backwards. The issue arises in that the system runs at full tilt and will always overshoot unless there is a lot of inertia in the system(e.g. a flywheel or significant thermal mass) leading to the oscillation around the target value as depicted in the figure below. During my initial implementation of the controller, I had a serious problem where the system would appear to be on target and tracking but would start spinning as the counts went from the expected range (0-300) to around 32,767 before flipping out. This is an indicator of unsigned int overflow but limiting the system read range to 300 did nothing to minimize this issue. Rereading the documentation, I realized that the encoder pins were not both on the hardware interrupts and that was causing it to miss a lot of counts since A phase was on HWINT1 but B phase was on a regular pin set as an interrupt. Moving B phase to HWINT0 fixed this problem. Attempts to lower the jitter around the target included decreasing drive PWM and testing deadzones and braking but none of those worked to the extent required for flight confidence. As I had eliminated bang-bang from flight consideration, I turned to the more complicated but also FAR superior PID controller which was a heck of a challenge. 
Oscillation of actual position (Red) vs setpoint (Blue)

A proportional–integral–derivative (PID) is a controller that calculated the difference between setpoint and current variable and corrects based on the three terms (Kp, Ki, Kd). I'm going to leave the rest of the explanation to Brett Beauregard who wrote the FANTASTIC library I'm using. Early attempts at implementing the PID by taping the well-respected PID library into the bang-bang controller led to frustration due to calculated outputs being WAY off the expected. The odd thing was outputs either sharply moving around but not passing 255 or locked at that value. As I was hitting the limits of my coding knowlege I called up Joe Barnard of Barnard Propulsion Systems (the OTHER active stabilization guy on the internet) to see if he would be able to help figure out what was going wrong. Unfortunately neither of us was able to make any sense of why it wouldn't work even after 3 hours of trying to debug. It wasn't until I found a very different method of driving the TB6612FNG in a Pololu robot, specifically the 3Pi that I finally got the system working. Instead of pulling the direction pins to logical 1/0 and driving the PWM pin I pulled PWM HIGH, and drove both directions with PWM signals, which puts the driver in half-brake mode and only needs 2 IO pins instead of 4. The magical code that finally got the system working is as follows

void pwmOut(int out) {
if (out > 0) { analogWrite(AIN1, out);
analogWrite(AIN2, 0); }
else { analogWrite(AIN1, 0);
analogWrite(AIN2, abs(out)); }}
 More tuning and testing needs to be done in addition to implementing servo-protocol control but this is VERY good news since I had been holding off on further system hardware work until I'd solved the problem of positional motor control. Hold on, I know you were wondering "Hey wait a minute you said something about source code, yet you said this project is likely under ITAR, what gives!?!" no? Well you're not exaaaactly wrong. I won't be sharing the source code for the rocket controller or other fun parts but CAN share the positional control since it's not regulated and a good lesson in control mechanics. The primary reason I'm sharing this is because all the existing material out there is either absurdly vague or headache inducing with uncommented code and very strange implementations of parts. So as a firm believer in open source and learning from analyzing other's code, I have adopted the beerware license on this and my other projects that will be getting code releases. My code is available on my GitHub for everyone to use and learn from. Timelapse of my fighting with the code has also been uploaded from one of my later Twitch streams.
Clear illustration of the issue faced with initial attempt, red is target, green actual, yellow PID output. 

The magical sight of a working PID plant in action. Red is actual, Blue setpoint, Yellow is PID, Green is error.

WAY too much gain

How it's supposed to look when locked on target position
Now as some of my longer-term readers will know due to me living farther out from civilization I'd been having some godawful internet. 80gb/month and horrifically slow (<1mb/s) is REALLY not conducive to content creation or getting much done. However the big red ISP has decided to bring back uncapped internet which has been WONDERFUL! From limping along and hitting the 80gb cap frequently, now comfortably burning 300+ a month and oddly the speeds are around 10mb/s. Now with all this power, I've done something that was discussed for a long time: Livestreams! From the stream lair I did a 2 hour quick CAD cloning of the Pharah Mechaqueen rocket from an image to get a feel for streaming, and will definitely be doing more soon including Live from the lab. More work needs to be done on the upstream settings, audio levels and recording but it's a start.
Streaming/editing battlestation
Craptactular stream setup #2
Workshop overview camera
I also decided to invest a bit more into my content this year and bought myself a proper DSLR during the black friday sale and have been playing around with it. After a ton of research, the Nikon D3400 stood out above the rest and the black friday deal on the full starter set made it a no-brainer. Now the videos and pictures for the blog and youtube channel will get a dramatic increase in quality. Below are some high resolution (6000x4000) images, previously had just been shooting with my LG G4 which has a great camera but can't compete with the MUCH larger sensor and aperture of a full size camera.
New gear day! :D Bought myself a proper DSLR
Gave the last version of the rocket a paint job!
Side on view showing dataport on the stabilizer business end
Gratuitous high resolution shot of stabilizer controller internals
The first sponsor! 
Another VERY important update is that I FINALLY got a sponsor! Pololu has stepped up and contributed a full set of high power micro gear motors and encoders to match. These will be integrated into the testing version and likely carried onto the flight system assuming that everything checks out in control authority testing and launch confidence checks are green.
Teaser for upcoming post on Wii IR camera
And lastly, after WAY too long screwing around with the Wii IR camera, pooling all the documentation floating around the internet I have FINALLY got it working! Once the next rev of boards is done and testers send some projects I'll spin up a larger run, put them up for sale on Tindie and release a blog post with a document compiling all the known data on these sensors.