I have no idea what the power draw of the receiver is, but I suspect it's pretty negligible - Probably less than 100mAh. Most of the receiver packs that ship with radio systems are about 1200mAh to 2000mAh. They last multiple flights (usually an hour or more) and they have to power the servos too, which obviously pull a lot of power.
The missing NAK & i2cStop calls are supposed to be there. The QuadX code currently only uses the gyro, but the ITG/ADXL driver is shared between that code and a version I'm working on that includes self-leveling. That code actually works, and is quite stable, but before I had a chance to finish tuning and cleaning it up I had a crash that wrote off my board (hence the previous post with my new frame). Once I have a platform with a gyro & accel combo up & running again, I can finish up the full stability code.
Jason,
Excellent project, thanks for sharing. I was wondering if you could outline the logic you are planning on using for self leveling. I have been experimenting with using a flight board driven by a separate propeller board. The idea is to leave the low level stabilization (more or less what you have done) to a separate board and use accelerometers and/or a full IMU on the propeller board to stabilize. Your project makes it possible to include the basic rate stabilization on the propeller as well, but I am interested in the next step, the auto-leveling. Being lazy, I am looking at a sensor that includes all IMU functionality built-in http://www.pololu.com/catalog/product/1256
However, I cannot persuade myself that this can work reliably in all situations. In a perfect case, if the frame is perfectly symmetric, the x-y acceleration would be zero and the z would be -1G, so during flight we can use that as the set point for the controller (let's leave out KF and EKF for now), and effectively use the rate as control input and accelerations as the plant. The problem I see with this is that any kind of external disturbance would make the quad drift, and I am not sure the accuracy of the accelerometers is good enough to really stay level. Also, if the frame is not symmetric, the 'zero' point would have to be determined during flight, effectively the pilot would have to first set the quad to as perfect hover as possible, then hit a button to indicate that this is 'zero', so the controller can now seek that as the goal. In any case, I am going to try this one way or another, but would love to hear your approach to auto-leveling.
As you say, the operator has to set what zero level is, but that's going to be the case regardless - You can't guarantee that the chips will be level on the board, that the board will be level in the craft, etc.
Ignoring those details, I've implemented the DCM attitude estimator and I use the info from the DCM to compute the pitch and roll angles of the craft with respect to ground. I use the stick inputs to determine my desired pitch and roll angles, and normal PIDs to run the motors based on those two angles. I use the current gyro readings as the derivative values instead of computing them.
Since then I've improved the code so it maintains 24 bits of accuracy instead of 15 (still using fixed point math). I have some more tweaks to make and things to try, but it is already self stable. It currently runs at 250Hz, but it's very close to going over that, and I haven't added the compass yet so I have some optimizing to do, too.
For zeroing, most radios have trim levers on them. In flight, if you use the trims to adjust your desired angle until the craft is level, you now have a vector for what level *really* is for the craft - it's the opposite of the trimmed control inputs. You could then turn on the craft, hit a button to read the current "trimmed" value and set that as the correction factor for the accelerometer inputs, zero your trims and fly.
Jason,
Are you ever going to post your completed code for those of us who are rolling our own hardware and not using the HoverFly boards?
Regards,
TCIII
I know it probably seems like I'm dragging my feet on it, but I killed another motor with a light crash last weekend and I'm still waiting for its replacement. I think the code is solid, but I was in the middle of some changes when the crash happened, so until I can verify everything's right I don't want to release it.
What's been done recently:
- RC_Receiver - I shaved off 3 instructions per channel from the input test code, so it'll be a little more accurate, or just support more channels with identical accuracy. I've also made it support -any- pins, not just sequential pins from 0.
- Servo8Fast - I've figured out how to make this code configurable, so I don't need "banks" anymore - you just tell the thing which pins you want, and as long as there are 8 or fewer it just works, and supports 250hz or 50hz updates, configurable for each of the 8 pins. (I can't remember if I've implemented this for my own quad, or just the HoverFly board - one of the things I have to check)
- Filtering - I've added a configurable low-pass filter to the gyro inputs. It's dirt simple code, but it makes a big difference in the stability. It made a HUGE difference when used on the accelerometer inputs for the DCM / self leveling version.
- ITG/ADXL driver - This code now has values in the DAT section for the I2C IDs, allowing quick changes between different variants of the ITG and ADXL
There are a couple others, but I think that's the bulk of it. As soon as that motor gets here and I can wire it up, I'll try to get everything out.
Jason I just appreciate the fact you are sharing your knowledge with all of us. I am going to use your code made for the Hoverfly board first and if that's succussfull I am going to mount an IMU to a Prop proto board and maybe add something simple like a light show into another cog (in no way interfering with your flight code and flight resources). By the way I tried my darnedness to guess what you made with your CNC, I would have never guessed a table!
Ditto on what rat said. Your code plus the Hoverfly open board that's supposedly on the way seems like it will really open up some interesting - and easy to try - DIY possibilities.
This is the code as it currently sits on my machine. The GroundStation is the same as the one for the Sport.
The code assumes you're using a SparkFun ITG3200 breakout as the gyro, and sets the I2C address accordingly. It (and the one for the ADXL that isn't actually used by the flight code) can be set in the ITG-3200-pasm.spin file toward the end.
Main-GyroOnly.spin is the top object file, and the motor indices are labeled in the code - they ascend clockwise from the front-left motor (for X) or front motor (for +), and the code assumes that the first motor spins counter clockwise.
I still don't have a flying quad, so I can't verify that this actually works, but I'm pretty sure does. Perhaps a brave soul among you can try it and let me know, but failing that I should have something flying shortly after my new motor arrives and will post here if anything is amiss.
I finally had some free time to work on my Elev8 build today. It's been on the shelf since I received it.
A few frustrations so far (not enough 1" screws, for example). My biggest problem at the moment is that the three wire plugs don't fit my AR8000 receiver. They are just a smidge wider than a normal servo plug and the AR8000 is quite rigid on that. Has anyone successfully mated them?
You can usually sand them or shave them with a razor to make them fit. Some plugs are square, some have the corner trimmed down, others have a little tab on them. Don't be afraid to modify the shape as long as you avoid the electrical connectors themselves.
Jason I was comparing your QuadX-V2 code with the code for the Hoverflysport board you posted in the Builder's forum. I notice mainly they follow the same line. I also noticed the difference in your PID settings for the 2 craft. The Elev-8 has
PitchRoll_PGain long $10_0000
PitchRoll_IGain long $0
PitchRoll_DGain long $1500_0000
PitchRoll_D2Gain long 0 '$1000_0000
Yaw_PGain long $28_0000
Yaw_IGain long $0
Yaw_DGain long $1800_0000
and your quad has
PitchRoll_PGain long $9_6000 '2400 << 8
PitchRoll_IGain long 400
PitchRoll_DGain long $0A00_0000 '2560 << 16
PitchRoll_D2Gain long $4000_0000 '16384 << 16
Yaw_PGain long $24_0000 '10240 << 8
Yaw_IGain long 400
Yaw_DGain long $1400_0000 '6400 << 16
Maybe it is too much to explain here but I wonder if you could tell us how you go about your working out the PID for the 2 different craft?
Honestly it's trial and error. I typically make independent settings for roll and pitch so I can compare them in flight. The values you posted are pretty close to each other. The differences are probably just a scale change from one set to the other (or close to it) resulting from the weight difference between the two.
I typically change the D gain until it starts to fight itself, back off by 30 to 50%, then bring up the P gain. You generally make changes on the order of 50 to 100% at a time, 30 when you're close to ideal. I know that's not a lot to go on, but it's mostly by feel. I test the response with it held at arms length to see how it resists external force, then when I'm close there I head outside. It's very iterative.
The calculator in Windows has a hex mode. Type a number in when it's in hex, then hit the Dec button and it'll convert it for you. I'll do it, but you can convert it pretty quick this way. And really, the exact numbers don't matter so much - you change the values in increments until they behave the way you want to.
Hi, i just finished my QuadX-PCB and want to test it, now my problem is,that i'm using the com1-serial-port (with max3232)
this won't work with the groundstation.
Could you tell me which parameters to change in the groundstation source and which version of Visual Studio to be use.
Visual C# express should work, but I think it's written in DevStudio 2008. In the MainForm.cs file, I have a line that looks for the available com ports, filters out Com1-Com4, and tries whatever is left. Change that code to just use COM1 all the time and that'll work. I'm on a mobile right now - if you're having trouble with that description, let me know and I'll send you the actual code changes when I'm at my PC next.
Why has no one said this yet: Your new frame looks amazing (post #29)! Ever thought of selling the CNC'd bits? Have you been able to stick a camera on it yet to see it's suitability as a FPV frame (i.e. is it nice and rigid)?
Thanks, Jamma! Yes, it's very rigid and quite strong - it's survived a couple of dead-stick falls onto pavement from 8 to 10 feet up. The parts are delrin, so they aren't inexpensive, but not too bad. I have considered selling them, but I want to try a few variations to get he weight and cost down a little.
I have built a camera gimbal, but I need to make taller landing gear to make enough clearance for it (it mounts underneath).
If you're interested in a set, PM me and I'll figure out what it would actually cost. I don't keep track when I'm just making them for me.
I have finished my open board wired to the QuadX V2 specs (sorry Ken, couldn't wait for an open board!) and loaded your last posted version and it seems to work (the protoboard is just laying on top of the chassis), at least I have throttle control and all the props are spinning the right direction! As soon as I figure a way to mount it I will insert the PID's from your Hoverfly sport program and give it a test. I put in a 10 row servo connector just in case you come up with some other goodies. It was very easy to assemble - not to much soldering.
Today I think I have my homemade board working with your QuadX-V2 code with the Elev-8 PID's. It finally feels like it has the proper response when moved by hand. I just had to set my gyro address, gyro orientation (2 for my setup), and the last thing I would like to check with you Jason is the P8 - P11 motor pins. The way you have them described in the below code "comments" the OUT_ BR and OUT_BL seems reversed for me to get a "feel good" response. I know the variable name should explain it but can you let me know if this is backwards for the X configuration?
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'' Motor pins for '+' shaped frame config
OUT_F = 0 ' Front ESC
OUT_R = 1 ' Right ESC
OUT_B = 2 ' Back ESC
OUT_L = 3 ' Left ESC
'' Motor pins for 'X' shaped frame config
OUT_FL = 0 ' Front Left ESC
OUT_FR = 1 ' Front Right ESC
OUT_BR = 2 ' Back Left ESC
OUT_BL = 3 ' Back Right ESC
Dave - I reversed those outputs for the Elev-8 board to match HoverFly's configuration, and obviously forgot to update the comments. To check it, hold the quad by the middle, and spin the motors up a little (doesn't need to be much). Tipping the quad in any direction should cause the motors on the side that dips to speed up. Check that it behaves this way tipping it both left/right and front/back. If it's doing that for you, then everything's correct.
It's also a good idea to double check that the yaw is responding correctly. Diagonally opposite pairs of the motors should speed up & slow down to resist twisting. Make sure that's correct before you lift off by spinning up the props enough to make it a little light on the ground, then grab it and turn it a little by hand. It should try to correct the heading back to where it was.
Comments
Jason,
Excellent project, thanks for sharing. I was wondering if you could outline the logic you are planning on using for self leveling. I have been experimenting with using a flight board driven by a separate propeller board. The idea is to leave the low level stabilization (more or less what you have done) to a separate board and use accelerometers and/or a full IMU on the propeller board to stabilize. Your project makes it possible to include the basic rate stabilization on the propeller as well, but I am interested in the next step, the auto-leveling. Being lazy, I am looking at a sensor that includes all IMU functionality built-in http://www.pololu.com/catalog/product/1256
However, I cannot persuade myself that this can work reliably in all situations. In a perfect case, if the frame is perfectly symmetric, the x-y acceleration would be zero and the z would be -1G, so during flight we can use that as the set point for the controller (let's leave out KF and EKF for now), and effectively use the rate as control input and accelerations as the plant. The problem I see with this is that any kind of external disturbance would make the quad drift, and I am not sure the accuracy of the accelerometers is good enough to really stay level. Also, if the frame is not symmetric, the 'zero' point would have to be determined during flight, effectively the pilot would have to first set the quad to as perfect hover as possible, then hit a button to indicate that this is 'zero', so the controller can now seek that as the goal. In any case, I am going to try this one way or another, but would love to hear your approach to auto-leveling.
As you say, the operator has to set what zero level is, but that's going to be the case regardless - You can't guarantee that the chips will be level on the board, that the board will be level in the craft, etc.
Ignoring those details, I've implemented the DCM attitude estimator and I use the info from the DCM to compute the pitch and roll angles of the craft with respect to ground. I use the stick inputs to determine my desired pitch and roll angles, and normal PIDs to run the motors based on those two angles. I use the current gyro readings as the derivative values instead of computing them.
The DCM code is very close to what I posted here: http://forums.parallax.com/showthread.php?131022-Propeller-DCM-Now-with-source
Since then I've improved the code so it maintains 24 bits of accuracy instead of 15 (still using fixed point math). I have some more tweaks to make and things to try, but it is already self stable. It currently runs at 250Hz, but it's very close to going over that, and I haven't added the compass yet so I have some optimizing to do, too.
For zeroing, most radios have trim levers on them. In flight, if you use the trims to adjust your desired angle until the craft is level, you now have a vector for what level *really* is for the craft - it's the opposite of the trimmed control inputs. You could then turn on the craft, hit a button to read the current "trimmed" value and set that as the correction factor for the accelerometer inputs, zero your trims and fly.
Are you ever going to post your completed code for those of us who are rolling our own hardware and not using the HoverFly boards?
Regards,
TCIII
Thanks for the update. Most encouraging.
Regards,
TCIII
What's been done recently:
- RC_Receiver - I shaved off 3 instructions per channel from the input test code, so it'll be a little more accurate, or just support more channels with identical accuracy. I've also made it support -any- pins, not just sequential pins from 0.
- Servo8Fast - I've figured out how to make this code configurable, so I don't need "banks" anymore - you just tell the thing which pins you want, and as long as there are 8 or fewer it just works, and supports 250hz or 50hz updates, configurable for each of the 8 pins. (I can't remember if I've implemented this for my own quad, or just the HoverFly board - one of the things I have to check)
- Filtering - I've added a configurable low-pass filter to the gyro inputs. It's dirt simple code, but it makes a big difference in the stability. It made a HUGE difference when used on the accelerometer inputs for the DCM / self leveling version.
- ITG/ADXL driver - This code now has values in the DAT section for the I2C IDs, allowing quick changes between different variants of the ITG and ADXL
There are a couple others, but I think that's the bulk of it. As soon as that motor gets here and I can wire it up, I'll try to get everything out.
Now that you have completed the HoverFly Sport Propeller code, do you plan to release your code for the DIYers?
Regards,
TCIII
The code assumes you're using a SparkFun ITG3200 breakout as the gyro, and sets the I2C address accordingly. It (and the one for the ADXL that isn't actually used by the flight code) can be set in the ITG-3200-pasm.spin file toward the end.
Main-GyroOnly.spin is the top object file, and the motor indices are labeled in the code - they ascend clockwise from the front-left motor (for X) or front motor (for +), and the code assumes that the first motor spins counter clockwise.
See this post for details on the use of the GroundStation software: http://forums.parallax.com/showthread.php?133372-Ken-Cluso99-W9GFO-JasonD-s-QuadCopter-Build-Log-(updated-info-ELEV-8-availability)&p=1070625&viewfull=1#post1070625
I still don't have a flying quad, so I can't verify that this actually works, but I'm pretty sure does. Perhaps a brave soul among you can try it and let me know, but failing that I should have something flying shortly after my new motor arrives and will post here if anything is amiss.
Thanks for the updated code. Much appreciated. Will try it out on my DIY Gadget Gangster Propeller board tonight.
Regards,
TCIII
A few frustrations so far (not enough 1" screws, for example). My biggest problem at the moment is that the three wire plugs don't fit my AR8000 receiver. They are just a smidge wider than a normal servo plug and the AR8000 is quite rigid on that. Has anyone successfully mated them?
and your quad has Maybe it is too much to explain here but I wonder if you could tell us how you go about your working out the PID for the 2 different craft?
I typically change the D gain until it starts to fight itself, back off by 30 to 50%, then bring up the P gain. You generally make changes on the order of 50 to 100% at a time, 30 when you're close to ideal. I know that's not a lot to go on, but it's mostly by feel. I test the response with it held at arms length to see how it resists external force, then when I'm close there I head outside. It's very iterative.
I am lost with Hex numbers , and I think other non professional programmers are.
Thanks
Hi, i just finished my QuadX-PCB and want to test it, now my problem is,that i'm using the com1-serial-port (with max3232)
this won't work with the groundstation.
Could you tell me which parameters to change in the groundstation source and which version of Visual Studio to be use.
Many thanx !
Christian
I shall be following this with great interest.
I have built a camera gimbal, but I need to make taller landing gear to make enough clearance for it (it mounts underneath).
If you're interested in a set, PM me and I'll figure out what it would actually cost. I don't keep track when I'm just making them for me.
It's also a good idea to double check that the yaw is responding correctly. Diagonally opposite pairs of the motors should speed up & slow down to resist twisting. Make sure that's correct before you lift off by spinning up the props enough to make it a little light on the ground, then grab it and turn it a little by hand. It should try to correct the heading back to where it was.
Let me know how it goes!
J