Need Help: TradHeli Direct Drive Variable Pitch Tailrotor

In moving from Copter 3.3 to Copter 3.4 and now 3.5, the direct drive variable pitch (DDVP) feature of the Trad Heli single rotor/tail rotor stopped working. Essentially the output on Channel 7 read zero for both armed and disarmed modes.

Here is what I found, in 3.3, the rotor speed output was left in 0 to 1000 range and then a servo function (calc_pwm) was used to push it to the servo. In 3.4, the rotor speed output range was changed to 0-1. This is then scaled to the range of 0-1000 and then turned into pwm in the write_rsc method using a pwm_min and pwm_max parameter set only for the main rotor. Thus the tail rotor pwm_min and pwm_max were never set causing it to read zero all the time.

So here is where I need help. What was the rationale for making PWM min and PWM max parameters for heli rather than using the servo pwm min and max values? I’m assuming either @rmackay9 or @tridge coded it up this way and would like their insight. so my choice is to put 3 more parameters (min, max, rev) for the tail rotor or have them determined from the servo min, max and rev values.
I’d like to get @Rob_Lefebvre and @ChrisOlson to weigh in on this as well.

Thanks in advance,

My friend Manfred Dickgiesser found that out with his TREX 600 when he tried the than new FW3.4. He contacted the developers at that time, like Robert Lefebvre. Because he never received any reply he still is flying FW 3.3 and has lost a lot of interest in this.
He was the one who introduced me to this hobby at the time when the APM 2.5 was the top FC. I thought to let you know there was not a lot of interest for this in the past. I hope you are successful with your approach.
I solved my situation with having Castle Heli ESC’s for main and tail motor’s. Those Castle ESC’s have excellent governors. That is why I am using y- cable and feed both ESC’s the same signal. It works great for me but is more costly in hardware.

Bill, I didn’t see where the _direct_drive_tailspeed function in the AP_MotorsHeli header file was ever being initialized. I fixed it using a different approach - I totally removed the Ext Tail Gyro functions for std and acro since nobody uses it anyway. Can’t even buy a tail gyro anymore so why have it in the code? Then I initialized the function on AP_MOTORS_HELI_SINGLE_AUX.

I haven’t tested it yet, but it built fine once I got rid of the conflict with the external gyro thing.

So I think in 3.3, it didn’t need to be initialized because the servo outputs were not being broken out and both the ext gyro and DDVP were being initialized using the same call. So in 3.5, the servo output is broken out by function. So when you initialized it, what method did you use:
_tail_rotor.init_servo() similar to the main rotor or SRV_Channels::get_channel_for.
If you used the latter one then be sure you have it pointing to the k_heli_tail_rsc function.
Certainly doing one of the two methods above should initialize it but it still won’t work until you fix the issue I described above. I needed to hard code pwm_min and max to 1000 and 2000 respectively in the write_rsc method before it worked. I had tested it in the SITL.

You’re right. I used the highlighted method but it didn’t work. I assumed it would use the min/max for the SERVO7_FUNCTION. But I still got zero output.

We’ll have to get a comment from @tridge or @rmackay9 on this. I didn’t review the entire commit history and I don’t understand why there is separate min/max params for heli.

Yeah it took me a while to figure this one out. They set the min and max parameter values for the main rotor in a very strange way in the AP_MotosHeli_Single.cpp. The variable in the parameter setup was _main_rotor.pwm_min and the same way for max. So tail rotor never had those values set and were defaulted to zero.
I guess I would prefer using the servo values. I haven’t tried using the servo min and max but I don’t expect it to be an issue getting the values from the SRV_channel library.

Hi Fred,
Thanks do the info. Now that I found the issue, it shouldn’t be too hard to fix. We just need to make some decisions for a path forward.
When i first started considering putting motors on the outriggers for my compound heli, I was thinking the same as you and just use y-cable from the main rotor servo out for both the main rotor and propeller motors. I’m still on the fence regarding this but it gives folks options.

I agree. All the min/max etc values for the cyclic and tail servos used to be in HSx_ params but were moved to the SRV_channel library in 3.5. Why was the heli RSC left with separate params? We don’t need to be doubling up on parameters.

I think it’s a good idea to fix this instead of using a y-cable. The heli tail RSC is not always run at the same value as the main rotor. And since it’s in the code and obviously broken we should fix it. Since you have a working implementation, Bill, why don’t you push it to like a DDVP_fix branch on ArduHeli, we’ll look at it, refine it, test it, submit a PR to Copter master.

I’d also like to get a comment from @tridge on whether or not we should leave the external tail gyro functionality in. Considering that external tail gyros are largely obsolete. That was put in in the APM days when the old code had problems with a “twitchy” tail. It’s been pretty much obsolete since Copter 3.2 and I don’t know of anybody flying an external tail lock gyro anymore. And even if somebody is, can simply set the yaw rate VFF to a decent value, zero the PID’s, and map one of your RC channels to adjust the gain on the gyro. So I see it as a total waste of a function and extra parameters that aren’t needed any longer.

I agree.

I’ll try to do that today. I also wanted to work on having it swap between servo outs a little better. When I was playing with this trying to get it to work, I noticed that it was hanging up every so often when I changed the servo function between channels in the servo parameters.

I tend to agree with removing the ext gyro feature. Otherwise it should probably be a servo function option. That way we can remove the parameter that has you selecting which option. Then the servo function tells the code when to use those features. I would like to code it this way for the tail rsc as well. Otherwise it seems like it holds the default channel hostage even though the feature is not being used.

Yes, that’s why I removed it in my experiment at getting the DDVP output to work. The external tail gyro function had the servo output tied up and no way to initialize the DDVP output.

@bnsgeyer I reverted my local changes for initializing the DDVP tail function, since it didn’t work anyway. Although I could’ve fixed it now that I know what the problem is. I think you have a more elegant solution to that.

I saved the changes I made in my local repo for removing the external gyro functions and params. I pushed those changes to a dev branch on ArduHeli and test built it to make sure the code is good and no typo’s.

So removing the gyro functions can be a separate issue, optional for Copter, but will be merged into ArduHeli master because we absolutely don’t need it. In order to even use that feature I’d have to dig thru my junk boxes and find an old tail lock gryo that still works and hasn’t had the wires cut off it to use the plugs for other more useful things.

Fred, sorry we didn’t get to look at this sooner. I was not aware that DDVP tails don’t work in 3.4 and newer until I tested it a few days ago. I have a Trex 600 with a DDVP tail but it’s not all built yet and flying. Evidently Bill and I had the same idea late yesterday afternoon - start looking at it and see what’s broken. Bill has a better solution than what I came up with. So we’ll get it fixed and if the changes don’t get into the 3.5 stable releases right away you can always fly the ArduHeli long-term testing build that has the changes in it. Those are on GitHub now as “releases” with notes as to what we’ve changed or fixed in the stable Copter release.

@ChrisOlson I made a new branch DDVP from the ArduHeli master. I uploaded my fix for this issue. So from what I see so far, you have to make the changes to SERVO7_FUNCTION and TAILTYPE and then reboot the controller. Then everything should work for the DDVP. I would assume that if you want to revert back to Ext Gyro, you would have to make the same parameter changes expcept for Ext Gyro and then reboot the controller for the changes to take. I wasn’t sure if these were hot swappable before but I’m not sure how to change it so they are.


@bnsgeyer I don’t know if the Ext Gyro and tail function are hot-swappable or not. I think they are but I wanted to test it with a real heli instead of a sim and I don’t have a working tail gryo around here to test that it actually has proper output using the Ext Gyro function.

The DDVP output signal to the Heli Tail ESC now works. It starts the tail motor when the motor interlock is raised and FC armed. And it ramps it smoothly up to speed. I tried a couple different speeds and it works properly.

I also tried mapping the HeliTailRSC to SERVO6 to make sure the servo mapping function works properly. It does. And I tried to start it with the motor interlock before arming to see if it would run - it doesn’t.

With a proper throttle hold that would leave the motor interlock raised, practice autorotations could be done with DDVP. And in the event of loss of power to the main rotor an autorotation is still possible with motor interlock raised. In the event of a mechanical problem where the main engine has to be shut down in flight with the governor switch a psuedo autorotation could still be done, but it would be hairy with no tail control. But it can be done - I did it when I lost my tail servo a few weeks ago, shut down in flight and autorotated to arrest the torque spin.

So it sounds like you think it is ready to be PR’d? I do have an ext gyro but not sure when I can test it. but what I saw on the sitl, it appears to work.

I have to do some clean up. I can delete the commented out text for the parameters that are no longer necessary.

Thanks for checking the fix!

It’s kind of interesting that the stock code (and ArduHeli modified code at present) sets SERVO7_FUNCTION to Motor7 (value 39), even if you set that param to Disabled. When you reboot the FC it’s set back to Motor7 again.

I just did a quick grep in the AP_Motors library and it’s coming from here. Why does it do this?

@bnsgeyer once you get it cleaned up on the parameter end where you have the param definition commented out in AP_MotorsHeli_Single.cpp, I see no reason this can’t be PR’d. I spent the last half hour testing it, and while I can’t fly the heli yet I have the motors all hooked up and running so I can test it without blades. It works like it did in 3.3, except that you can map the function to whatever SERVO output you want.

If you set SERVO7_FUNCTION to HeliTailRSC the setting sticks on reboot. I’m still not sure why that output is being set to Motor7 by default otherwise, but it doesn’t seem to affect the DDVP tail functionality if it’s mapped to that output.

@ChrisOlson when you did your test, did you always use RC 8 in as the input for motor interlock and setting ESC speed (mode 1) or did the input channel change with the main rotor servo out channel. Not close to my computer and can’t verify it right now but was wondering if you remembered.

Those are on GitHub now as “releases” with notes as to what we’ve changed or fixed in the stable Copter release.

Thanks for the info, Chris.

I always used RC8 in as the motor interlock channel and tested all (main_rotor) RSC modes.

The input channel does not change when you map an output using the SERVOx_FUNCTION. The default (and only possiblity in 3.4 and earlier was 7 for aux and 8 for RSC. Those can now be changed in 3.5 with the SERVOx_FUNCTION. Even a Pixracer with only 6 outputs uses the RC8 in for motor interlock.