Elevon Math?

I'm trying to program elevon mixing. Does anyone know the mathematical relationship between the Elevator and Aileron? I'm trying to write a function that receives the two servo variable names and preforms the task.

(im going to be using the simple servo class; ie servo1.write(90);)

From what i can figure out, if I want to program the Aileron relationship in an Elevon configuration; the values should match since one servo is laying to the right and the other is laying to the left - so equal values should give it opposite motion.

If I'm programming the Elevator relationship in a Elevon configuration; the value of the Elevator from 90 deg creates an offset that i apply to the aileron servo - so if the elevator is at 100 deg, the offset is 10 and the aileron should be sent the value of 80 deg.

(I think thats right)

What is the best way to program this? Will i get jitter if i send aileron and elevator input at the same time? How can I translate this theory into code in the form of a nice function I can call if the "elevon" boolean is true?

Thanks for your time.

Am i on the right track? Am I missing something?

I would guess you just use vector math. Do the reverse of deteriming the X and Y component of a iX+jY vector. Beech’s used mechanical mixing, so it can’t be that hard.

I doubt if this is a "maths formula" question. As far as I know some real aircraft only use the elevator on one side for gentle movements, but then they have things the size of garage doors when some real oomph is required. (I've often wondered where they get the power to open a garage door in a 250mph wind!).

You haven't said where your inputs are coming from?

Do you have a working model of the same aircraft from which you can copy the relationship between aileron stick movement and aileron movement and between elevator stick movement and elevator movement (I do realize that in this case the aileron and elevator is the same device, but you could figure out the separate relationships.

If you don't I suspect you are in for a long period of trial and error - hopefully without crashes. I suspect a good rule of thumb would be "less is more". If you are not already a competent RC pilot I wouldn't even try unless you have a large bank balance that you don't like.

I doubt if the relationships are linear. What I mean is that 5 deg of elevator movement with no aileron movement would probably have a different effect from 5 deg of elevator with full aileron.

Which brings up another interesting question - how can you have full elevator and full aileron at the same time?

Once you have figured out what the mechanical things should do the programming should be fairly easy. In effect you do two calculations and merge the results before sending a single signal to each servo.

Looking forward to seeing video of it flying.

...R

This is the code i came up with and it seems to work; I'll have to hook it up to my plane to truely test - that will have to wait until the pcb is printed:

if(elevon){                            //perform elevator and aileron mixing
          
            offset = pos[1] - 90;           //elevator position - 90
            int mix = pos[0]+offset;      //offset aileron
            int mix2 = pos[0]-offset;     //offset elevator
            
            if(pos[0] == 0){                  //account for lost packets
              servo1.write(posArray[0]); //write previous pos
              //print to lcd  
            }else{                                //if no error, print to aileron servo
              servo1.write(mix);              
              posArray[0] = mix; 
              //print to lcd          
            }
            if(pos[1] == 0){                    //account for lost packets
              servo2.write(posArray[1]);   //write previous pos
              //print to lcd
            }else{                                  //if no error, print to aileron servo
              servo2.write(mix2);
              //print to lcd
            }
            
          }else{
           //DO REGULAR MOVEMENT
          }

A few things occur to me from looking at your code.

If I lost a packet from one control (pos[0]) but not the other (pos[1]) I think I would be worried about using either value. I suspect a better integrity check would be an expectation that the new values are not too different from the previous ones.

I don't understand why you have "if (elevon)". Is your code also meant to work in a plane without elevons? Is that wise?

Does it matter to your application if Servo.write(90) doesn't move both servos the the exact same position?

When you mention a PCB being printed I assume that the Arduino on the circuit board will be flying in the plane. Have you seen these DelTino devices http://www.deltino.com/ which come ready made with a 2.4Ghz transceiver, and are very small and light. Also look at the Deltang page.

...R

Robin2: If I lost a packet from one control (pos[0]) but not the other (pos[1]) I think I would be worried about using either value. I suspect a better integrity check would be an expectation that the new values are not too different from the previous ones.

this is exactly what I'm doing. posArray[] is initialize (not shown in snippet) with a starting value of {90,90,90,145} //A,E,R,T; so when the loop runs the first time, the servos are centered, but when you give it an input, that input is replaced in the array and is now the "previous pos."

I don't understand why you have "if (elevon)". Is your code also meant to work in a plane without elevons? Is that wise?

This snippet is part of a larger program, reading toggle inputs and other feedback from the arduino. (yes)

Does it matter to your application if Servo.write(90) doesn't move both servos the the exact same position?

I dont understand this one...if you give both servos the same info, they should respond the same.

When you mention a PCB being printed I assume that the Arduino on the circuit board will be flying in the plane. Have you seen these DelTino devices http://www.deltino.com/ which come ready made with a 2.4Ghz transceiver, and are very small and light. Also look at the Deltang page.

...R

yes I have, but like many on the forum...its fun to do it yourself :) (and learn while doing it)

I dont understand this one...if you give both servos the same info, they should respond the same.

Not if the servo CAN'T move to the commanded position. Also, the assumption is made that both servos are adjusted exactly the same.

PaulS: Not if the servo CAN'T move to the commanded position. Also, the assumption is made that both servos are adjusted exactly the same.

How do you fix that?

Your response suggests that I didn't make myself as clear as I should have. You have two separate IF statements to check whether either pos[0] and pos[1] == 0. You only ignore the one that is 0. I suggest you should ignore BOTH of them because there it seems unlikely that one would be right while the other is wrong.

[quote author=Keith Brown link=topic=176510.msg1310734#msg1310734 date=1373453838]

Robin2: If I lost a packet from one control (pos[0]) but not the other (pos[1]) I think I would be worried about using either value. I suspect a better integrity check would be an expectation that the new values are not too different from the previous ones.

this is exactly what I'm doing. posArray[] is initialize (not shown in snippet) with a starting value of {90,90,90,145} //A,E,R,T; so when the loop runs the first time, the servos are centered, but when you give it an input, that input is replaced in the array and is now the "previous pos." [/quote]

You will probably be better using Servo.writeMicroseconds with your servos in place of Servo.write which uses degrees. You will need to experiment with each servo to find out what number of microseconds corresponds to the centre point (nominally 1500) and the extremes. You may then need to store correction factors in your program.

...R

How is the Microseconds method more beneficial? I never used that, just curious- thanks

With the microseconds method you have a much wider range of servo positions - for example some will go "lower" than 0 degrees and many have a full range from left to right greater than 180 degrees. As far as I know the servo library has some arbitrary minimum and maximum(?) microsecond values which can be changed by hacking the code if necessary to make full use of a servo. (I've done this with the ServoTimer2 library).

...R

[quote author=Keith Brown link=topic=176510.msg1311187#msg1311187 date=1373473614] How is the Microseconds method more beneficial? I never used that, just curious- thanks [/quote]

It's more granular than the write method, which uses it to do its own job.

The point is that servos contain analog components and thus, a pair of servos of the same type and manufacturer will likely not behave exactly the same way. You'll need to determine by experiment where the null elevon point is for each servo and writemicroseconds gives you finer control to dial it in just right for each servo.

wildbill: It's more granular than the write method, which uses it to do its own job.

The point is that servos contain analog components and thus, a pair of servos of the same type and manufacturer will likely not behave exactly the same way. You'll need to determine by experiment where the null elevon point is for each servo and writemicroseconds gives you finer control to dial it in just right for each servo.

Thanks a lot for the explanation. I think it would be a bit much at this point to change my program. There is a serial input that broadcasts the degree value, unless i can write a function to convert it.. I wouldnt know how to do that though