Go Down

Topic: [UPDATES] Bicopter stabilization algorith (PLEASE HELP NEEDED!!!) (Read 8335 times) previous topic - next topic

rossi86m

Hey guys,

I am building a bicopter from scratch

Using:
Arduino nano
1 mpu6050
1 hc05 for communication with an android app
2 brushless motors 2300kv
2 12a esc
2 9g servos
1 11.1v 2200 mah lipo battery

I was able to stabilize the roll using a PID, but i can not figure out how to stabilize the pitch using the servos.

I tried a PID but not sure if that is the way to go.

I still can not make a take off

I will attache the code later today since i do not have it right now

I add a couple of images of the bicopter so you have an idea of what i am doing

I hope someone can give me some guidance

Thanks!!

Marco

pert

You already created a thread for this topic:
http://forum.arduino.cc/index.php?topic=462312
why start a new one? Even if there is a good reason you should still post a link to the other thread so people can see that you have already been provided some information on the subject.

rossi86m

#2
Mar 17, 2017, 01:57 pm Last Edit: Mar 17, 2017, 02:04 pm by rossi86m
You already created a thread for this topic:
http://forum.arduino.cc/index.php?topic=462312
why start a new one? Even if there is a good reason you should still post a link to the other thread so people can see that you have already been provided some information on the subject.
Yes you are right, my mistake. Sorry for that

As pert mention i created this topic when i started the project
http://forum.arduino.cc/index.php?topic=462312

Now i made adjustment and i wanted to create a topic with all the information.

i am also adding the code here.

I am thinking of changing the copter frame in order to put the motors on the top closer between each other.

something like the image i am attaching.

Any opinion?

Thanks and sorry again,
Marco

rossi86m

Update:

I change the frame as it is shown inthe sketch. You can see how it looks like on the attachment. I think it is more stable now.

Still not able to do a take off.

Based on same test that i made the problem seems to be that response from the servos is to fast so the shoot to stabilize the pitch angle is npt gentle enough. I dont know if my code is correct.

Can someone help ke with that?

I will upload a video soon also

Thanks
,Marco

MartinL

#4
Mar 19, 2017, 07:47 pm Last Edit: Mar 19, 2017, 07:56 pm by MartinL
Hi Marco,

In your code you're only using the gyroscope X and Y axis for roll and pitch, you'll also need to read the Z axis for yaw.

For the motors use the analogWrite() function rather than the servo library. To use analogWrite() at 490Hz on the Nano use digtal pins 3, 11, 9 or 10. (Pins 5 and 6 operate at a higher frequency, too high for the ESCs). The servo library operates at 50Hz and this frequency is not enough to allow the motor ESCs to stabilise the dualcopter.

Finally, I'd comment out the accelerometer and complementary filter code for now. Before you can implement auto-level you'll need to set-up the dualcopter using only the gyroscope, with the input from the pilot converted to degrees/s. This is variously called aero/rate/gyro mode and will ensure that you have your inner gyroscope roll, pitch and yaw rate PIDs tuned correctly. This is necessary before moving on to auto-level. For the PIDs, initially tune using the P term only. You'll be able to fly using the P term alone. Add the I and D terms after you get airborne.

To test the dualcopter I'd first remove the props and test it on the bench. You'll know when it's working properly, because with zero pilot input (0 degrees/s on roll, pitch and yaw) and a little bit of throttle, the motors and servos will oppose the aircraft's motion in an attempt to stabilise it.

Your dualcopter looks cool, by the way, something out of the ordinary.

rossi86m

Hi Marco,

In your code you're only using the gyroscope X and Y axis for roll and pitch, you'll also need to read the Z axis for yaw.
Yes i konow i am just focusing first in pitch and roll, thanks for that!

For the motors use the analogWrite() function rather than the servo library. To use analogWrite() at 490Hz on the Nano use digtal pins 3, 11, 9 or 10. (Pins 5 and 6 operate at a higher frequency, too high for the ESCs). The servo library operates at 50Hz and this frequency is not enough to allow the motor ESCs to stabilise the dualcopter.
I made a switch i put the servos on 5 and 6 and the esc on 9 and 10. Can you give me an example on how to use the analovwrite? Thanks!

Finally, I'd comment out the accelerometer and complementary filter code for now. Before you can implement auto-level you'll need to set-up the dualcopter using only the gyroscope, with the input from the pilot converted to degrees/s. This is variously called aero/rate/gyro mode and will ensure that you have your inner gyroscope roll, pitch and yaw rate PIDs tuned correctly. This is necessary before moving on to auto-level. For the PIDs, initially tune using the P term only. You'll be able to fly using the P term alone. Add the I and D terms after you get airborne.
Do you mean using the raw values from the gyro??

I just hope to make a successful take off

Looking forward to reading your anwers.

Marco

MartinL

#6
Mar 20, 2017, 08:48 am Last Edit: Mar 20, 2017, 11:40 am by MartinL
Hi Marco,

Quote
I made a switch i put the servos on 5 and 6 and the esc on 9 and 10. Can you give me an example on how to use the analovwrite? Thanks!
The analogWrite() function has two parameters: pin number and value. The value is a number between 0 and 255, so it's necessary to map/convert from your 0us - 2000us ESC values to 0 - 255.

For example to set the motor PWM to mid-throttle on digital pin 9 (50% duty cycle):

Code: [Select]
analogWrite(9, 127);
Here's a link to the analogWrite (PWM) page: https://www.arduino.cc/en/Reference/AnalogWrite.

Quote
Do you mean using the raw values from the gyro??
I used the wrong terminology, I meant just using the gyroscope's values coverted to degrees per second.

Another thing, the MPU6050 has an in built low pass (anti-aliasing) filter. For multi-rotor applications this has to be set at around 20Hz to 40Hz. Using Jeff Rowberg's I2CDev library, you can set it with the following line in your setup() code:

Code: [Select]
mpu.setDLPFMode(MPU6050_DLPF_BW_20);
Finally, I'd also strongly recommend adding to your code an ARM/DISARM interlock for your motors. This can take the form of a button, stick movement or arm switch to allow you to remotely enable and disable your motors before and after flight. It just ensures that your motors won't burst into life if you accidentally knock the throttle stick (or whatever you're using to control the throttle), while connecting or disconnecting the battery.

rossi86m

Quote
The analogWrite() function has two parameters: pin number and value. The value is a number between 0 and 255, so it's necessary to map/convert from your 0us - 2000us ESC values to 0 - 255.
I will do the map. And use analogwrite
I thought that analogWrite would also need some delay in order to generate the same signal than writemiliseconds.

Quote
I used the wrong terminology, I meant just using the gyroscope's values coverted to degrees per second.

Another thing, the MPU6050 has an in built low pass (anti-aliasing) filter. For multi-rotor applications this has to be set at around 20Hz to 40Hz. Using Jeff Rowberg's I2CDev library, you can set it with the following line in your setup() code:
Thanks for this, i will remove the filter code and use what you suggested.
Code: [Select]
mpu.setDLPFMode(MPU6050_DLPF_BW_20);

Quote
Finally, I'd also strongly recommend adding to your code an ARM/DISARM interlock for your motors. This can take the form of a button, stick movement or arm switch to allow you to remotely enable and disable your motors before and after flight. It just ensures that your motors won't burst into life if you accidentally knock the throttle stick (or whatever you're using to control the throttle), while connecting or disconnecting the battery.
I will use a button for this on my android app. I have already got a finger cut because of what you mentioned  :)

I will do the adjustments today and let you know the results

Thanks!!!

MartinL

Quote
I thought that analogWrite would also need some delay in order to generate the same signal than writemiliseconds.
Using AnalogWrite() there's minimal delay, as it will output the new value on the next PWM timer cycle. At 490Hz the selected pin will automatically produce a new pulse every 2.04ms (1/490Hz).

rossi86m

Quote
Using AnalogWrite() there's minimal delay, as it will output the new value on the next PWM timer cycle. At 490Hz the selected pin will automatically produce a new pulse every 2.04ms (1/490Hz).
I made the code adjustments that you suggested. I still wasn't able to check the code in arduino, but do you mind having a look at it?

Any other suggestion is welcome

Thanks a lot,
Marco

MartinL

Hi Marco,

I had a look at your code.

AnalogWrite() is not a member function of the servo library, but a function in it's own right, so you can just call it without the "motor1" and "motor3" prefix:

Code: [Select]
analogWrite(9, 127);
You're assigning the accelerometer Z-axis rather than the gyroscope Z-axis, as an input of your yaw rate PID.

rossi86m

Hi Marco,

I had a look at your code.

AnalogWrite() is not a member function of the servo library, but a function in it's own right, so you can just call it without the "motor1" and "motor3" prefix:

Code: [Select]
analogWrite(9, 127);
You're assigning the accelerometer Z-axis rather than the gyroscope Z-axis, as an input of your yaw rate PID.
You are right!!

I will make the adjustments and test them.

Thanks!!!

Marco

rossi86m

You're assigning the accelerometer Z-axis rather than the gyroscope Z-axis, as an input of your yaw rate PID.
I have read that i would need a compass to get that value is that right? or is there a way to get z-axis gyro from mpu6050?

MartinL

#13
Mar 23, 2017, 09:22 am Last Edit: Mar 23, 2017, 09:31 am by MartinL
Quote
I have read that i would need a compass to get that value is that right? or is there a way to get z-axis gyro from mpu6050?
A compass isn't necessary for piloted modes such as rate or auto-level. You only need a compass if you're implementing GPS automated flight modes such as loiter or return to home, where the flight computer needs to know its heading.

The MPU6050 contains a 3-axis gyroscope that has a Z-axis for yaw, it's just that your code isn't yet reading it from the device.

With regard to your question, it means is that you can use your accelerometer X, Y and Z axes (with some trigonometry) to calculate the roll and pitch angle, but the accelerometer itself is unable to measure yaw angle (heading), for that you need a compass. In other words the accelerometer has no means of knowing where magnetic north is located.

To implement rate mode you'll need the gyroscope X, Y and Z axes, as inputs to your rate roll, pitch and yaw PIDs.

rossi86m


To implement rate mode you'll need the gyroscope X, Y and Z axes, as inputs to your rate roll, pitch and yaw PIDs.
[/quote]

Should i add this?

Code: [Select]

Wire.requestFrom(MPU, 6, true);
GyZ = Wire.read() << 8 | Wire.read();


OR this

Code: [Select]

mpu.getMotion6(& AcX, & AcY, & AcZ, &GyX, &GyY, &GyZ);


Thanks

Go Up