General servo handler - almost done

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

General servo handler - almost done

Post by Mis »

Hi.
I started write code for universal servo mixer.

General rules:
SERVO1 is always used as Camstab PITCH servo (except HEXA on promini with A0_A1_PIN_HEX)
SERVO2 is always used as Camstab ROLL servo (except HEXA on promini with A0_A1_PIN_HEX)
SERVO3 is always used as CAMTRIG servo or traditional FLAPS servo
SERVO8 is always used as Motor output (if no MOTOR1 output is used for motor control)
SERVOS 4..7 are used depending selected model

Flying Wing : 4-left wing, 5-right wing
Airplane : 4-left wing, 5-right wing, 6-rudder, 7-elevator
SingleCopter : 4,5-side servos, 6-front, 7-rear
DualCopter : 5-Pitch servo, 6-Roll servo
BI : 5-left servo, 6-right servo
TRI : YAW servo on servo 6 or servo 4 in MEGA2560 boards with HW_PWM's
HELI: 4,6,7 - swashplate servos, 5-rear servo or rear motor (MOTOR2 output can be used too for rear motor)

All servos are configured via servoConf structure:
servoConf[].min - MIN endpoint (should be in range 1020..1500 with SW_PWM's or 400..1400 with MEGA boards with HW_PWM's)
servoConf[].max - MAX endpoint (should be in range 1500..2500)
Warning : max must be higher than min. With endpoints below 1020 and over 2000 servos are stretched with HW_PWM's. Not proportional setting of min and max cause some neurtal point shift, but this can be corrected with servoConf[].middle.
servoConf[].middle work in two ways. Values in range higher than number of RC channels (eg 1000..2000) sets midpoint to entered value.
Values in range 0..RC channels (8,12,16) enable midpoint control via one of RC Channel (any channel can be used, not only AUX channels)
This is easy way for gimbal control and flaps control via AUX channels or even YAW channel on flying wing.
servoConf[].rate - in some cases simply control rate and direction of servos. Should be witchin range -120..120.
This mode are used for gimbal and airplane. In other cases rate variable holds only reverse flags for individual servos and axis.
The reverse flags are coded at individual bits from rate. In example for the flying wing, rate for each wing serwo holds reverse flag for PITCH axis (BIT0) and for ROLL axis (BIT1).

About CAMTRIG. Camtrig interval can be set at constant value writed to servoConf[2].middle (time in msecs) or can be controlled via an AUX poti/switch.
In AUX controlled mode (servoConf[2].middle value lower than RC_CHANS) the interval control range is from about 2sec to 60sec.

Most of work is done, but some ideas need to be tested.
Now I tested Camstab,Camtrig,Airplane and Flying wing.
AND... We need GUI with servo configuration tab.

For now I have my small application to setup servos and misc configuration. Available at http://romek_by.republika.pl/MK/ServoMiscConf_v06.exe
Software is available as r1421 in _shared folder.
Last edited by Mis on Fri Sep 13, 2013 6:58 pm, edited 1 time in total.

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: General servo handler - almost done

Post by Alexinparis »

Hi,

I think it's a nice basis to extend servo usability.

some comments

servo stretching:

Currently, the min&max are here to set physical angle barrier.
I think the possibility to extend the min&max values (below 1020 and after 2000) should be just a way to extend the limits.
I'm not a fan of using a map() function to explicitly stretch an interval (and map() is very math costly)

Code: Select all

servo[i] = map(servo[i], 1020,2000, conf.servoConf[i].min, conf.servoConf[i].max);       // servo travel scaling


Code: Select all

  for(i=0; i<7; i++) servo[i] = 0;

you should know exactly for each model which servo to activate or not. so why spending some cycles to zero everything?

models that do not use servo
should not be impacted
I think #if defined(SERVO) should be inserted in different parts to isolate code.

SERVO_TILT
the rc signal superposition is no more possible

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Ok, now the servo calculations are isolated by #if defined(SERVO), and precalculation of first and last used servos is done, then for(i...) loops is limited to only used servos. After some tests I commit this changes.
What you mean "the rc signal superposition is no more possible"
You can control the gimbal servos via RC signal. Just set conf.servoConf[0].middle to value of 5 (corresponded to AUX2), and you can control cam pitch via AUX5.
The same rule is aplied to all servos.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: General servo handler - almost done

Post by nhadrian »

Mis wrote:Ok, now the servo calculations are isolated by #if defined(SERVO), and precalculation of first and last used servos is done, then for(i...) loops is limited to only used servos. After some tests I commit this changes.
What you mean "the rc signal superposition is no more possible"
You can control the gimbal servos via RC signal. Just set conf.servoConf[0].middle to value of 5 (corresponded to AUX2), and you can control cam pitch via AUX5.
The same rule is aplied to all servos.


Hi,

may I ask you how to setup the conf.servoConf values for camstab servos???

I see the defaults in the EEPROM file, but there is no such settings on the settings tab in the GUI (I'm using the latest from Shared).
I think your global servo handling will be usable only when the settings will represent in the GUI!

Looking forward to your solution.

BR
Adrian

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hi Adrian.
Download my little configurator : http://romek_by.republika.pl/MK/ServoMiscConf.exe and setup all servo parameters with it.
BTW, Updated, with servo, motor and RC signal monitor.

Tifani
Posts: 63
Joined: Sun Nov 06, 2011 5:15 pm

Re: General servo handler - almost done

Post by Tifani »

Czesc!
Norton nie lubi Twojego programu ;)
Pozdrowienia
Tomek

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: General servo handler - almost done

Post by nhadrian »

Mis wrote:Hi Adrian.
Download my little configurator : http://romek_by.republika.pl/MK/ServoMiscConf.exe and setup all servo parameters with it.
BTW, Updated, with servo, motor and RC signal monitor.


Hi, unfortunatelly I'm running on MAX OS... :S
So still looking forward of having an updated GUI. (or EZ-GUI?! :D)

BR
Adrian

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

Hi Mis.

You placed some ants in my head trying to figure out how the code works...
But now i'm up running.

Some things i found.
Flaps don't seem to work.
Wing is missing brackets around the if (!f.ARMED).
Same in Airplane.

//Patrik

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hehe :-)
Flaps fixed.
ServoMiscConf updated too (added support for multiple profiles, minor bugfix, and last used COM and Speed is saved).

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

I committed a small change regading Heli YAW.

A testVersion of MultiWiiConf.zip

Tested models.
Heli 120
Airplane
F-Wing
BI
TRI

/Patrik

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Partik, can you provide compiled version of MultiwiiConf ? I'm not compatibile with Processing :roll:

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

Ok.
Compiled new file same path.
MultiWiiConf.zip

/Patrik

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: General servo handler - almost done

Post by nhadrian »

PatrikE wrote:Ok.
Compiled new file same path.
MultiWiiConf.zip

/Patrik


Hi,

I tried but there is not any additional setup / config tab. (with latest _shared we have additional tabs).
I'm running MWI1422.

BR
Adrian

User avatar
mgros
Posts: 90
Joined: Thu Jan 20, 2011 12:32 am

Re: General servo handler - almost done

Post by mgros »

nhadrian wrote:Hi,

I tried but there is not any additional setup / config tab. (with latest _shared we have additional tabs).
I'm running MWI1422.

BR
Adrian


Me too running r1426 in a HEXA. With SERVO_TILT.
Last edited by mgros on Fri May 03, 2013 10:10 pm, edited 4 times in total.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

It's a test and I haven't moved the settings to the correct MSP I the gui yet.
That's why I didn't commit to shared...
There's a servoTab if you select a model with servos.
Otherwise it's hidden.

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Servo TAB should be enabled too if camstab or camtrig is enabled. And for Bi, TRI, Heli, Flying Wing, Airplane, SingleCopter and DualCopter.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

SettingsTab Back in Gui.
MultiWiiConf.zip

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Patrik, i found some bugs in GUI
1. Airplane mode: Yaw servo rate is not working. Other servos are OK, but all reverse boxes are inverted (normally, non inverted should be gray, but are white).
2. TRI - on Mega Boards when using HW PWM's The YAW servo is not handled because the servo is moved from SERVO 6 to SERVO 4. I think that you can safetly setup values for both, SERVO4 and SERVO6 simultanously. But at main screen, the YAW servo value is getted always from servo6. For now I don't have idea how dedect TRI_YAW servo number.

And no servo setup TAB for singlecopter, dualcopter and HELI90

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: General servo handler - almost done

Post by nhadrian »

Mis wrote:Patrik, i found some bugs in GUI
1. Airplane mode: Yaw servo rate is not working. Other servos are OK, but all reverse boxes are inverted (normally, non inverted should be gray, but are white).
2. TRI - on Mega Boards when using HW PWM's The YAW servo is not handled because the servo is moved from SERVO 6 to SERVO 4. I think that you can safetly setup values for both, SERVO4 and SERVO6 simultanously. But at main screen, the YAW servo value is getted always from servo6. For now I don't have idea how dedect TRI_YAW servo number.

And no servo setup TAB for singlecopter, dualcopter and HELI90


Neither setup tab for Y6 or other multirotor with camstab...

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

Is the new servoMiddle function really neccessary for all usage Scenarios? I am asking because it gets called in the mix function every cycle?

Or coul we instead use a macro that would resolve to the regular struct value directly and only for the special case substitute the servoMiddle ivocation?

I cannot currently browse code comfortably so please bear with me. But this using rcdata value for servo midpoint seems to be rather the exception not the norm. So maybe it should be isolated and only enabled for tuning?

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

The check take about quater microsecond and cycle time impact is completely negligible.
This is usable a) for tunning, b) for gimbal control.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

I can accept tuning. If it was only gimbal control then that in my eyes would merit the conditional macro.
After all cycle time is precious still or is it not? At least we tinker with 8 vs. 16 vs. 32 bit arithmetics and un.neccessary function calls for optimization constantly. But then maybe we are getting closer to moving to superior hardware

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hamburher, look at "annex_code()". This is super time waste procedure... Lot of calculations of RC signals on every main loop cycle, but RC signal source is only 50Hz period... And calculations of dynamic PID's, Throttle Curve, and Pitch/roll rate is maked on every cycle. This is only hugue processor time wasting.
And now, You have an good job. Optimize this function :lol:

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

Mis
What are you trying to tell me?
Alex' rule to avoid extra function calls wherever possible is no longer valid?
The horrible experience from when tommie swamped the code with function calls making MWii non-flyable is forgotten?

I have accepted that the programming we do for such limited hardware requires a special coding approach. For as long as such limitations stand I will from time to time question some implementation details. Contrary to what you have done in the past I will not remove others code only because I do not want/need it. I think asking for clarification among us should be good practice and I will continue that approach.
Have fun and continue the good work

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

anyone successfully used HELI_120_CCPM with the reworked servo stuff?
By 'used' I mean beyond compile and tweaking servo presets via GUI - like real flying? I would at least like to know in advance whether updating to current new servo code base has worked for others already or will turn my perfectly working copter into an alpha test.

If so, were you just lucky that the yaw servo direction was working for you out of the box? Or did you have to use the gui to revert? Or some other means I have failed to find?

Code: Select all

    // maybe collective range can be replaced replaced by this ?
    //collective = rcData[COLLECTIVE_PITCH] - get_middle(7);               // zero pitch offset
    //collective = ((int32_t)conf.servoConf[7].rate * collective)/100L;    // collective range

I like the idea but two things
- how does using servo[7] for collective collide with when one uses a real servo to throttle the main motor - I guess in that case 'conf.servoConf[7].rate' was already needed for servo direction?
- the proposed code does not take different scaling for above/below collective midpoint - does it matter to anyone? I can certainly live without that.
Patrik, care to comment?

So far it seems like some servo settings could no longer be preset at compile time but needed manual gui interaction. Since I periodically update my copters I prefer to keep such important presets as servo limits, centers, directions in special config.h files. I am currently adding the neccessary code again.

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Yaw servo reversing: set servo5 rate to 1 (0 is no reverse) or use Servo5 first "Reverse" checkbox on my ServoMiscConf program.
Throttle servo never use conf.servoConf[7] values. All min,max,middle and rate can be used for other settings. But maybe must for gas engine helis ??
I don't know...
BTW. Some new fixes in r1431

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: General servo handler - almost done

Post by nhadrian »

Dear Mis,

couldn't you merge your servo settings additions to the Multiwii GUI?
For example I'm running on MAC OS X, and GUI works just great.
But all your servo changes are unusable without proper setup program... :(

Thanks in advance, great job!

BR
Adrian

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

BTW, some new fixes in r1432 - r1431 had unbalanced '()' for me.

@Adrian,
I think the modified MWiiGui from Patrik does support servo settings? I am about to test some of it.

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hamburger, i'm sorry, accidentally I delete one bracket (before "YAWMOTOR" in "#if defined(HELICOPTER) && (YAWMOTOR)" after testing, but before commiting to _shared :-( Thank's for correct this.
Nhadrian: I not good programist in "processing" and additionally I have some problems with compiling the GUI.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

Mis, no problem, I was fiddling with Output.ino so it was easy to find and fix. No one but me should have found time to use r1431. It is obvious you did not use the COPTERTESTs for prior checking :)
What googlecode shows for a diff is plain useless for r1432.
Here is a diff without the space/indentation differences. As always, diff is your friend with 'diff -u -bBw'

Code: Select all

--- r1431/Output.ino   2013-05-07 22:45:41.834837779 +0200
+++ r1432/Output.ino   2013-05-07 22:45:57.205830723 +0200
@@ -945,72 +945,62 @@
     axisPID[YAW] = constrain(axisPID[YAW],-100-abs(rcCommand[YAW]),+100+abs(rcCommand[YAW]));
   #endif
   /****************                   main Mix Table                ******************/
-  #ifdef MY_PRIVATE_MIXING
+  #if defined( MY_PRIVATE_MIXING )
     #include MY_PRIVATE_MIXING
-  #else
-    #ifdef BI
+  #elif defined( BI )
       motor[0] = PIDMIX(+1, 0, 0); //LEFT
       motor[1] = PIDMIX(-1, 0, 0); //RIGHT
       servo[4] = (SERVODIR(4,2) * axisPID[YAW]) + (SERVODIR(4,1) * axisPID[PITCH]) + get_middle(4); //LEFT
       servo[5] = (SERVODIR(5,2) * axisPID[YAW]) + (SERVODIR(5,1) * axisPID[PITCH]) + get_middle(5); //RIGHT
-    #endif
-    #ifdef TRI
+  #elif defined( TRI )
       motor[0] = PIDMIX( 0,+4/3, 0); //REAR
       motor[1] = PIDMIX(-1,-2/3, 0); //RIGHT
       motor[2] = PIDMIX(+1,-2/3, 0); //LEFT
       servo[TRI_SERVO-1] = (SERVODIR(TRI_SERVO-1, 1) * axisPID[YAW]) + get_middle(TRI_SERVO-1); //REAR
-    #endif
-    #ifdef QUADP
+  #elif defined( QUADP )
       motor[0] = PIDMIX( 0,+1,-1); //REAR
       motor[1] = PIDMIX(-1, 0,+1); //RIGHT
       motor[2] = PIDMIX(+1, 0,+1); //LEFT
       motor[3] = PIDMIX( 0,-1,-1); //FRONT
-    #endif
-    #ifdef QUADX
+  #elif defined( QUADX )
       motor[0] = PIDMIX(-1,+1,-1); //REAR_R
       motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
       motor[2] = PIDMIX(+1,+1,+1); //REAR_L
       motor[3] = PIDMIX(+1,-1,-1); //FRONT_L
-    #endif
-    #ifdef Y4
+  #elif defined( Y4 )
       motor[0] = PIDMIX(+0,+1,-1);   //REAR_1 CW
       motor[1] = PIDMIX(-1,-1, 0); //FRONT_R CCW
       motor[2] = PIDMIX(+0,+1,+1);   //REAR_2 CCW
       motor[3] = PIDMIX(+1,-1, 0); //FRONT_L CW
-    #endif
-    #ifdef Y6
+  #elif defined( Y6 )
       motor[0] = PIDMIX(+0,+4/3,+1); //REAR
       motor[1] = PIDMIX(-1,-2/3,-1); //RIGHT
       motor[2] = PIDMIX(+1,-2/3,-1); //LEFT
       motor[3] = PIDMIX(+0,+4/3,-1); //UNDER_REAR
       motor[4] = PIDMIX(-1,-2/3,+1); //UNDER_RIGHT
       motor[5] = PIDMIX(+1,-2/3,+1); //UNDER_LEFT
-    #endif
-    #ifdef HEX6
+  #elif defined( HEX6 )
       motor[0] = PIDMIX(-7/8,+1/2,+1); //REAR_R
       motor[1] = PIDMIX(-7/8,-1/2,-1); //FRONT_R
       motor[2] = PIDMIX(+7/8,+1/2,+1); //REAR_L
       motor[3] = PIDMIX(+7/8,-1/2,-1); //FRONT_L
       motor[4] = PIDMIX(+0  ,-1  ,+1); //FRONT
       motor[5] = PIDMIX(+0  ,+1  ,-1); //REAR
-    #endif
-    #ifdef HEX6X
+  #elif defined( HEX6X )
       motor[0] = PIDMIX(-1/2,+7/8,+1); //REAR_R
       motor[1] = PIDMIX(-1/2,-7/8,+1); //FRONT_R
       motor[2] = PIDMIX(+1/2,+7/8,-1); //REAR_L
       motor[3] = PIDMIX(+1/2,-7/8,-1); //FRONT_L
       motor[4] = PIDMIX(-1  ,+0  ,-1); //RIGHT
       motor[5] = PIDMIX(+1  ,+0  ,+1); //LEFT
-    #endif
-    #ifdef HEX6H
+  #elif defined( HEX6H )
       motor[0] = PIDMIX(-1,+1,-1); //REAR_R
       motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
       motor[2] = PIDMIX(+ 1,+1,+1); //REAR_L
       motor[3] = PIDMIX(+ 1,-1,-1); //FRONT_L
       motor[4] = PIDMIX(0 ,0 ,0); //RIGHT
       motor[5] = PIDMIX(0 ,0 ,0); //LEFT
-    #endif
-    #ifdef OCTOX8
+  #elif defined( OCTOX8 )
       motor[0] = PIDMIX(-1,+1,-1); //REAR_R
       motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
       motor[2] = PIDMIX(+1,+1,+1); //REAR_L
@@ -1019,8 +1009,7 @@
       motor[5] = PIDMIX(-1,-1,-1); //UNDER_FRONT_R
       motor[6] = PIDMIX(+1,+1,-1); //UNDER_REAR_L
       motor[7] = PIDMIX(+1,-1,+1); //UNDER_FRONT_L
-    #endif
-    #ifdef OCTOFLATP
+  #elif defined( OCTOFLATP )
       motor[0] = PIDMIX(+7/10,-7/10,+1); //FRONT_L
       motor[1] = PIDMIX(-7/10,-7/10,+1); //FRONT_R
       motor[2] = PIDMIX(-7/10,+7/10,+1); //REAR_R
@@ -1029,8 +1018,7 @@
       motor[5] = PIDMIX(-1   ,+0   ,-1); //RIGHT
       motor[6] = PIDMIX(+0   ,+1   ,-1); //REAR
       motor[7] = PIDMIX(+1   ,+0   ,-1); //LEFT
-    #endif
-    #ifdef OCTOFLATX
+  #elif defined( OCTOFLATX )
       motor[0] = PIDMIX(+1  ,-1/2,+1); //MIDFRONT_L
       motor[1] = PIDMIX(-1/2,-1  ,+1); //FRONT_R
       motor[2] = PIDMIX(-1  ,+1/2,+1); //MIDREAR_R
@@ -1039,17 +1027,13 @@
       motor[5] = PIDMIX(-1  ,-1/2,-1); //MIDFRONT_R
       motor[6] = PIDMIX(-1/2,+1  ,-1); //REAR_R
       motor[7] = PIDMIX(+1  ,+1/2,-1); //MIDREAR_L
-    #endif
-    #ifdef VTAIL4
+  #elif defined( VTAIL4 )
       motor[0] = PIDMIX(+0,+1, +1); //REAR_R
       motor[1] = PIDMIX(-1, -1, +0); //FRONT_R
       motor[2] = PIDMIX(+0,+1, -1); //REAR_L
       motor[3] = PIDMIX(+1, -1, -0); //FRONT_L
-    #endif
-
+  #elif defined( FLYING_WING )
     /*****************************             FLYING WING                **************************************/
-
-    #if defined(FLYING_WING)
       if (!f.ARMED) {
         servo[7] = MINCOMMAND;       // Kill throttle when disarmed
       } else {
@@ -1065,11 +1049,8 @@
       }
       servo[3] += get_middle(3);
       servo[4] += get_middle(4);
-    #endif
-
+  #elif defined( AIRPLANE )
     /*****************************               AIRPLANE                **************************************/
-
-    #if defined(AIRPLANE)
       // servo[7] is programmed with safty features to avoid motorstarts when ardu reset..
       // All other servos go to center at reset..  Half throttle can be dangerus
       // Only use servo[7] as motorcontrol if motor is used in the setup            */
@@ -1129,11 +1110,8 @@
         servo[i]  = ((int32_t)conf.servoConf[i].rate * servo[i])/100L;  // servo rates
         servo[i] += get_middle(i);
       }
-    #endif // airplane 
-
+  #elif defined( SINGLECOPTER )
       /***************************          Single & DualCopter          ******************************/
-
-    #if  defined(SINGLECOPTER)
     // Singlecopter
     // This is a beta requested by  xuant9
     // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
@@ -1147,9 +1125,7 @@
         servo[i] += get_middle(i);
       }
       motor[0] = rcCommand[THROTTLE];
-    #endif
-   
-    #if defined(DUALCOPTER)
+  #elif defined( DUALCOPTER )
       // Dualcopter
       // This is a beta requested by  xuant9
       // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
@@ -1170,11 +1146,8 @@
         servo[7] = motor[0];
       }
 */
-    #endif
-
+  #elif defined( HELICOPTER )
     /*****************************               HELICOPTERS               **************************************/
-
-    #ifdef HELICOPTER
       // Common controlls for Helicopters
       int16_t heliRoll,heliNick;
       int16_t collRange[3] = COLLECTIVE_RANGE;
@@ -1242,7 +1215,7 @@
         #ifdef GOVERNOR_P
           servo[7] += governorThrottle;
         #endif
-        servo[7] = constrain(servo[7], conf.minthrottle, MAXTHROTTLE);   //  limit min & max
+      servo[7] = constrain(servo[7], conf.minthrottle, MAXTHROTTLE);   //  limit min & max    }
       }
       #ifndef HELI_USE_SERVO_FOR_THROTTLE
         motor[0] = servo[7];     // use real motor output - ESC capable
@@ -1254,8 +1227,6 @@
       //              ( Collective, Pitch/Nick, Roll ) Change sign to invert
       /************************************************************************************************************/
       #define HeliXPIDMIX(Z,Y,X) (collRange[1]*Z + collective*Z + heliNick*Y +  heliRoll*X)/10
-      // original #define HeliXPIDMIX(Z,Y,X) collRange[1]+collective*Z + heliNick*Y +  heliRoll*X
-
       #ifdef HELI_120_CCPM
         static int8_t nickMix[3] = SERVO_NICK;
         static int8_t leftMix[3] = SERVO_LEFT;
@@ -1274,7 +1245,16 @@
       servo[3] += get_middle(3);
       servo[4] += get_middle(4);
       servo[6] += get_middle(6);
-    #endif // HELICOPTER
+  #elif defined( GIMBAL )
+    #define S_PITCH 0
+    #define S_ROLL  1
+    for(i=0;i<2;i++) {
+      servo[i]  = ((int32_t)conf.servoConf[i].rate * att.angle[1-i]) /50L;
+      servo[i] += get_middle(i);
+    }
+  #else
+    #error "missing coptertype mixtable entry. Either you forgot to define a copter type or the mixing table is lacking neccessary code"
+  #endif // MY_PRIVATE_MIXING
 
     /************************************************************************************************************/
     /****************************                Cam stabilize Servos             *******************************/
@@ -1307,15 +1287,6 @@
       servo[S_ROLL]  = MIDRC-angleP-angleR;
     #endif
     
-    #ifdef GIMBAL
-      #define S_PITCH 0
-      #define S_ROLL  1
-      for(i=0;i<2;i++) {
-        servo[i]  = ((int32_t)conf.servoConf[i].rate * att.angle[1-i]) /50L;
-        servo[i] += get_middle(i);
-      }
-    #endif
-
   /****************                    Cam trigger Sevo                ******************/
     #if defined(CAMTRIG)
       // setup MIDDLE for using as camtrig interval (in msec) or RC channel pointer for interval control
@@ -1358,14 +1329,13 @@
             servo[i] = map(servo[i], 1020,2000, conf.servoConf[i].min, conf.servoConf[i].max);   // servo travel scaling, only for gimbal servos
           }
         #endif
-        #if defined(HELICOPTER) && YAWMOTOR)
+    #if defined(HELICOPTER) && (YAWMOTOR)
           if(i != 5)  // not limit YawMotor
         #endif 
             servo[i] = constrain(servo[i], conf.servoConf[i].min, conf.servoConf[i].max);          // limit the values
       }
     #endif
     
-  #endif //MY_PRIVATE_MIXING
 
   /****************                Filter the Motors values                ******************/
   #ifdef GOVERNOR_P

Imho much better to read; apart from indentation I did not do too much damage to the code really.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

@Mis,
your change for HELI_ to optionally support a yawmotor was bad.
Increasing #define NUMBER_MOTOR from 1 to 2 downright breaks servo handling. For heli120 servo[6] is used for swash and does not work any longer.
I have reverted your change for now back to 1. If you want the yaw motor feature, then do not lightly break other stuff. You have a reputation for knowing your way around pwm/interrupthandling.

As I have little knowledge of the servo handling beyond servo[i]= assignments, this cost me 3 hours of fruitless hunting down all the way through the mixtable into atomicServo handling. Not good for my mood and wasted time.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

Fixed Rudder on Airplane and Gimbal on Multi's.
MultiWiiConf.zip

No graphics for Heli 90.
Single and DualCopter yet.

wilco1967
Posts: 156
Joined: Thu Aug 18, 2011 6:04 pm
Location: Winterswijk, Netherlands

Re: General servo handler - almost done

Post by wilco1967 »

PatrikE wrote:Fixed Rudder on Airplane and Gimbal on Multi's.
MultiWiiConf.zip

No graphics for Heli 90.
Single and DualCopter yet.


Good work...

Did you do something special that would explain why it will not detect my bluetooth dongle on com2 ? :roll:
the bluetooth works fine with the 'official' Gui, but com2 does not even show up in your version. Might be some windows issue....

Seems like it is trying to connect when I start the GUI, but times out before it detects the port is there
it looks like the led on the dongle is blinking for a moment, same as if you try to connect, but it stops before it completes. Is there somewhere I can extend the time it waits before deciding to go to the next com port ?
Works just fine with the FTDI cable.

small note: The tail servo indication for a Tri does not move in your Gui ;)

Thanks !

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hamburger:
Ok, I'm sorry, I missed this collision on promini board, BUT on Mega2560 boards this should work without problem, especially with hardware PWM's.
I use Mega2560 board for testing...

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

small note: The tail servo indication for a Tri does not move in your Gui

It's is a problem with TRI.
It can use 2 different servos for Yaw it you use MEGA boards.

Today there's no real way for the gui to identify witch servo is used.
It could be temporarily soved by showing both servos.

It could be solved this way in def.h.
Create a new MULTITYPE for the Gui if MEGA_HW_PWM_SERVOS is used.

Code: Select all

#if defined(TRI)
#if defined(MEGA) && defined(MEGA_HW_PWM_SERVOS)
  #define MULTITYPE 21
#else
  #define MULTITYPE 1
#endif

Then it's easy to idetify it for the Gui.

Any oppinions on that?


/Patrik

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

Mis,
you should add some predominant info for some of your changes. I saw you did move servos for FlyingWing to different pins, right?

Maybe you can help me to understand this. I started trying out the new servo code on a nanoWii m32u4. With the broken code, now the formerly working servo on servo[6] is dead. I mean the servo is dead now. Any idea what in 'your code' took it out of business? (this is especially miserable because I cannot buy a replacement anymore, now have to replace 3 swash servos; expensive, time-consuming, ugly tiny mechanics)

For further diagnosis I rigged up a crius 328p board, wrecked another old analog servo, then attached a pwm-meter (Textstar LCD rules!) to the servo[6] pin. From there I meandered my way down in the depths of servo pwm generation in MWii to finally end in heli motors configuration.

Not really a great day, but I guess that's what it takes - sometimes. I would really like to understand though; I hope you can provide some technical information what happened on that servo[6] pin that could cause such desaster?

Status:
HELI_120 - basic, servos initially tested on 328p and m32u4. Mixing needs verification.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

PatrikE wrote:It could be solved this way in def.h.
Create a new MULTITYPE for the Gui if MEGA_HW_PWM_SERVOS is used.
Any oppinions on that?

I should probably dive into the code before writing, but I think having another multitype to resolve a cpu-select conflict is a bad idea.
Cannot all code in MWii for communicating with the GUI use the way mis introduced for the mixtable- namely servo[TRI_SERVO-1]?

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hamburger: All pin definitions are in def.h and output.ino.
For promini:
Motors : 9,10,11,3,6,5,A2,12
Servos : A0,A1,A2,12,11,3,10,9
As you see S8 collide with M1, but this is not a problem because both is used as the same value output for mainmotor
S7 collide with M2, and enabling Motor2 disable servo7.

For promicro:
Motors : 9,10,5,6,4,A2,SW_PWM_P3,SW_PWM_P4 OR 9,10,5,6,11,13,SW_PWM_P3,SW_PWM_P4 OR for tenesy 14,15,9,12,22,18,16,17 OR 14,15,9,12,4,10,16,17
Servos : A0,A1,A2,A3,5,6,10,9 OR A0,A1,A2,4,5,6,10,9
Horror :evil:

For Mega it's easy:
Motors: 3,5,6,2,7,8,9,10
Servos SW_PWM : 34+44 , 35+45 , 33+46 , 37,6,2,5,3
Servos HW_PWM : 44,45,46,11,12,6,7,8

As you see use all 8 servos always collide with motors, except mega with HW_PWM - in this case two motors can be used independly.

PatrickE:
I think that BEST method of idenify board type and used options is using "capability" flags of MSP_IDENT command.
For now BIT0 is used for bind capability. We can add:
BIT1 to signalise PROMICRO board
BIT2 to signalise MEGA board
Both BIT1 and BIT2 = 0 to signalise PROMINI board.
Additionally BIT3 for version signalisation and set when:
1. Promini board with A0_A1_PIN_HEX option enabled.
2. Promicro board with HWPWM6 option enabled.
3. Mega board with MEGA_HW_PWM_SERVOS option enabled.

In output.ino this should be like this:

Code: Select all

#define BIND_CAPABLE 0   //Used for Spektrum today; can be used in the future for any RX type that needs a bind and has a MultiWii module. 
#if defined(SPEK_BIND)
  #define BIND_CAPABLE 1
#endif

#define BOARD_TYPE 0
#if defined(PROMICRO)
  #define BOARD_TYPE 2
#elif defined(MEGA)
  #define BOARD_TYPE 4
#endif

#define BOARD_OPTIONS 0
#if (defined(PROMINI) && defined(A0_A1_PIN_HEX)) || (defined(PROMICRO) && defined(HWPWM6)) || (defined(MEGA) && defined(MEGA_HW_PWM_SERVOS))
  #define BOARD_OPTIONS 8
#endif

const uint32_t capability = 0 + BIND_CAPABLE + BOARD_TYPE + BOARD_OPTIONS;


In this case you can propertly identify board, assigned pins and motors/servos.
Additionally command MSP_MOTOR_PINS is no longer needed.
Now if the BIT2 and BIT3 = 1 this mean MEGA board with HW_PWM and you can use propper motors and servos numbers for this type. Easy ? :D

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

so did the conflict of both MOTOR2 and SERVO7 being defined result in outputting both values simultaneously on that one pin to the poor servo?

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: General servo handler - almost done

Post by Alexinparis »

Mis wrote:PatrickE:
I think that BEST method of idenify board type and used options is using "capability" flags of MSP_IDENT command.
For now BIT0 is used for bind capability. We can add:
BIT1 to signalise PROMICRO board
BIT2 to signalise MEGA board
Both BIT1 and BIT2 = 0 to signalise PROMINI board.
Additionally BIT3 for version signalisation and set when:
1. Promini board with A0_A1_PIN_HEX option enabled.
2. Promicro board with HWPWM6 option enabled.
3. Mega board with MEGA_HW_PWM_SERVOS option enabled.

In output.ino this should be like this:

Code: Select all

#define BIND_CAPABLE 0   //Used for Spektrum today; can be used in the future for any RX type that needs a bind and has a MultiWii module. 
#if defined(SPEK_BIND)
  #define BIND_CAPABLE 1
#endif

#define BOARD_TYPE 0
#if defined(PROMICRO)
  #define BOARD_TYPE 2
#elif defined(MEGA)
  #define BOARD_TYPE 4
#endif

#define BOARD_OPTIONS 0
#if (defined(PROMINI) && defined(A0_A1_PIN_HEX)) || (defined(PROMICRO) && defined(HWPWM6)) || (defined(MEGA) && defined(MEGA_HW_PWM_SERVOS))
  #define BOARD_OPTIONS 8
#endif

const uint32_t capability = 0 + BIND_CAPABLE + BOARD_TYPE + BOARD_OPTIONS;


In this case you can propertly identify board, assigned pins and motors/servos.
Additionally command MSP_MOTOR_PINS is no longer needed.
Now if the BIT2 and BIT3 = 1 this mean MEGA board with HW_PWM and you can use propper motors and servos numbers for this type. Easy ? :D


Hi,

I think all this stuff should be abstracted so that the GUI see a tricopter with always the same servo number.
The cook behind should stay in the specific part of boards & hardware options.
It's not the job of the GUI to determine what is the right pin depending on the hardware behind.
The multitype should be enough to represent without ambiguity a model: fixed id for motor&servo + a specific layout.

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

Hamburger, if you disable "#define HELI_USE_SERVO_FOR_THROTTLE" the last used servo number is 7, not 8. At this case no output for SERVO8. Motor1 can use this pin.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

My helis are 120_ccpm with 3 swash + 1 tail servo + 1 main motor. So I always have #undef HELI_USE_SERVO_FOR_THROTTLE.
In mixtable, we still use servo[7] (SERVO8) for that case to compute the value and copy it to motor[0] at the end of mixing.
But for gasser #define HELI_USE_SERVO_FOR_THROTTLE and SERVO8 is used.

My guess is if you want heli90 with yawmotor, then you must differentiate more in def.h where setup of NUMBER_MOTOR, SERVO-from-to, is done. It must take into account
- heli90 vs. heli120
- HELI_USE_SERVO_FOR_THROTTLE
- yawmotor
That would be theoretical 8 cases, probably not all 8 cases are to be found in real world.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

A warning!...

This option is default in the code.

Code: Select all

  /***********************          Airplane                       ***********************/
    #define USE_THROTTLESERVO // For use of standard 50Hz servo on throttle.

Problem is with the new servocode The motor starts at Full Throttle!
With the option commented everything works as normal!


Same thing happens on Both Airplane and FlyingWing.

On Heli120
#define HELI_USE_SERVO_FOR_THROTTLE
Starts ESC in programming mode.
Probably best!
I wouldn't want to be close to a heli at full throttle! :shock:


This cased my friend a visit to the Emergency to day!

Please dont commit untested code in _shared!!!!!!

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

damn. And this has been propagated to the downloads section!

Also, Heli120 is broken again and is likely to destroy the swash nick servo! Reason is NUMBER_MOTOR set to 2 in def.h. See my earlier posts.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

I noticed that NUMBER_MOTOR set to 2 in def.h.
Not many servos can manage 300hz.
It should be cahnged to 1 motor.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

done in r1436!

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

I identified the code causing the visit to the ER and removed it in r1437!...

Code: Select all

  #if SERVO_END == 8      // Exclude Motor servo
    #undef SERVO_END
    #define SERVO_END 7
  #endif 

*Yawmotor is still broken.
In Mixtable.

Code: Select all

#if YAWMOTOR
        motor[1] = servo[5];   // use motor2 output for YAWMOTOR
#endif

motor[1] Must be defined in def or simply remove it in mixtable!

*Flaps is still broken!
There is no controll from RC channels!
Only centering!..

Code: Select all

      int16_t lFlap = get_middle(2);
      lFlap = constrain(lFlap, conf.servoConf[2].min, conf.servoConf[2].max);
      lFlap = MIDRC - lFlap;

Should be..

Code: Select all

      int16_t lFlap = rcData[FLAPS];
      lFlap = constrain(lFlap, conf.servoConf[2].min, conf.servoConf[2].max);
      lFlap -= get_middle(2);


// Flapperon Controll TODO - optimalisation
Please don't!!!
Unless it's tested and verified first!

/Patrik

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: General servo handler - almost done

Post by Hamburger »

seems we are kinda stuck now with the last unfortunate code changes and nasty side effects - I for one am quite hesitant to upload to my test-rig or even update any of my copters' software and take the chance to destroy more servos or risk flesh&bones.

To overcome this stall I propose we keep track of who tested which coptertype on which cpu successfully. By testing I mean upload latest software to a board with all servos and esc+motor attached and verified all physical servo+motor response, either on bench or in flight - GUI alone does not count.

Code: Select all

328p     m32u4     2560    | type                       
---------------------------------------
   .       .        .      | Gimbal
   .       .        .      | BI
   .       .        .      | TRI
   .       .        .      | FlyingW
   .       .        .      | Airplane
   .       .        .      | singlecopter
   .       .        .      | dualcopter
   .       .        .      | heli90
   .       .        .      | heli90+yawmotor
   .       .        .      | heli120
   .       .        .      | heli120+throttleservo

Mis
Posts: 203
Joined: Fri Apr 01, 2011 12:23 am

Re: General servo handler - almost done

Post by Mis »

PatrikE wrote:*Yawmotor is still broken.
In Mixtable.

Code: Select all

#if YAWMOTOR
        motor[1] = servo[5];   // use motor2 output for YAWMOTOR
#endif

motor[1] Must be defined in def or simply remove it in mixtable!

It is irrelevant and has no effect.

PatrikE wrote:*Flaps is still broken!
There is no controll from RC channels!
Only centering!..
....

Do not write "is still broken" if you simply can not setup it !!!!
Look at this video: http://www.youtube.com/watch?v=8j9MGNPbB0A
Working ?

PatrikE wrote:
// Flapperon Controll TODO - optimalisation
Please don't!!!
Unless it's tested and verified first!

No problem. I can no longer touch the official multiwii code.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: General servo handler - almost done

Post by PatrikE »

Mis wrote:Do not write "is still broken" if you simply can not setup it !!!!
Look at this video: http://www.youtube.com/watch?v=8j9MGNPbB0A
Working ?

Ok that's someting i missed!
Quite smart.. But not obvious.

Mis wrote:No problem. I can no longer touch the official multiwii code.

That's bad because you made a lot good things.
You just made the misstake to add untested code.

/Patrik

Post Reply