I replaced the stock 11T pinion with a 12T pinion, and replaced the stock E-Flite 800 mAh LiPos (68 g) with Turnigy Nano-Tech 370 mAh (38 g) batteries. The Turnigy batteries are 30 g lighter, and deliver 7.5 to 8 minutes of (mostly hover) flight. These modifications, in addition to the throttle gain increase described here, make the helicopter very zippy – it lifts off at ~50%. I’m replacing my Sparkfun RedBoard and SD card shield (35 g combined) with an Arduino Pro Mini and MicroSD breakout board (6 g combined). The combined changes should give me sufficient T/W for experiment with sensors on board.
I have several FreeIMUs that I built myself a while ago, but never got farther than running Fabio’s yaw/pitch/roll demonstration. The FreeIMU library is very large, and takes up almost all of the ATmega328 memory, so I’ve been experimenting with communicating with the sensors directly via I2C so I can have a lightweight program to log raw data to an SD card. I’ve discovered that the MPU-6050 is a very complicated little device – its user manual and register map total 98 pages. The HMC5883L compass is much simpler, so I decided I’d start with that sensor. However, I encountered weird behavior where sometimes I could access the compass via I2C, but sometimes I couldn’t. The screenshot below shows the ouput of I2c.scan() – it only identifies the MPU-6050 accelerometer/gyro at 0x68 and the MS5611 barometer at 0x77.
Fabio has the HMC5883L compass tied to the MPU-6050’s auxiliary SDA/SCL – not the main SDA/SCL – and the MPU-6050 blocks I2C access to devices on its auxiliary bus unless certain bits are set. Fabio’s FreeIMU library sets these so I2C can access the HMC5883L, but they reset when the power cycles. So before running I2c.scan() I set the following registers on the MPU-6050:
I2c.write(ACCGYR_ADDRESS,0x6B,0x00); //Take device out of sleep mode I2c.write(ACCGYR_ADDRESS,0x6A,0x00); //Disable master mode, precondition to enabling I2C bypass I2c.write(ACCGYR_ADDRESS,0x37,0x02); //Enable I2C bypass
And after all that head scratching, I can see all three devices on the I2C bus.
Lots of reinventing the wheel. Blerg.
I put an IMU (Fabio Varesano’s FreeIMU with the MPU-6050 and HMC5883L) on the helicopter and flew it until I crashed. The y-axis on all the plots below are raw ADC output, not scaled to engineering units, but the obvious message is the sensors get noisy as soon as the rotor spools up. I was using both sensors’, or Fabio’s, default settings. I think both have a low pass filter feature that I can tune, and I’ll try some different mounting techniques. I tried to fly level passes back and forth: the magnetometer X-axis looks almost useful and you can kind of see my turns in the gyro Z-axis. All of the accel channels are garbage, and clipped for most of the record.
I’m kind of re-inventing the wheel here, because the Blade SRX 200 has a really effective stabilization feature. When I opened up the receiver, it found it’s using an MPU-6050, and I suspect it’s using Invensense’s DMP.
The noise in the accelerometer and gyro is narrowband at 5.6 Hz (336 rpm). Magnetometer noise looks broadband, and by the shape of the amplitude, it looks like the LPF cutoff frequency is around 20-25 Hz.
I stripped the helicopter LIDAR setup down to minimum usable form factor and flew during lunch. Setup works pretty well, this time it looks like I got up to 31.8 m. I think the LIDAR malfunctioned for approximately 1 second near t = 140 s; the 40 m peak is erroneous. I still stay at full throttle for most of the flight, which I think will make controlling altitude difficult, but consistent with what people say about this little helicopter. While the helicopter is in the air, the throttle PWM duty cycle only varies between 59.5% and 63.9% (also, the full throttle duty cycle is a now a little higher than I measured before…not sure why). Next up, some state estimation and closed loop altitude control. I also ordered some lighter LiPo batteries – sacrificing flight time, but shaving almost 30 g of weight.
It’s been a while since I worked on this project in earnest, but this weekend I tried to fly the helicopter with the LIDAR mounted to the tail to record altitude. I bought the original LIDARLite for $90 like 3 years ago. Since then, Garmin acquired PulsedLight (the original manufacturer) and now sells what looks like the same sensor for $150. The V1 LIDAR had an unfortunate cable – a tiny 6 pin JST where one of the wires is red, and the remaining 5 are all black, so it was very tough to distinguish GND, from SDA, from SCL, and so on. This weekend I realized that two of the wires had snapped off at the connector, and after a futile effort trying to reuse the the JST contacts, I decided to remove the JST connector from the board and solder my own (uniquely colored) leads to it.
My first sensor package is too heavy, and even with the throttle gain at 200%, I was basically at T/W = 1 and barely got off the ground. The plot below shows the LIDAR altitudes and the throttle PWM high period. I characterized the throttle signal before flying using pulseIn() (so take that with a grain of salt), and the command a 337 Hz (T = 2.96 ms) PWM with duty cycle = 37.4% (1108 us) at 0% throttle and 63.2% (1872 us) at 100% throttle. I think the highest altitude is 80 cm (31.5 inches) near the 8100 sample mark.
Here’s what the helicopter looks like now. I’ll trim some weight and try again this week. Expect rubber bands and hot glue.
I incorporated a Kalman filter into the altitude control loop; it estimates altitude and velocity from a model of the helicopter and the altitude measurement from the LIDAR Lite. It doesn’t compensate for tilt errors, so it only works for small pitch and roll angles. The dynamics model includes a lag between issuing the thrust command and when the rotor thrust reaches steady state, so a transfer function Tactual/Tcommand = 1/(tau*s + 1) goes between the controller transfer function and the plant. This plot shows a climb to 20 m then a descent at 1 m/s. The black curve is the Kalman filter altitude estimate and the red points are the noisy LIDAR measurements.
This plot shows the commanded control output and the actual control output for tau = 0.9 seconds.
I tested the LRD-3 Aluminum air tank and it burst at 828 psi (57.1 bar).
Dry Mass: 2.34 kg (5.16 lbm)
OD: 7.271″ (18.47 cm)
Wall thickness: 0.097″ (2.46 mm)
Ultimate strength: 30,204 psi (208.2 MPa)
This ultimate strength is about 10% higher than what I computed for the 5 gallon tank, but still well below the 42 ksi UTS I’ve seen published for 5086-H116. I posted the entirety of the burst test video (burst occurs 2:09) so you can see the tank balloon as it is pressurized. The catalog diameter of the tank is 7″, but I measured a 7.271″ OD after the test; I neglected to measure the tank OD before the test. In retrospect, it worked in my favor that the UTS was lower than expected because my tester and pressure transducer are only good to 1000 psi.
For the vehicle, I’m considering downsizing from 5 gallon propellant tanks to 3 gallon tanks and from 250 lbf thrust to 180 lbf. Low Rider Depot makes a 3 gallon version of the 5 gallon tanks I’ve had success with and I purchased one for burst testing. Assuming engine thrust = 180 lbf, Isp = 140 seconds, O/F = 1.1, and runtime is 20 seconds, I’ll need 1.865 gallons of ethanol and 1.414 gallons of LOX. I’ll need high pressure tanks to hold the pressurant and equations from Sutton Chapter 6 and H&H Chapter 5 yield similar answers for the required volume: 0.79 to 0.92 gallons of nitrogen at 2000 psi per propellant tank (pressurantSupply). Based on the dimensions I could find (OD = 4.3 inches, height = 16.5 inches), the volume of a D size medical oxygen cylinder is ~1 gallon, so I’ll need 1 of those cylinders per propellant tank. Here’s a crude version of the vehicle with the 3 gallon propellant tanks and the D size medical oxygen cylinders. The vehicle is roughly 50 inches (129 cm) tall.