Thursday, August 16, 2012

Project Status

It's been a while since our last post, and it's obviously past the end of the school year. So, where did we get with our capstone project?

Well, we didn't get flying.

But, that's ok. What we learned in the process was, to put it bluntly, overwhelming. And we'll keep on working on this as time goes by. It was fun to work on something so audacious that we had to focus almost entirely on the project, and with no guarantee of success.

The most recent stage of the project has the quadrotor being able to balance on the test stand. This provides validation for the main control loop, and all of the associated software (motor PID control, serial interface, and the GUI control/profiling application). Unfortunately, it wasn't until the end that we realized how poorly the CHR-UM6 inertial measurement units actually functioned. These units (we had two) failed to provide an accurate attitude estimation, which caused the quadrotor to tilt without reference to the ground.

To see what our project documents, take a look at code.anzhelka.com

So, the next step is to come up with an IMU that works. There are several possible solutions out there, but all of them are expensive to the point of making the project unfeasible. So, I think we'll look into building our own IMU: one that is accurate, and extensible to include GPS and barometer readings as well. It's always been a dream of mine to implement a Kalman filter of my own.

The Anzhelka quadrotor project waits for a new set of eyes.

Tuesday, June 5, 2012

Anzhelka Quadrotor Roll Pitch Testing




 We have a nice video of the quadrotor (sort of) balancing on the roll/pitch test stand. These are exciting times. Although it's clearly not ready to fly, the quadrotor system is now working from end to end, and it's merely (!) a point of tuning now. Maybe we will still be able to fly soon.

Tuesday, May 29, 2012

Cody's Update



We have been very busy over the last few weeks as we work hard towards getting the quadrotor flying before the end of the quarter. I've been working mostly on the software, including, in no particular order:

- PID control
- Math equation to assembly compiler
- UM6 IMU integration
- Memory management

So far, our software is getting very close to completion for the first testing phase. We have all of the software components up and tested, and now I need to integrate them into a single program that works end to end. Our first testing will be on the roll pitch test stand, pictured above.

This stand will allow us to test the software without worrying about crashing and damaging the quadrotor. It allows the quadrotor to spin freely on a single axis. With this, we can tune the flying parameters and, hopefully, be able to go to stable flight once we figure out all of the different parameters here.

There is still some work to be done before stable flight, namely:

- Altitude sensor integration
- PID parameter tuning
- Altitude testing

I'm very optimistic, and am working hard to fly before our presentation in about a week.

Monday, May 14, 2012

Presentation Countdown

We have been answering lots of questions about our quadrotor, and most of them are "When will it be flying?" I'm here to tell you when: by our presentation! When is that? Well, it's not too far away:

Wednesday, May 9, 2012

UM6-LT IMU

I've been working recently with the CHR Robotics UM6-LT Inertial Measurement Unit. At first glance, the sensor seems to be ok, and within it's price range ($150) it's certainly the best that we could find. Most IMUs have, in the past, been very expensive. However, a couple of things that I don't like about the UM6:

UM6 AHRS- The product is under documented (see below for specifics).
- Customer service is lacking (see email conversation below).
- Their interface software is windows only.
- They say their software is open source, but what they really mean is that you can download the .hex programming file. No source code available.

I've written a driver object, soon to be uploaded to the Propeller obex, and currently available via our repository (code.anzhelka.com).


Datasheet Omissions
 I've noticed that the datasheet is missing some critical information, which I have written below:

1. The orientation of the axes of the sensor. [NEED TO FIND OUT]
2. The sensor has no reverse polarity protection. If you connect it backwards you'll fry the board, and then it won't work.
3. You cannot power it at 3.3v (this has been updated in their most recent datasheet).
4. The checksum is calculated as the unsigned sum of all bytes from the first 's' to the last data byte.
5. Data bytes are transmitted such that D3 is received first, followed by D2, D1, and D0.
6. By default, processed xy accel, gyro, and magnemometer are transmitted; along with xy euler angles, Note that Z (yaw) is not transmitted for any of these.
7. The newest version (with GPS "support") does not use the GPS in the filter algorithms.
8. When it is working, the gyros will heat up and need to have their bias adjusted after 5-10 minutes.
9. The UM6-LT board has 2 green LEDs that should be lit when in normal operation.
10. When outputting quaternions, the UM6 outputs [a=w,b=x,c=y,d=z] where w is the scalar (from here).


Customer Service
When testing a few weeks back, I noticed that the sensor was not responding. I emailed their technical support, and through some emails we went back and forth on things to check to see what was wrong. Eventually, I was told to mail the IMU in so that they could test. Below is the complete email record from that point forward. I've removed names and salutations from the excepts.

Me (Sun, April 6):
I've posted via USPS the sensor to the address you specified. It should be there on Monday. Thank you for taking a look at it,


Me (Wednesday, April 16):

Have you received the sensor yet? It was scheduled to arrive last Monday the 9th of April.


CHR (Thursday, April 17):
Yes, we have received it but haven't yet had the opportunity to troubleshoot it.  We'll have a look as quickly as possible and I'll get back to you.

Me ( Friday, May 1):
I just wanted to check on the status of the IMU, and whether you have had the chance to test it yet.

Me (Thursday, May 7):
You've had the sensor for four weeks. If you're not going to take a look at it like you said, do you think you could mail it back?

CHR (Thursday, May 7)

Please accept my apologies for the delay.


We tested your sensor near the end of last week and determined that the RX UART line on the device has been damaged, possibly due to over-voltage or ESD.  Since we took so long to investigate the issue, we'll replace the damaged module at no charge.  I'll see that a replacement is shipped tomorrow.
_____________________


So, in short it took them a month to respond back to me. I appreciate that they were willing to test it in the first place, but I don't think their customer service was any good. At the very least I expect a response to any emails that I send, even if it's just to say that they have not been able to test it yet.


Conclusions
Still, the CHR UM6-LT sensor is among the best value sensor that I could find. The next runner up that I'd like to try is the X-Monkey IMU. It looks to be a very nice module with all the features that we really want. I've also found an article in Circuit Cellar called "The FreeSpace IMU" which gives a complete description of a simple IMU version, along with source code (here). If we ever get around to implementing our own IMU I'll probably look into this as an alternative algorithm.

My goal with this review isn't to be unfairly harsh. The IMU hardware itself seems to work ok at this point, but the support for the product is minimal. I'll keep using it since we are committed to the module now, but unless it improves we'll look elsewhere when we next work on the IMU side of things.



Writing PASM Code Update

Luke and I have been working very hard on the project. Over the past week I have been working on writting the CHR-UM6-LT IMU interface object, and it's been going ok. Check out the post on that topic for more information.

I've put in the whole weekend, plus time during the week for about a total of 40 hours in the past week. The main challenge in the past week was (re)learning all of the Propeller assembly that I've forgotten. The last time that I have programmed in PASM was during the summer of 2009, when I wrote some driver objects for the USB Memory Stick Datalogger and NMEA GPSs (link). Those objects share many of the same characteristics as the current work: streams of serial data, automatic parsing, and data control in the hub.

In the next week I'll delve more into the assembly, and hopefully get the UM6 object finished and the assembly code for flight up and running. I've relearned many of the tips and tricks of assembly programming, so it shouldn't be too much work getting everything else done.

In the meantime, here is a picture of Luke and I presenting our project at the Parallax Expo 2012 in Rocklin, CA.

Thursday, May 3, 2012

Thrust/torque test video


We have our first video! Exciting times. Our thrust/torque test stand is still incomplete, but we are getting closer. All we need to do now is calibrate the darn thing and then we are done. Be sure to watch the video in HD: http://www.youtube.com/watch_popup?v=viVVwRabck4

Monday, April 30, 2012

Cody's Pre- Control Loop Update

Last week we worked very hard on the report. We wrote most of the document, and so now it's about ready to turn in. Of course, we don't have anything on there about flying yet. We're not there! Other sections are done, however. We have about fifty five pages of documentation for our project, and we feel that more is needed for an accurate representation of what we have done.

As always, all of our documents and code are at code.anzhelka.com for download. The reports are there as well, and we hope you'll take a look at them.

-------------------------------------------------------------------------------------------------------

Over this past two weeks, I've worked approximately seventy hours on this project. It's been a busy time, but we have accomplished much. I'll next start working on the IMU interface code and hopefully get that up and running. Then it's on to working on the assembly code for the main control loop. For that, I've been looking into the BMA debugger for Propeller assembly. I'm (as always) optimistic about what can be accomplished, and I still have hope for flying.

Wednesday, April 18, 2012

Project Task Schedule

We've been getting lots of questions on when we will be flying, so here is our best guess at the timeline. This is updated live too, so be sure to check back. I thought about adding a "Who to Blame" column, but it wouldn't work anyway... It's clear who is to blame for any and all delays.





Tuesday, April 17, 2012

GUI Update

Over the last week I have been working on the test stand. I've developed the structure for the Anzhelka GUI as well. This GUI will be used to display real time data about the quadrotor. For this part of the project we will be able to display in real time the RPM, voltage, current, torque, and thrust of the motors as they go through the test stand process. The GUI is particularly necessary for tuning the various runtime parameters during testing. We have about a dozen PID loops that will  need to be dynamically tuned. The GUI will be very useful for tuning without requiring that we change constants in the code (which would require a compilation/download cycle).

I also worked on a poster display board for the thrust/torque test stand. This board is helpful because it provides an introduction to a part of our project. Luke and I presented the board and test stand by tabling at the Parallax Expo in Rocklin last weekend.

This next week I hope to get the GUI code and the test stand code finished.

Week 2

Last week was a very busy week. The IMU is currently in a state of disrepair and we are waiting on a reply from the manufacture to see if it is covered under warranty, or if we need to buy another. We have managed to get all machining done for the Motor Thurst Torque test stand thanks to Gene. 
When we went to the Expo, we learned that there was a design flaw with the stand and that we wouldn't be measuring the force correctly. Cody already knows how he is going to change the stand so that we do achieve proper measurements of the forces.
In the past week I have put in over 50 Hours (excluding driving ~15 Hours). It put a very big toll on my body to be able to dedicate that much time into the project in one week.
Before my next update I want to have the motors tested, graphed and ready to add their coefficients into the stabilization algorithm. I would also like to have the report up to speed on where we are in the project.

Parallax Expo in Review

So I am going to admit that I have never been much of a Parallax guy, not because I didn't like them or anything personal, but because I had never really used their product. I also had never been to company Expo. 
With all that said, I had loads of fun this past weekend. Cody and I set up a booth to show off our Motor Thrust, Torque test stand. It was great to get both feedback and to teach people about the dynamics of flying a quadrotor autonomously. There were many different types of people and companies that attended. It was very cool to talk to the robotics guys from Microsoft, they liked our project so much that they wanted to record our little presentation to show it off to their colleges. Telling people about our project helped me see that people were actually interested in such a project.
One of the best parts of the Expo was getting to see all the great talks given by various people from different backgrounds. Zigbee had sent a guy to the Expo to explained what they were doing with their new products and how to use their products. There was a talk given by an animatronics expert who talked about his projects and movies that he had worked on. Some of the other presenters showed off personal projects from RFID readers to teaching high school students about robotics.
Even though our goal of gaining sponsors for our project was not met, I feel that not all was lost and that people will hopefully spread the word on what we are doing so that interest is gained.

Monday, April 9, 2012

Code Performance Estimation

In the past few weeks we have made a significant amount of progress towards our goal. I've finished up all of the mathematics, and most of the software design architecture. Luke has been working on a different portion of the project, and I'm sure he will post up here soon about that.

For our software, the critical portion is the main control loop that keeps the quadrotor flying at the desired attitude (roll, pitch, yaw) and altitude. It is essential that this control loop operates fast enough to respond to disturbances. From my research into what other quadrotor groups have done I have found that 50Hz to 75Hz is sufficient for flying. So for our project we need to analyze our system and determine if we can achieve the desired rate.

The first component to consider is the inertial measurement unit (IMU). The IMU that we have selected is the CHR-UM6-LT IMU. From the datasheet, it can output at up to 300 Hz. On the output we have the ESCs that control the motors. These expect a control pulse every 20ms, so that is on update rate of 50Hz. Most stock components can run with a slightly faster update rate, and we can select ESCs that are designed for a faster rate. In any case, we have guarenteed support for 50Hz updates with the hardware we have.

Now we need to consider the software control loop. I've broken the math into three blocks: attitude control, altitude control, and motor control. The attitude control block and altitude control block can be done in parallel, and their output fed into the motor control block. Luke and I will be writing the code in Propeller Assembly using the Float32 floating point library.

The Float32 documentation includes timings and space requirements for each of the mathematical functions. If we count the operations required for each block we can then calculate an estimate of running time and space.

First, we have to count up all of the operations so we know how much math we have to do:





















Quantity + - * / cos sin asin acos atan2 sqrt quat* Sum








Moment 1 6 20 11 3 4 0 2 2 0 3 52 ops







Altitude 3 1 4 1 0 0 0 0 0 0 2 11 ops







Motor Speed 14 10 18 10 0 0 0 0 0 4 0 56 ops







Sum 18 17 42 22 3 4 0 2 2 4 5 119 ops





























Our control loop has 119 mathematical operations. The number sounds small, but it is slightly misleading. In the next table we see that the time to execute an addition or multiplication is much less than it is to calculate arcsin or arccos. For quaternion multiplication we assume that one multiply has 6 floating point additions, 6 floating point subtractions, and 16 floating point multiplies. This follows from the quaternion multiplication formula. In summary, since we have the number of each operation, we can calculate the total times:
























100 MHz + - * / cos sin asin acos atan2 sqrt quat* Sum








Time (uS) 4 4 8 11 78 75 261 265 117 174 225









Moment 4 23 168 116 234 298 0 531 234 0 675 2283 uS 438 Hz 2283 uS



Altitude 11 4 34 11 0 0 0 0 0 0 450 509 uS 1964 Hz
uS



Motor Speed 53 38 151 106 0 0 0 0 0 694 0 1042 uS 959 Hz 1042 uS



Sum 68 65 353 232 234 298 0 531 234 694 1125 3835 uS 261 Hz 3326 300 Hz















w/o Parallel w/ Parallel























Our estimates show that we can have an inner control loop of 260Hz, and if we parallelize the moment and altitude calculations then we can get about 40Hz faster. Also of interest is that the quadrotor control loop has a response time of 3.3milliseconds. For reference, the average human reaction time is roughly 200milliseconds (source).

Finally, we are interested in code size. The floating point library has a number of required support functions that do things such as convert to and from floating point, compare floats, and so on that require space. We also assume that 4 longs on average are used to setup each operation. This gives us:























(w/ 4 extra) + - * / cos sin asin acos atan2 sqrt quat* Float Trunc Cmp Pack Upck Extra



Size(longs) 24 6 18 19 2 45 36 5 25 28 15 13 17 22 25 42 30
Ops + Support

Moment 28 30 98 63 14 61 0 49 33 0 27 13 17 22 25 42 30
552

Altitude 36 10 34 23 0 0 0 0 0 0 23 13 17 22 25 42 30
275

Motor Speed 80 46 90 59 0 0 0 0 0 44 0 13 17 22 25 42 30
468

Sum 96 74 186 107 14 61 36 13 33 44 35 13 17 22 25 42 30 848 1295



















Sum w/o dup.





















So, if we were to do each instruction in sequence then it would take approximately 850 longs. Unfortunately, a Propeller cog only has enough memory for 496 longs. If we break it into sections then the altitude and motor calculations will fit into a single cog, but the moment block is too big. Some optimizations will probably be able to reduce the size to fit.

All in all, the code performance estimates are looking very promising. We should be able to achieve 100Hz update rates without too much trouble. The actual programming is unlikely to pose a challenge since we have the equations laid out in the exact order necessary for implementation.

Many have been asking if we are flying yet. No, sorry, we are not. Both Luke and I have been working full time on this, but there are many details to be concerned about. We are getting closer though. In the next week I plan on working on the thrust/torque test stand, and once that is done I'll start programming the control loops and the like.

The current version of the tables in this post can be found at this link.

Monday, April 2, 2012

First Board Populated

So what have we accomplished today... As you can see the board has been fully populated, no real problems or overlooks were found while putting the board together.

One thing that was not ordered was the 73.2K ohm resistors for the current sensing, so for this version of the board we have 100K ohm resistors.

Some changes that will have to come from REV A are
  • The spacing between the battery input and ESC1 are way to close together.
  • The spacing between R44 and R45 are also to close.
  • Better silkscreen to determine which way Capacitors and LEDs are supposed to face.
Here are some more photos of the finished board.



Saturday, March 31, 2012

Anzhelka Rev A boards have ARRIVED!

After a full 30 days of waiting the REV A Quad Rotor boards have arrived! Just as a reminder these boards were ordered through IteadStudio's PCB Prototyping services. Taking my first look at these boards I get a sense success in having a physical entity. It is really hard to see if all the traces are connected because of the white solder mask, but when I do the electrical testing on Monday I should be able to easily determine that. Solder mask looks decent, but the smaller fonts and text didnt come out at all. As some of you guys may know, there was atleast one major thing that was forgotten on this rendition of the board, Gound Plane. This has been fixed in the diagrams for Rev B. I also  forgot to add a resistor on the DOUT pin of the MCP3208. Both of these issues should not contribute to any serious problems with this board.  Take a look at the photos below.



Final thoughts
 If you are in a time crunch to get a set of boards, I would highly NOT recommend getting your boards through IteadStudio. I also placed an order for some PCB's from SeeedStudio a week later and received them on the same day at twice the quantity and for only about $10 more.

Stay tuned in the days to come. There is going to be lots of soldering work on the way. :)

Sunday, March 25, 2012

Motor Testing: PWM vs RPM

Today I was able to test the response of the motors to pwm inputs. I tested the Turnigy 2217 860Kv brushless outrunner (link) Note that the motor is black on the product page, but ours is red.

To test, I hooked the motor up to it's ESC and a Parallax Propeller development board. Motor power is provided at 12v from a computer power supply*, and the code slowly ramps the motor up in 10uS increments. The rpm is read at the end of each step to allow the motor one second to settle in to it's new speed.

The up loop code:
repeat
 repeat i from 0 to 1000 step 10
  pwmoutput := i + 1000
  debug.str(string("PWM= "))
  debug.dec(pwmoutput)
  pwm.servo(ESC_PIN, pwmoutput)
  waitcnt(clkfreq + cnt)
  debug.str(string(9,9,"RPM= "))
  debug.dec(rpm.getrpm(0))
  DebugNewline

A couple of comments on the data:

  • Minimum power up was with a pulse of 1120 uS (microseconds), and resulted in 1800 rpm.
  • Maximum rpm was approximately 12000rpm.
  • The graph is definitely not linear, so coming up with a function that maps pwm to rpm would be difficult

* I found that, with these motors in particular, that if the throttle is suddenly reduced to off (1000uS) the motor creates a surge on it's power lines, which then causes the computer power supply to automatically turn off. But it works fine if the speed is gradually reduced.

Eagle Tree Brushless RPM Sensors

In order to determine the amount of thrust that a motor is producing we must be able to measure the RPM of the motor. For a normal two wire DC motor the only solution would be to use some sort of optical sensor to watch the motor rotate and to count the number rotations. Usually this is done with an IR sensor that either senses a black stripe on the can of the motor, or watches the propeller and detects it's passing over the sensor.

With a brushless motor, we have a new option: monitoring the control pulses. A brushless motor has three control lines that go into the motor, and to make the motor spin the lines are pulsed in a specific order. The  timing of the pulses determine the speed of the motor, and the pulses must match the position of the motor rotor. Modern brushless motor controller chips (ESCs: Electronic Speed Controllers) have circuitry built into them that can automatically sense the position of the motor rotor and which could, in theory, be used by a host microcontroller to determine motor rotation speed. Unfortunately, most ESCs don't provide this sort of information to a host, so we'll have to measure the pulses directly and infer from the control pulses instead.

By taping into a brushless motor control wire we connect to the circuit show below. In that figure, each arrow is a pulse sent by the ESC to the motor, and each pulse is sent once per rotation. Now, imagine our RPM sensor has a tap right at the B marker. Pulses 1,4,2, and 5 all pass through B, so that's 4 pulses per rotation. For the remaining two pulses 3 and 6, the ESC sets B to be high impedance (ie unconnected). But for pulses 3 and 6 there is still a detectable pulse on B simply because a high impedance input can "skip" the b coil and measure the voltage at com, which has a pulse. With that, a single rotor revolution produces 6 measurable pulses.

In the above image, there are two magnetic poles. I suspect that if there were four magnetic poles the sensor would produce twice any many pulses, if there were six poles it would produce three times as many, and so on. I don't have a motor to test this on, but this is an interesting thread on the RCgroups forum that has a custom circuit to measure brushless RPM.

Anyway, this is my current theory on why the number of pulses have to be divided by 6. I've also heard  that outrunner motors have 6 poles, so that may be why. I'll have to take apart a motor and take a look at it to see what's up.

The Eagle Tree Brushless RPM sensor is the only ready made solution on the market. It's a very small device, priced at about $12 a piece, and it can sense the rotation rate of a single motor. It converts the brushless motor signals to a series of pulses where each pulse is equivelent to a rotation. We don't measure the signal directly from a brushless motor control line because there are very high voltages and back EMF from the motor, all creating a very nasty environment for our 3.3v microcontroller. So we use the Eagle Tree sensors instead.
The only Propeller source code that I could find came from a single forum post here. The code is under documented and very minimal, but it works. For the rest of this post I will analyze the object and show how it is used. I have attached a condensed version of the source code to the end of this post.

First, the circuit. In the object, it says
  Connect black to 3.3V, red to Gnd, white to prop pin  
And yes, it does work the way it is written. Despite going against standard color coding conventions, the red line is connected to ground and the black is to 3.3v (the Propeller VDD).

Next, connect both single red wires from the sensor to any two of the brushless motor lines. A single line would work, but I found that connecting both reduced erroneous readings on motor load situations. In a simple test, with only one lead connected there was a variation of 15 RPS, while with two there was a variation of 10 RPS (and a slightly higher bias).
The object will work for up to eight sensors, each with it's own Propeller I/O pin. These pins must be in a contiguous block of eight pins, regardless of how many sensors are actually used. The pins to use are declared by calling the setpins(_pinmask) function. Once the pins are set, call start to dedicate a new cog to the process.

The object times the number of clock cycles between rising edges of a pulse, and stores this value in the  Pins[n] variable. Most users probably don't care about the absolute time, so the getrps function will return the rotations per second of the specified channel. This function accounts for the six pulses per revolution, and the current system clock rate. It could be sped up a bit by making the division and multiplication done in assembly.

As currently written, the object supports up to 8 sensors, and regardless of how many you use the update time (minimum delta clock) will be the same since the code runs through the entire sequence on every iteration. You can remove the unused code, or if you have more than 8 motors (wow!) you can add more copies without too much loss of precision.

The (nearly complete) object. For the original, check out post four of this thread. For the latest and greatest, check out code.anzhelka.com.
Con
  Mhz    = (80+10)                                      ' System clock frequency in Mhz. + init instructions
   
VAR
  long  Cog
  long  Pins[8]
  long  PinShift                                          
  long  PinMask

PUB setpins(_pinmask)
'' Set pinmask for active input pins [­0..31]
'' Example: setpins(10_1001) to read from pin 0, 3 and 5
  PinMask := _pinmask
  PinShift := 0
  repeat 32
    if _pinmask & 1
      quit
    _pinmask >>= 1
    PinShift++ 
PUB start : sstatus
--- etc.
PUB stop
--- etc.
PUB getpinptr
  return @Pins
PUB getrpm(i) | delta
--- etc.
PUB getrps(i) | delta
'' Get the RPS of motor i (by index, not pin number)
'' Valid index range is 0-7
'' Returns -1 when no valid data
 if i > 7 OR i < 0 'Check Range
  return -1
 delta := Pins&#091;&#173;i&#093;
 if delta == 0
  return -1
 return (clkfreq / (delta*6))
DAT
        org   0
INIT    mov   p1, par                           ' Get data pointer
        add   p1, #4*8                          ' Point to PinShift
        rdlong shift, p1                        ' Read PinShift
        add   p1, #4
        rdlong pin_mask, p1                     ' Read PinMask
        andn  dira, pin_mask                    ' Set input pins

'=================================================================================

:loop   mov   d2, d1                            ' Store previous pin status
        waitpne d1, pin_mask                    ' Wait for change on pins
        mov   d1, ina                           ' Get new pin status 
        mov   c1, cnt                           ' Store change cnt                           
        and   d1, pin_mask                      ' Remove unrelevant pin changes
        shr   d1, shift                         ' Get relevant pins in 8 LSB
{
d2      1100
d1      1010
-------------
!d2     0011
&d1     1010
=       0010 POS edge
}
        ' Mask for POS edge changes
        mov   d3, d1
        andn  d3, d2

'=================================================================================

:POS    'tjz   d3, #:loop                       ' Skip if no POS edge changes
        mov   p1, par       ' Hub variable address
'Pin 0
        test  d3, #00_0001   wz    ' Change on pin?
        mov   d4, c1       ' Copy :loop count value to d4
        sub   d4, pe0       ' Subtract old count value from new count value ( delta(cv) = d4 - peo )
                  ' If pos change:
if_nz   cmp   d4, mintim wc      '  -> write c if d4 (delta count value) is less than minimum time
if_nz_and_nc wrlong d4, p1      ' -> write the delta count value to the hub if greater than minimum time
if_nz_and_nc mov   pe0, c1                      ' -> Store POS edge change cnt (system clk time, not delta)
            ' If no pos change:
if_z    cmp   d4, maxtim wc      '  -> write c if d4 (count value) is less than maximum time 
if_z_and_nc wrlong zero, p1      ' -> write zero to the hub if greater than maximum time

'Pin 1
        add   p1, #4
        test  d3, #00_0010   wz              ' ...
        mov   d4, c1
        sub   d4, pe1
if_nz   cmp   d4, mintim wc
if_nz_and_nc wrlong d4, p1
if_nz_and_nc mov   pe1, c1
if_z    cmp   d4, maxtim wc
if_z_and_nc wrlong zero, p1
'Pin 2
        add   p1, #4
        test  d3, #00_0100   wz
        mov   d4, c1
        sub   d4, pe2
if_nz   cmp   d4, mintim wc
if_nz_and_nc wrlong d4, p1
if_nz_and_nc mov   pe2, c1
if_z    cmp   d4, maxtim wc
if_z_and_nc wrlong zero, p1
'Pin 3
--- etc.
        jmp   #:loop

fit Mhz                                         ' Check for at least 1µs resolution with current clock speed
'=================================================================================
mintim  long  3000
maxtim  long  10_000_000
pin_mask long 00_0000
shift   long  0
c1      long  0      
d1      long  0
d2      long  0
d3      long  0
d4      long  0
p1      long  0
pe0     long  0
pe1     long  0
pe2     long  0
pe3     long  0
pe4     long  0
pe5     long  0
pe6     long  0
pe7     long  0
zero    long  0
        FIT   496

Motor Testing: Volts vs RPM

Today I was able to test the motors under no load to get a general idea of how they work. I tested some Turnigy 860kV motors with a bench top power supply, and the eagle tree RPM sensors. I used an RC airplane remote set at full throttle for all tests.



VoltRPMAmps
986400.6
1096000.64
11105600.685
1211520
0.73
13124800.78









From this graph, a few things are clear:
  • RPM and current vary linearly with voltage.
  • No load current is very low (~675 mA)
  • The kV rating is off by a bias, but a very good predictor of no load.
Concerning the kV rating I found that with 

expected rpm / measured rpm

I came up with .895833 for every result. The measured kV can be calculated by

measured rpm / measured voltage

This resulted in a measured kV of 960, a full 100 more rpm than the manufacturer specified 860kV.

This test is important because it indicates that we can test the other characteristics of the motors (thrust, torque, etc.) and reliably extrapolate the results to different voltages.


Wednesday, March 14, 2012

So What has Luke been doing?

So these last couple of weeks I have been finished up the circuitboards, part sampling and ordering. I sent the design off to the PCB manufacture on March 1st. They said that the boards had a 4 day turn around. I got an email from them on the 7th saying that the order had been shipped out to me, however, from the tracking number all I can see is that the package is "POSTING". If someone could help me understand what this means it would be much appreciated.

Last week I ordered the $300 in parts needed so that we could populate our 5 circuit boards that are on the way. These components have already arrived and are ready to be used and tested.

For anyone who has never sampled parts, it is a God send! Sampling parts allows you to receive nearly anything for free. If you need a box, you can most likely sample that. If you need some ICs you can most likely get them. Here is a Instructable on a list of known places that sample and what they sample. So with that information aside, I placed orders to Texas Instruments and Microchip to sample: TBX0108PWR, INA169NA, I2C EEPROM, MCP3208.

In Cody's post below you will notice that we are building a stand to test the thrust and torque of our motors so that we can learn their characteristics. One thing that he didn't mention is how we are going to be powering our test stand. We were able to come across a Corsair HX520W. This power supply is has three 12V lines capable of delivering 18amps max on each channel, however if you tie all the lines together you can achieve a max of 40amps. Just to let everyone know, because you cant find this info in the manual, one of the 12V rails resides in the Molex connectors for harddrives and like components, another is in the ATX12V connector for the Motherboard, the last one can be found on PCI-Express power connectors. On the side I am working on making a board so that I can plug these connectors into a single board that will breakout the 3V3, 5V, 12V, -12V, 5VUSB with the high current capability. (BTW, Molex also lets you sample components from them.)

Who are we using for our PCB manufacturing?
http://www.iteadstudio.com/

Would you recommend them?
Currently unsure of that question. Stay tuned to find out.

If you guys have any questions be sure to leave us a comment or send us an email to either ilukester@anzhelka.com or srlm@anzhelka.com. We love questions.

Monday, March 12, 2012

Introducing: The Thrust/Torque Test Stand!

A good autonomous quadrotor needs to be able to measure, in real units such as kilograms and seconds, important aspects about itself such as orientation, motor thrust, acceleration, and so on. It's fairly easy to make a remote controlled quadrotor platform since the human in the loop can intuitively correct for many small errors, and our eyes are very good at collecting the necessary raw information. An autonomous quadrotor does not have this luxury, and must explictly define each kinematic and dynamic equation. Most of the fundamental equations that a quadrotor must use will have some sort of general constant in them. This constant is meant to account for small errors in the system, differences between almost identical parts, and so on. Some of the most important constants and most difficult to measure are the motor torque and thrust constants. This post will cover details about our motor thrust/torque test stand.

I posted the equations last week, but here they are again:




[If your browser is like mine and is messing up the equations, then the first is K_T = T / (rho*n^2*D^4) and the second is K_Q = Q / (rho*n^2*D^5) ]

Don't be intimadated by equations. Most of the quadrotor mathematics look very difficult and impossible to understand, but it's my belief that understanding is not too difficult. I'm writing a paper to address the subject in great detail, and I'll be covering each equation from first principles to implementation.

Above, we have the two equations that define how our motors affect our quadrotor system. The form that they are in now makes it convienient for us to measure the constants K_T and K_Q: if we can somehow measure the terms on the right hand side then we can figure out what the constants are.

But first, we need to cover some notation details. When a term is written with a subscript it will be denoted in this text with an underscore (e.g. K_T is K with subscript T), and exponents are denoted with a chevron ( ^ ).  Greek letters such as rho (the sideways 'p') will be spelled out with the standard English letters. Other notation follows standard mathematical practice. The terms used are:

K_T - Thrust constant
K_Q - Torque constant
T - Thrust
Q - Torque
rho - air density
n - motor shaft rotation rate
D - propeller diameter

From these equations, it is clear that we need to measure thrust, torque, air density, rotation speed, and the propeller diameter. Ideally, we would build a machine that for any given motor and propeller combination will automatically test and produce the constants, along with information about how the motor operates and it's efficiency. Measuring rotor diameter, motor speed and air density are all fairly easy to do, and so we won't cover it here. The real challenge comes from measuring motor thrust and torque.

Most of the people who measure motor thrust seem to be RC airplane people. They measure the motor thrust in order to properly size a motor for their airplanes. Most motor thrust test stands are simple: a motor is mounted at the end of a lever arm with the opposite end fixed in place, and an L bend that presses on a scale (similar to a sensitive bathroom scale). From there the hobbyist powers the motor and and reads the force directly off of the scale and ends up with a thrust measurement. Easy.

Calculating torque is a bit more complicated: the motor body needs to be mounted on a rotating axis that is directly in line with the motor shaft, and the torque along this axis needs to be measured. In my research I found only a few examples of a motor torque test stand. This is likely because on an airplane the torque that a motor produces can be considered negligable since the motor is so proportionally small. Unfortunately, this is not the case on a quadrotor. In fact we rely on the torque to yaw the quadrotor vehicle.

To measure torque, most test stands had the motor mounted to a rod, which then had a lever arm attached that pressed on a scale. In a same way as thrust the force pressing on the scale can be read, and with the length of the lever arm torque can be calculated.

We want our test stand to be different: we want to measure both thrust and torque simultaniously, and we want to do all the testing automatically. To do this means that we will need a method to measure force (or pressure) without relying on scale, since a scale would be difficult to connect a microcontroller to. We have decided to try using the Flexiforce pressure sensors. These sensors vary the resistance based on the amount of pressure, and resistance is very easy to measure with a microcontroller.

For motor speed we will be using a Eagle Tree brushless RPM sensors, and we will use an contactless IR thermometer from Parallax. Our main control board will simply be the quadpower board that we have developed for our quadrotor. This has the advantage of being identical to what we will be flying, it will have the motor current and voltage sensing built in, and we'll be able to test the functionality of the board.

At this point, the motor test stand is almost completely built, and we are almost done with the hardware. The hardware is particularly complex because each joint needs ball bearings to make friction negligible, and there are some odd mechanical linkages that we need to account for.

I'll post more later this week when we (hopefully!) have a test stand up and running.