Fly Sherlock Air https://flysherlockair.com Tue, 05 Jul 2016 10:37:35 +0000 en-US hourly 1 https://wordpress.org/?v=7.1.3 Model building notes – Blaster 3 https://flysherlockair.com/2016/06/model-building-notes-blaster-3/ Tue, 28 Jun 2016 06:13:20 +0000 http://flysherlockair.com/?p=115 Continue reading Model building notes – Blaster 3]]> I recently completed my build of a Blaster 3 Spread-Tow Carbon 1.5m DLG, which is a fantastic craft. Here are some notes of the things I learned during building.

This RCGroups thread has all the build notes you could ever need, though you’ll have to read a lot of pages to find all the highlights! Particularly useful is the “view all attachments” feature, which shows all of the pictures in the thread on one page. The Hyperflight store page also has a handy list of recommended control throws.

The official manual doesn’t mention how the horns should be placed relative to the hinge line of the control surfaces. I believe they should be positioned so that the hole in the horn is directly above the hinge line.

If you’re a left-handed thrower, the rudder’s horn should also be on the left side of the craft (so it’ll effectively be hidden by the rudder when you’re holding the glider by its peg ready for launch).

When gluing the V-mount and rudder to the tail, be sure to scuff up the surfaces first with some sandpaper, and then clean the carbon parts down with acetone to remove any leftover release agent (from the moulding process). This will ensure a secure glue. After carefully aligning the V-mount, I glued it to the boom by wicking thin CA into the crack between it and the boom. A small balsa spacer was added to align the last control rod sleeve with the rudder. I also glued the vertical stabiliser using thin CA.

I found that the manual’s suggested aileron pushrod placement (exiting through the top of the back of the pod) required them to be ridiculously bent, and the force required to move them was too high. Instead, I drilled slots in the back of both sides of the pod (at the level of the servo arms) which allowed the aileron horns and the servos to connect together in a straight line. This also gave me more room for my antennas to exit the back of the pod alongside the rudder and elevator pushrods. A small round file can be useful in extending the drilled hole into a slot shape.

In compression, the aileron pushrods would bow near the ailerons. To fix this, I glued balsa supports between the aileron pushrod sleeves and the boom to hold them in place. By happy coincidence, these supports ended up being at the 80mm suggested CoG location, so I can use them as a CoG reference.

Balsa supports for aileron control rods

This is a popular modification, so there are lot of pictures of it for reference on the RCGroups thread, like this from Brain52.

When cutting the PTFE pushrod sleeving into 10mm lengths for the elevator and rudder pushrods, I found that the ends of the sleeves were getting crushed flat by the cutting action. I squeezed them in the opposite direction with a pair of pliers to bring them back to round, but the shape was still imperfect, and the friction with the pushrod was extremely high. To fix this, I slid the sleeve segments onto a piece of piano wire, and then heated them with a hair dryer. This allowed the sleeving to relax back to its former shape, and the friction dropped away to just about nothing. You’ll know if you got this right when the sleeves can slide up and down the wire on their own (under just their own weight).

If you choose your servos carefully, you can use a 2S LiPo battery to power everything. I’m using the Ripmax SD100 servos (Dymond D47 clone), which can tolerate the 8.4V of a fully-charged 2S battery. This way, you don’t need to use a voltage regulator, and FrSky telemetry-enabled receivers can transmit the actual battery voltage down to the ground without adding additional battery voltage sensors.

If you glue a servo in the wrong place, don’t worry about it, this is why you wrapped the servo in masking tape. The servo can be cleanly pulled off the tape, leaving just a square of glued tape behind on the boom, which can be removed with acetone.

Because the ailerons need such a large throw to allow for braking, I used longer arms on the aileron servos. This also allows room for the sleeves of the rudder and elevator servos to pass by within the arms of the ailerons.

I’m using the Turnigy Nano-Tech 300mAh 2S 35-70C as a battery, which is a little too tall to slide all the way to the front of the nose, so mine is mounted about 10mm further back. Because there’s so little vertical space available above the servos, the JST battery connector is a bit too thick to fit nicely above them. It works acceptably for the moment, but I plan to replace both the main connector and balance connector on the battery with a single servo connector.

I was worried that the Blaster wouldn’t fit in my car (Nissan Primera), but it turns out that I can fit it in the boot (trunk) if I fold both back seats down. I cut a slot in the top of a small cardboard box to act as a stand to hold the tail surfaces off the floor, then used masking tape to attach the left wingtip and the nose to the carpet. This holds the glider very nicely in place while driving.

 

]]>
Slope soaring at the beach https://flysherlockair.com/2015/09/slope-soaring-at-the-beach/ Mon, 21 Sep 2015 04:51:17 +0000 http://flysherlockair.com/?p=100 Continue reading Slope soaring at the beach]]> North-east wind flow over Aramoana beach

Today it was a beautiful blue sunny sky with a reasonable North-East breeze, which means that the wind would be coming directly onshore at Aramoana beach. There is a tall cliff a little back from the water’s edge, and I wanted to try slope soaring on this from its base. However, as I drove out there, the wind speed picked up until I was unsure if I’d be able to fly.

I carried my Libelle over the dunes, fighting with the wind the entire way, a little worried that it would pull the wings off. I finally took off and made a test flight over the dunes. But the wind was too strong, so although I was able to stay in the air, the Libelle’s ground track was continually moving downwind.

I copied some seagulls and moved out from the dunes and onto the beach itself. This was much better, but in the strong wind I still wasn’t getting much lift. I could hardly fly passes along the line of the beach, because I was forced to face almost directly into the wind in order to avoid being blown back into the dunes.

I gave up on flying over the dunes and headed along the beach to the base of the cliff. The strong gusty wind dropped as if I was standing in a sheltered area. I think this is because the cliff forces the air to rise upwards somewhat off-shore, leaving a nearly dead bubble of air at the base of the cliff where I was standing. The wind was even calm enough in this area for a DLG launch, so that’s what I did.

I found a nice steady upward flow of air near the cliffs, so I didn’t have to fight to keep the Libelle pointed where I wanted it. I flew passes along the cliff edge, steadily gaining altitude. I think I eventually managed to climb above the top of the cliff. I had feared that there might be a sudden wind shear at the top of the cliff that would slam me out of sight over the lip of the cliff inland, but luckily this was not the case and there was no discontinuity. A few seabirds joined me in patrolling the beach.

This is where I messed up. I had been soaring out from the cliff towards the water, quite high up so I had to look almost directly upwards to see the Libelle. Then at one point I flew right in front of the sun. This is normally no problem, I just glance away for a second, and then I’ve flown clear of the sun and it’s fine. However this time, as I glanced away, I suddenly realised that the Libelle was facing directly into the onshore wind. So the Libelle would actually be making very little progress across the ground (it was practically hovering in place) and wouldn’t clear the sun nearly as fast as I needed it to. By the time I could see it again, the strong wind could have rotated it into practically any orientation.

By the time I looked back, I couldn’t see the Libelle any more. Bewildered, I searched the whole sky, but there really didn’t seem to be any trace of it. I twitched the controls a little as if it would help me feel where the Libelle was, but to no avail (I need a force-feedback system :)). It really seemed like it had vanished. Finally, 10 or 20 seconds later I heard the unmistakable sound of the Libelle crashing into rock, so I believed that it had crashed into the cliff face, though I didn’t see any wreckage fluttering down to the ground.

I flipped a switch on my Taranis which causes it to announce the RSSI (received signal strength) every 5 seconds, and began to walk up the sand dunes towards the base of the cliff. The initial RSSI reading was about 60, so I knew that the Libelle wasn’t buried too deeply in the sand. Gratifyingly, the RSSI begin to steadily climb with every step I took upwards.

Eventually I found it. It hadn’t crashed into the cliff at all, but rather had crashed into a boulder that was 5-10 metres downslope from the cliff.

Aramoana crash site

Unfortunately it was sitting in a tidy pile of rather more pieces than it took off with. The nose cone is pretty comprehensively smashed, the wings have separated, both dihedral braces have snapped, the wing plate has shattered, and one end of the wing mount has begun to pull vertically out from the foam. One of the aileron servos is completely stripped, while the rudder servo has a notch only at one extreme end of its travel, and could probably fly again. The tailplane and wing surfaces are no uglier than when they took off, and the wing root break is clean and can be easily re-repaired. I think it must have landed nose-first, saving the foam from direct impact.

The peg mounting plate on the right wing was already fractured from a previous incident. Unfortunately, my CA glue repair of this plate must have given way on takeoff (without me noticing) as the launch peg has made a break for freedom and taken the wingtip with it. I don’t know where that ended up.

Wrecked again!

Unfortunately I think the issues with the wing mount damage, nose cone and missing wingtip are going to keep this Libelle grounded for the moment. Because of the high cost of shipping to New Zealand, I’ve found that the most cost- and time-effective way of buying spare parts is just to order more than one Libelle (particularly for long pieces like the pod/boom assembly or the wing, which require a large shipping box, costing nearly as much as shipping a whole Libelle). So luckily for me I have a pristine, never flown, backup Libelle sitting assembled on the shelf for just this eventuality!

When I lost visual contact with the Libelle, I probably should have gone into a slight bank in the hopes of spiralling to the ground, although the downwind speed was really fierce and it might not have improved things. I’m considering installing a lost-model beeper in future builds, which might have helped locate it in the air as well. Anyway, next time I’m going to stay as far away from the sun as I can!

]]>
Found a new place to soar https://flysherlockair.com/2015/09/found-a-new-place-to-soar/ Thu, 03 Sep 2015 02:36:48 +0000 http://flysherlockair.com/?p=93 Continue reading Found a new place to soar]]> I had some really great flights today! Two of the edges of the field I fly at (Opoho Park, Dunedin) are big slopes that fall away into a valley and into the city respectively. I’ve never flown on them before because they’re covered in trees, and there are trees planted around the edge of the field obscuring the view downslope and making last-minute landings impossible. But since my discus throw has been improving, I’ve been able to get enough launch altitude to clear the trees on the edge of the field and have a reasonable chance of safely returning even in dead air.

So today I drove through drizzle to the field and squelched through the mud to the edge of the hill. It’s heavy overcast and 8 degrees with only a breath of wind, so I wasn’t expecting much. I threw four or five tosses alongside, then slightly above and beyond the trees, without having any issue returning back to the field in time for landing. I got bolder and bolder, and flew further from the edge of the hill. This is the view past the cemetery towards the city, seen through a gap in the trees:

Opoho park pano

I made it out far enough that I was suddenly able to hang motionless in midair. I’m thinking the air was moving up the hill to match the slow end of the Libelle’s cruise speed. I was able to make very slow passes along the line of the slope (slower than walking speed I think), meanwhile my altitude was slowly climbing. I seemed to be in very smooth air and I didn’t need to make any big corrections, but I also didn’t have so much extra lift that I could make more than a slow cruise. I was able to get 4, 6, 8 minute flights, ranging further and further away from me out towards the city.

Some gulls circled near my altitude while I was hanging motionless next to them, pointing into the wind. At one point a bird of prey was suddenly 2 metres behind me, right on my six, and I had to zoom back over to the field to land, with it in pursuit. Once I touched down, it briefly looked like the bird was going to stoop down and strike the Libelle on the ground, but luckily it didn’t. I think it was just curious, because I’d like to hope it wasn’t considering taking down something as large as the Libelle, which was way bigger than it.

My last flight of the day was 12 minutes 30 seconds! Now I have to clean all the mud off everything, and find some warm gloves for next time.

]]>
My Libelle DLG’s on-board electronics https://flysherlockair.com/2015/09/my-libelle-dlgs-on-board-electronics/ https://flysherlockair.com/2015/09/my-libelle-dlgs-on-board-electronics/#comments Wed, 02 Sep 2015 06:19:19 +0000 http://flysherlockair.com/?p=83 Continue reading My Libelle DLG’s on-board electronics]]> Libelle electronics overview

I’ve now reglued my Libelle glider’s wings since my last crash, and while I have the covers off I thought I’d take the chance to post about the electronics I’m using.

I’m using the stock Dream-Flight servos, which I’ve been happy with. They do jitter a little bit, but I suspect this is mostly due to my transmitter/receiver. I shortened the servo cables for the elevator and rudder, and produced my own servo extension cables for the ailerons using the Pololu Crimping Tool to terminate the cable. With a little practice, this crimping tool (along with female & male crimping pins and connector housings) produces a strong, secure bond that I’d trust just as much as those on commercially produced servo cables. This allows you to avoid your control rods in the front pod binding on a tangle of cables by making the cables just the right length.

Instead of the stock 300mAh 4.8V NiMH battery, I’m using a Turnigy 1200mAh 3.7V 1S round LiPo from HobbyKing. This weighs less than the stock battery (23g vs 31g) but the capacity is much greater (4.4 watt-hours for the LiPo versus 1.4 watt-hours for the original). This gives me flight times exceeding 4 hours on a single charge, versus about one and a half hours on the stock battery. This is great because with the old NiMH I had several days of flying where the battery ran flat in mid air and I still wanted to keep flying. Now the battery outlasts me!

I took a servo extension cable, cut off one end, and soldered it onto the positive and negative battery tabs as shown, which accepted the solder readily without using special solder or techniques. I soldered the other half of the servo extension to a XT-60 plug in order to create a charging cable to plug into my Accucel charger.

The round cell is a little bit too long and tall to fit into the original foam cavity. I used a knife to remove the foam fillets from the battery bay floor at either end to accommodate the length, and dug down a few millimetres to accommodate the extra height. The pod lid now closes perfectly!

My receiver is a FrSky D4R-II, which has 4 channels and works down to 3.5V. In theory this could be powered by a single LiPo cell, but since I know how much the battery voltage can sag when the servos are operating, I didn’t want to chance it.

In order to give me a place to inject power (since all 4 channels are already occupied) I soldered 2 pins from a 0.1″ straight pin header onto the back of VCC and GND pins on the D4R-II’s right-angle header. These two pins in turn are soldered onto the back of the right-angle header of a Pololu 5V Step-Up Voltage Regulator (U3V12F5). This regulator boosts the voltage from the 1S LiPo into a nice steady 5V supply that the servos and receiver will work optimally with. Here’s a top view showing the battery plugged in to the regulator:

Pololu 5V regulator on D4R-II

And a side view:

Pololu 5V regulator

The manual says that the iron balance weights should be secured with double-sided tape and/or painters tape, and the battery should be secured with hot glue. I found that the glue was a poor solution for holding the original battery and would let go during a crash or on takeoff and eject the battery. Once the battery was ejected, I didn’t have a hot glue gun in the field to replace it with, so it basically grounded me.

Instead, after balancing the Libelle, I glued the weights to the foam walls using CA glue and covered the top of the battery bay with a wide piece of clear packaging tape which wraps down the outside of the pod. I conformed the tape to the contour of the balance weights and the foam surface so that the tape doesn’t hinder the closing of the pod lid. This holds the battery in very strongly without relying on the strength of a glue/foam bond, but still allows the battery to be easily removed if desired.

]]>
https://flysherlockair.com/2015/09/my-libelle-dlgs-on-board-electronics/feed/ 1
Whoops, wrecked my Libelle again… https://flysherlockair.com/2015/08/whoops-wrecked-my-libelle-again/ https://flysherlockair.com/2015/08/whoops-wrecked-my-libelle-again/#comments Mon, 17 Aug 2015 03:54:26 +0000 http://flysherlockair.com/?p=72 Continue reading Whoops, wrecked my Libelle again…]]> Dammit:

Broken Libelle

I was trying out a launch preset switch today to give me some reflex and up-elevator on takeoff (instead of trying to control the elevator manually during the throw, which I found difficult to make repeatable).

I got about 5 or 6 nice throws, adjusting the elevator launch preset strength to tune in the climb rate I wanted. There were a few gusts of wind coming by occasionally, and when they sometimes ended up being tail gusts this was a bit annoying for the airspeed drop, but wasn’t a huge issue.

Then for some reason on my last toss, instead of climbing upwards, the Libelle nosed straight down, as if the launch preset’s direction got reversed, and ended up with its nose buried about 10cm into the mud. I have no idea what happened with that. I double checked the launch preset after the crash and I definitely hadn’t accidentally reversed its elevator direction. I wish I had set up the Taranis to log its data to its MicroSD card so I could see what went wrong. I might even see if I can shoehorn an AfroMini 32 onboard in order to log my flight with Cleanflight’s Blackbox feature.

My first guess is that I wasn’t touching the right stick with my thumb, so I might have been unaware that it was being bumped by my clothing or something. I think I’ll program the Taranis to sound a warning tone if the right stick moves off-centre while the launch momentary switch is being held down, or program it to ignore the right stick during launch.

My other guess is that I simply forgot to hold down the launch switch at all, or released it during the rotation. I’ll add an audio notification for the switch being released.

It looks like the wings separated very cleanly, with just one of the locking tabs ending up being stolen by the other side. The two dihedral braces and the wing top plate all shattered, but interestingly both wing bolts survived. I think this suggests that my wing gluing wasn’t strong enough. I believe that the wings should be held together strongly enough that the nylon wing bolts fail before the wing does (making the nylon bolts a sacrificial failure point).

My electronics and the boom/pod assembly are all pristine, making this hopefully an easy fix once I receive new braces from dream-flight.

]]>
https://flysherlockair.com/2015/08/whoops-wrecked-my-libelle-again/feed/ 1
Profiling Cleanflight and speeding up the Naze32 https://flysherlockair.com/2015/07/how-does-cleanflight-spend-its-time-lets-profile/ https://flysherlockair.com/2015/07/how-does-cleanflight-spend-its-time-lets-profile/#comments Mon, 06 Jul 2015 03:52:58 +0000 http://flysherlockair.com/?p=56 Continue reading Profiling Cleanflight and speeding up the Naze32]]> With the recent release of the SPRacingF3 flight controller and the Seriously Dodo flight controller, both based on the newer STM32 F3 CPU, users have been posting great Blackbox flight logs demonstrating very fast and consistent looptimes. I found this interesting because the F3’s CPU isn’t clocked any faster than the F1 processor that is used on the Naze32 and compatibles.

One major difference between these CPUs is that the F3 has a hardware floating point unit, while the F1 must emulate its floating point support using some very large software routines. Floating point support is used in the IMU (which is responsible for estimating the craft’s attitude) and also as part of some PID controllers such as the new Harakiri controller. It’s not heavily used in any other parts of the code.

But how much time does the Naze32 spend doing floating point operations anyway? What is the total possible speedup available from just adding a hardware floating point unit? Could I speed my Naze32 up some other way?

In order to find out, I built a Sampling Profiler feature for Cleanflight. A sampling profiler works by periodically interrupting the program’s execution to check what code is currently running. The profiler makes 1000 of these checks per second and sends the results out to a serial port to be logged.

The checks can be used to measure what percentage of the time is spent on each line of code in the program. If one piece of code accounts for 30% of the execution time of the program, then we should expect 30% of our random samples to end up seeing that line of code being run. In this way we can construct an accurate picture of the program with a nice constant overhead.

If the profiler slows down the CPU too much, we only have to reduce our sampling rate and sample for longer. Our results will be the same, and CPU sampling overhead will decrease.

Limits

This profiler is somewhat limited because it can only see the top function that was executing when it takes a sample. It doesn’t currently have the ability to look up the stack and see which functions were responsible for calling the function that was interrupted.

This can make it harder to work out which parts of the code are the culprits for slowdowns, because some routines are shared by many parts of the program. It also means that functions which mostly just call other functions to do their work for them will have very low execution times as measured by the profiler.

The very highest priority interrupt handlers (I2C EV and ER interrupt handlers) are not measured by the profiler. This is because the profiler is not high priority enough to interrupt them. I configured it this way because of the I2C documentation’s warning that the interrupt handlers should not themselves be interrupted (I assume they’re too timing sensitive).

Results

You can see the raw output from the profile log decoder here. The results are pretty interesting. I was running a Naze32 Full with a PPM receiver, PID controller 0, looptime set to 0 and all other features disabled, so pretty much a barebones system.

Profiler results

You can see that the majority of runtime is spent on floating point routines (48%) plus trigonometry routines (5%), which are the likely callers of most of the floating point routines. This is great news for the SPRacingF3 because these are precisely the routines that will be sped up by its hardware floating point unit!

Of the remaining time, 36% is spent just waiting to receive data from the gyroscope over the I2C bus. I haven’t examined this code before, but from a quick glance it appears that the CPU performs a busy-wait while it waits for a response to be received from the gyroscope. If this task could be handed off to the DMA controller, which would perform the read in the background, it could potentially free up to 36% of the CPU time for other tasks.

It’s clear that it’s not worth speeding up any other part of the code, because the remainder accounts for such a small percentage of the total runtime. This information is a win for developers because we don’t need to waste our time on something that isn’t going to make a difference to looptimes!

Speeding up the Naze32

So, the SPRacingF3 is likely faster than the Naze32 because its floating point operations are faster. But can I squeeze more speed out the Naze32? There are two main approaches here.

One option is to speed up the floating point routines themselves. One way of doing this is to use routines which are slightly less precise than the default implementation, which can bring large speedups. The default implementation is extremely pedantic about being precise and handling error conditions in order to conform to IEEE floating point standards, but in a noisy system like a quadcopter that precision isn’t noticeable. To this end, some developers have been discussing Taylor approximations of our trigonometry routines over on the Cleanflight issue tracker.

The other option, which is even simpler, is to avoid the calls that require floating point in the first place. Since I’m flying PID controller 0, the main place in the code that is actually using floating point is the IMU’s attitude estimator. This is responsible for figuring out the roll/pitch angles and heading of the quadcopter. That information is required for Angle and Horizon flight modes, as well as the flight modes based on sensors like the magnetometer and barometer. But good old Acro flight mode doesn’t use the IMU at all, because it only uses rotation rates read directly from the gyroscope.

Luckily, I happen to be an acro-only pilot. So in my case, the only thing the IMU is being used for is the pretty display of the 3D model in the Configurator’s welcome page. Let’s see what happens when I turn off my accelerometer, which causes the IMU to never run:

Entering CLI Mode, type 'exit' to return, or 'help'

# set acc_hardware
acc_hardware = 0

# set acc_hardware=1
acc_hardware set to 1
# save
$ blackbox_decode LOG-ACRO.TXT
Decoding log 'LOG-ACRO.TXT' to 'LOG-ACRO.01.csv'...

Log 1 of 1, start 00:18.056, end 00:28.247, duration 00:10.190

Statistics
Looptime            325 avg           10.3 std dev (3.2%)
I frames     978   44.1 bytes avg    43094 bytes total
P frames     978   24.5 bytes avg    23994 bytes total
E frames       2    9.0 bytes avg       18 bytes total
S frames       8    4.0 bytes avg       32 bytes total
Frames      1956   34.3 bytes avg    67088 bytes total
Data rate  191Hz   6696 bytes/s      67000 baud

29325 loop iterations weren't logged because of your blackbox_rate settings (9552ms, 93.75%)

Yep, that’s a looptime of 325 with standard deviation of 10.3 microseconds! It looks like 1/8 logging rate is about as much as the Blackbox can keep up with at 250,000 baud. It’s now a lean, mean, acro machine! Here’s what the distribution of execution time now looks like according to the profiler:

Profile results - Acro only

i2cRead didn’t get slower, it probably stayed the same, but now it accounts for a larger portion of the total runtime because the floating point routines have shrunk so much. Now we’re seeing the actual flight code taking up a noticeable portion of the runtime, like mixTable() which is responsible for deciding what strength each motor should be driven at, and the PID controller itself. Here’s the raw profiler report for my acro-only configuration.

Sourcecode

The version of Cleanflight with (extremely experimental, only useful for developers) profiling support can be found here:

https://github.com/sherlockflight/cleanflight-dev/tree/profiler

You must read the documentation first, which is here:

https://github.com/sherlockflight/cleanflight-dev/blob/profiler/docs/development/Profiler.md

The decoder tool which reads profile logs is here (it’s also my first application written in Go, so it’s probably horrible):

https://github.com/sherlockflight/cleanflight-profiler

]]>
https://flysherlockair.com/2015/07/how-does-cleanflight-spend-its-time-lets-profile/feed/ 20
Improving variance in Blackbox flash logging overhead https://flysherlockair.com/2015/06/improving-variance-in-blackbox-flash-logging-overhead/ Tue, 30 Jun 2015 05:39:17 +0000 http://flysherlockair.com/?p=49 Continue reading Improving variance in Blackbox flash logging overhead]]> In my last post I showed that Blackbox’s logging behaviour when writing to an onboard flash chip ends up adding a lot of variance to the looptime. This was because 3/4 of the time, Blackbox would just write its log entry to a write buffer in memory, which was very fast, but the remaining 1/4 of the time it would have to flush that buffer through to the flash chip itself, which was very slow. The difference in speed between these iterations causes a variance in the looptime which is undesirable for stable flight. This caused the distribution of overhead due to Blackbox logging to have a twin-peaked shape like this:

Blackbox overhead from logging to flash

One way of solving this problem is to use the CPU’s DMA controller to send the write buffer out to the flash in the background. This way the buffer can be slowly written to the flash chip all the time while other tasks are executing, instead of the whole CPU pausing to make one big slow write every now and then. That’s still something I want to implement in the future, but in the meantime I looked into other ways to reduce the variance.

Since I want every Blackbox logging iteration to take a similar amount of time, I need to perform similar tasks in every iteration. So flushing the buffer to the flash in only 1 in 4 iterations is a big no-no. Instead I decided to flush the buffer out to the flash in every iteration, even if the buffer wasn’t full yet. This increases the mean execution time a little bit, because each flush operation itself has some overhead, but it causes a dramatic improvement in the standard deviation. Instead of two widely-spaced peaks in execution time, there is now one large, tightly-grouped peak:

Blackbox overhead from logging to flash, with flush every iteration

 

Here’s the new statistics:

Mean overhead  (μs)

Standard deviation (μs)
Logging to serial 64 5
Logging to flash
(old behaviour)
95 59

Logging to flash
(flush every iteration)

104 11

Flushing every iteration only causes a modest 9% increase in mean logging overhead, while it reduces the standard deviation by 81%!

This fix will be part of the next release of Cleanflight (the current release as of this writing is 1.9).

]]>
Measuring Blackbox logging overhead and looptime variation https://flysherlockair.com/2015/06/measuring-blackbox-logging-overhead-and-looptime-variation/ https://flysherlockair.com/2015/06/measuring-blackbox-logging-overhead-and-looptime-variation/#comments Sun, 28 Jun 2015 15:09:55 +0000 http://flysherlockair.com/?p=25 Continue reading Measuring Blackbox logging overhead and looptime variation]]> If you want the absolute fastest looptime possible on Cleanflight, you need to be aware of the additional execution time cost that various features add on.

One great feature for tuning your craft’s performance is the Blackbox flight log. However, the choice between logging to an OpenLog device or to an onboard flash chip brings with it quite different performance impacts, and you may need to factor this in when you’re choosing your logging device.

Logging to an OpenLog logging device

When logging to an OpenLog, the Blackbox writes the log to the serial port’s transmit buffer in memory, then returns control to the flight loop immediately. It never waits for the OpenLog to catch up, or for the buffer to be ready. Cleanflight’s DMA support slowly streams the transmit buffer to the serial port in the background, allowing the rest of the system to continue execution with little to no overhead.

When logging to the serial port, the extra overhead that Blackbox adds to each flight loop iteration (in microseconds) looks like this:

93 60 62 62 63 62 63 62 62 62 61 63 63 64 66 65 62 65 61 63 62 63 66 69 63 65 61 62 61 62 65 62 90

Every 32 loop iterations Blackbox logs an “intraframe”, which allows Blackbox to resync the log when it encounters missing or damaged log iterations. Because these frames are larger than normal, they take longer to write to the buffer, and so appear as an increase in overhead of ~30μs over the baseline (up to 90μs). So when logging to an OpenLog, Blackbox adds a mean of 64μs of overhead to the looptime, with a tight standard deviation of 5μs. That overhead is illustrated with this density plot:

Overhead due to Blackbox logging to serial port

Logging to onboard flash (Naze32 full)

When the Blackbox is set up to log to an onboard flash chip, it writes the flight log slightly differently. When there is space available in the flash’s write buffer in memory, Blackbox can complete its write in a similar time to writing to the serial port’s transmit buffer, and so it can quickly continue with the rest of the flight loop. But unlike the serial port, the flash chip is not written to in the background by the DMA engine. So when the buffer fills up, the Blackbox must briefly pause to write it through to the flash chip over the SPI bus. The looptime overhead from Blackbox logging (in microseconds) looks like this:

209 56 54 189 56 196 56 55 190 56 55 189 56 55 189 60 55 193 56 55 188 58 55 189 56 55 190 55 190 56 55 188

In the iterations where Blackbox only writes to the write buffer, it finishes its work quickly in about 55μs. But when it must flush the buffer through to the flash chip itself, the overhead is 190μs! The mean Blackbox logging overhead is 105μs, a reasonable 1.6x that of writing to the serial port, but the standard deviation is 65μs, which is 13 times the deviation of logging to the serial port! This is visible as a strong twin-peak pattern in the density plot:

Overhead due to Blackbox logging to onboard flash

Why looptime deviation matters, and why it doesn’t

The problem with variance in looptime is that there are several algorithms in Cleanflight whose results depend on the delay between flight control loops, but don’t have any built-in correction to deal with looptime variation. With a fairly speedy looptime of 1500μs, a standard deviation of 65μs represents a potential for a 4.3% error in calculations which (depending on PID controller) could translate to noticeable noise in signals sent to motors and flight instability.

However, this variance only comes in to play if you set the “looptime” setting to a time faster than the slowest loop that the flight controller encounters. As long as you set the looptime to a longer value than the slowest possible loop (when the variance in execution time is at its worst), then Cleanflight can make sure that every flight control loop starts with a similar spacing, minimising error.

The worst case results when looptime is set to zero, because Cleanflight cannot add any delay between loops in order to smooth out variations in execution time.

Here’s what the whole-system looptime variation looks like when looptime is set to zero and Blackbox is logging to the serial port. The mean looptime achieved is 1230μs, and the standard deviation is 82μs (6.7%).

Whole-system looptime when Blackbox logging to serial port

Note that this shows the sum of all looptime variation present in Cleanflight, not just the 5μs that’s due to Blackbox logging.

Here’s the system looptime variation (with looptime = 0) when Blackbox is logging to flash:

Whole-system looptime when Blackbox logging to flashThe mean was 1292μs and the standard deviation 102μs (7.9%).

We can use these graphs to decide on the best looptime to choose in order to minimise looptime variation. In the case of logging to the serial port, it looks like most loops can complete in under 1300μs, so let’s have Cleanflight aim to space its loops at 1300μs intervals by setting looptime to 1300:

Looptime 1300 logging to serial port

The new mean is 1328μs and the standard deviation 68μs (5.1%). There is still a strange tri-peak distribution which would be nice to remove, but the centre peak is now much taller than its surroundings than it was before.

I think the three peaks are likely due to variations in the time taken to read sensors like the gyroscope and accelerometer and update the craft’s attitude estimate. Cleanflight attempts to begin the execution of its imuUpdate() routine at regular intervals, but Blackbox records its timestamp at the end of this routine, which is used to derive the variation shown above.

When logging to flash, our looptime will have to be set slower in order to encompass the secondary peaks in activity that we saw in the 1300-1400 looptime range. So let’s set looptime to 1400μs:

Looptime 1400 logging to Naze32 flash

The mean is 1419μs and the standard deviation 56μs (4.0%), about half the standard deviation we had at looptime 0!

In the future

In the future I would like to investigate adding support for DMA to the Blackbox’s flash engine. This would allow the Blackbox to log to flash with a similar delay and variation as writing to the serial port, eliminating the 135μs flash-writing penalty observed above.

]]>
https://flysherlockair.com/2015/06/measuring-blackbox-logging-overhead-and-looptime-variation/feed/ 1
Flying the Libelle DLG on a slope https://flysherlockair.com/2015/06/flying-the-libelle-dlg-on-a-slope/ https://flysherlockair.com/2015/06/flying-the-libelle-dlg-on-a-slope/#comments Sun, 21 Jun 2015 04:52:50 +0000 http://flysherlockair.com/?p=9 Continue reading Flying the Libelle DLG on a slope]]> Ready to fly with the Libelle DLG and Taranis transmitterEver since I received my Libelle, I’ve only been flying discus-launch on flat land in calm wind, but last night I saw the forecast for today was for a nice 10km/hr westerly wind and clear sunny skies. I had a hunt around on Google maps and finally found a west-facing slope. It’s a big hillside with a series of switchbacks and jumps carved into it as part of a downhill BMX race course, in Dunedin, New Zealand.

And indeed, when I got there a 10-20km/hr wind was blowing almost directly up the slope to me. I gave the Libelle a lazy javelin toss and wow! It zoomed straight up into the air. Suddenly, compared to flat-land, I had almost infinite power available. I even managed an aileron roll, although it seemed to hesitate forever at the halfway point. I quickly learned the importance of always making your turn into the wind instead of back towards the slope, as it wipes off a ton of airspeed/altitude if you do it the wrong way. Luckily not enough to make me crash.

Eventually I managed to lose enough altitude that I had to land it, about halfway down the slope. Unfortunately the slope is lined with 2 metre tall toetoe bushes, so visibility was extremely limited and I couldn’t see the landing spot. I had to hunt through gorse bushes in order to find it again. Once I got within 10 metres of it I was able to waggle the ailerons and immediately hear the servos whirring further down the bank. Nice gentle landing in grass:

Tidy crash landing

I gave the control surfaces a quick check and then it was back in the air!

Unfortunately, 15 minutes after that first sunny photo was taken, a dark raincloud started rolling up the valley and it started to rain on me. I was going to brave it out, but my lift started dropping. I couldn’t manage to land it somewhere nice where I could guarantee I wasn’t going to get gouged by gorse again, so I decided to land it on that playing field you can see way the heck at the bottom of the hillside. (maybe 125m vertical).

Wow, depth perception is difficult at that distance! I set flaperons for landing, and I was like “Okayyyy…. touchdown! No? Tttt…….ouchdown! No?? What?”. Finally I made a perfect landing (pretty much by chance). It’s the tiny white speck you can see on the field through the rain:

The rain rolls in and I land in the field

Unfortunately the field turned out to be composed of 95% moss, it was basically a sodden swamp. My shoes have seen better days. Can’t wait to go back!

]]>
https://flysherlockair.com/2015/06/flying-the-libelle-dlg-on-a-slope/feed/ 1
Libelle back in the air! https://flysherlockair.com/2015/06/libelle-back-in-the-air/ https://flysherlockair.com/2015/06/libelle-back-in-the-air/#comments Tue, 02 Jun 2015 04:57:54 +0000 http://flysherlockair.com/?p=18 Continue reading Libelle back in the air!]]> So, I previously wrecked my Libelle pretty hard, tearing both the wings and the nose cone in half. I’ve now repaired both of those using Gorilla Glue, which worked excellently. The glue foams up, so there is still some excess here and there that I haven’t sanded off yet.

I’m happy to say that it’s now back in the air!

4g9WUs0

I’ve been flying it until the battery runs flat for the past three days, and having a blast. My discus technique is slowly improving, though I’m still doing poorly compared to those I see on YouTube. I might take a video one day and get your guys’ suggestions. I haven’t found a thermal at my flying field yet, I might start hunting further abroad.

I’m now running proper flaperon mixes on my Taranis to give me Thermal and Landing modes according to the deflections specified in the excellent included manual, so my landings can now be much more gentle.

I noticed that since I re-glued the wings, their angle is offset compared to the tailplane, which obviously is not a good thing. One of the plastic mounts snapped in half when the wing did, so there’s not as much holding them in alignment any more. For the moment, I’m just going with the flow and flying counter-clockwise circuits to match the craft’s bias.

I managed to lose the carbon fibre launch peg, so I replaced it with a section of cheap paintbrush handle, which happened to be tapered so I could find a precise fit from halfway down the brush :).

 

]]>
https://flysherlockair.com/2015/06/libelle-back-in-the-air/feed/ 2