Work with SITL model of helicopter

Hello, I’m trying to work with a custom model from Rhys Mainwaring (Helicopters in Gazebo, Gazebo: Helicopter: add models for rotor head and helicopter by srmainwaring · Pull Request #149 · ArduPilot/SITL_Models · GitHub).

I have built Gazebo Ionic using his commits, downloaded a patched repo of SITL_Models and the repo of ardupilot (on the tag: Copter-4.6.2).

Now I can launch the Gazebo helicopter model, SITL with mavproxy, which prints heartbeats from the model, but I cannot make it spin the rotor.

My commands:
Loiter
Rc 3 1000
Rc 8 1000
Arm throttle
Rc 3 1500 (at this step I see a slight movement of the rotor, for a moment only)

And another question, why does the takeoff command fail after the arm command in guided mode? Can a helicopter be controlled by automatic programs (takeoff, reposition, land..)?

@Oleg88 I have not experimented with this yet. @rhys could you help with this?

He told me about these commands in an email letter. Recently I played with commands and with docker container settings, and suddenly the rotor started to spin O_o..

But now there’s another problem, I set rc 8 2000, rc 3 1500 and higher, but the helicopter cannot takeoff, it is spinning around itself on the ground. The Command takeoff 5 is accepted in the loiter mode, but it moving around only.

@Oleg88 did you get the parameters that he used to set up the helicopter in ardupilot?

Hi Oleg, thanks for trying the model out. There are still a number of open PRs needed to support the helicopter. I’ve updated everything to latest today, and am also using Gazebo Jetty now that it has been released. It is the LTS version replacing Harmonic, so a better choice than Ionic if you are upgrading as it has all except two of patches needed to support the rotor head.

The ArduPilot Gazebo plugin has been updated to support Jetty I’ll list all the patches below so you can check.

The reason the copter is spinning is be because is needs a custom patch of ArduPilot that amongst other things to do with Matt’s autorotation code, adds a reversible direct drive fixed pitch tail rotor. This is needed for yaw control in autorotation with the model, and without the patch the copter model will not work correctly in normal flight either.

If the copter arms, takes off and hovers in LOITER then all the usual modes will also work (AUTO, GUIDED fly-to etc).

I’ve tested today on my two macs (one Intel x86_64 the other mac silicon arm64). All working as expected.

Patches: Gazebo Jetty

This is the physics patch from DetachableJoint: allow physics constraint properties to be set by srmainwaring · Pull Request #754 · gazebosim/gz-physics · GitHub ported to Jetty:

And this is the patch from DetachableJoint: allow physics constraint properties to be set by srmainwaring · Pull Request #2960 · gazebosim/gz-sim · GitHub ported to Jetty:

Patches: ArduPilot Gazebo

The main branch of GitHub - ArduPilot/ardupilot_gazebo: Plugins and models for vehicle simulation in Gazebo Sim with ArduPilot SITL controllers has support fort Jetty (be sure to set the environment variable GZ_VERSION=jetty)

Patches: ArduPilot SITL_Models

I am using this branch for the helicopter

It differs from the PR Gazebo: Helicopter: add models for rotor head and helicopter by srmainwaring · Pull Request #149 · ArduPilot/SITL_Models · GitHub as it has a more complex tail rotor assembly (better treatment of the fixed pitch prop blades so they can be reversed).

Patches ArduPilot

This is the version of ArduPilot that goes with all the changes above. It was rebased on master earlier today, so is almost current.

These are the relevant parameter changes from the default heli model (you’ll want the first column labelled “current”). The CAN and range finder parameters are for the autorotation testing. They need a separate Python script to publish RPM and range data from Gazebo via DroneCAN. If you are interested in getting that running later I can walk you through it, but best to get the basic model flying first.

Parameter        Current  Default
WPNAV_SPEED      1200.000000 1000.000000
ATC_ANG_RLL_P    5.000000 4.000000
ATC_ANG_PIT_P    5.000000 6.000000
ATC_ANG_YAW_P    5.000000 5.800000
ATC_INPUT_TC     0.150000 0.200000
ATC_HOVR_ROL_TRM 380.000000 320.000000
ATC_RAT_RLL_P    0.004000 0.060000
ATC_RAT_RLL_I    0.120000 0.105000
ATC_RAT_RLL_D    0.010000 0.000100
ATC_RAT_RLL_FF   0.120000 0.210000
ATC_RAT_RLL_ILMI 0.110000 0.100000
ATC_RAT_PIT_P    0.010000 0.024000
ATC_RAT_PIT_I    0.080000 0.095000
ATC_RAT_PIT_D    0.010000 0.002000
ATC_RAT_PIT_FF   0.080000 0.190000
ATC_RAT_YAW_P    0.500000 0.246850
ATC_RAT_YAW_I    0.060000 0.024500
ATC_RAT_YAW_D    0.006000 0.003900
ATC_RAT_YAW_FF   0.100000 0.000000
AHRS_TRIM_Y      -0.010000 0.000000
CAN_P1_DRIVER    1.000000 0.000000 # First driver (DEFAULT: Disabled)
CAN_P2_DRIVER    1.000000 0.000000 # First driver (DEFAULT: Disabled)
CAN_D1_UC_ESC_BM 1.000000 0.000000 # ESC 1 (DEFAULT: )
SIM_GPS1_ENABLE  1.000000 0.000000
H_COL_MIN        1470.000000 1460.000000
H_COL_MAX        1680.000000 1740.000000
H_RSC_SETPOINT   48.000000 66.000000
H_RSC_RUNUP_TIME 3.000000 10.000000
H_COL_HOVER      0.300000 0.500000
H_COL_ANG_MAX    12.200000 12.000000
H_RSC_AROT_ENBL  1.000000 0.000000 # Enabled (DEFAULT: Disabled)
H_TAIL_TYPE      3.000000 0.000000 # DirectDrive FixedPitch CW (DEFAULT: Servo only)
RNGFND1_TYPE     100.000000 0.000000 # SITL (DEFAULT: None)
RNGFND1_MIN      0.100000 0.200000
RNGFND1_MAX      10.000000 7.000000
RNGFND1_POS_X    0.325000 0.000000
RNGFND1_POS_Z    -0.325000 0.000000
SERVO1_MIN       1000.000000 1100.000000
SERVO1_MAX       2000.000000 1900.000000
SERVO2_MIN       1000.000000 1100.000000
SERVO2_MAX       2000.000000 1900.000000
SERVO3_MIN       1000.000000 1100.000000
SERVO3_MAX       2000.000000 1900.000000
SERVO4_MIN       1000.000000 1100.000000
SERVO4_MAX       2000.000000 1900.000000
SERVO5_MIN       1000.000000 1100.000000
SERVO5_MAX       2000.000000 1900.000000
SERVO6_MIN       1000.000000 1100.000000
SERVO6_MAX       2000.000000 1900.000000
SERVO7_MIN       1000.000000 1100.000000
SERVO7_MAX       2000.000000 1900.000000
AROT_ENABLE      1.000000 0.000000 # Enabled (DEFAULT: Disabled)
AROT_FWD_SP_TARG 8.000000 11.000000
AROT_ROT_SOL     0.054000 0.050000
AROT_ROT_DIAM    0.750000 1.250000
AROT_FLR_MAX_HGT 20.000000 30.000000
RPM1_TYPE        5.000000 10.000000 # ESC Telemetry Motors Bitmask
RPM1_ESC_MASK    1.000000 0.000000 # Channel1 (DEFAULT: )

He told me about these commands in an email letter. Recently I played with commands and with docker container settings, and suddenly the rotor started to spin O_o..

Maybe the net: host settings? The ardupilot_gazebo plugin sends gz-transport messages to control the rotors and servos. To see them run

gz topic -l

The relevant topics are

/model/helicopter/joint/tail_motor_joint/cmd_vel
/model/rotor_head_cw/joint/main_joint/cmd_vel
/model/rotor_head_cw/joint/servo_arm_1_joint/0/cmd_pos
/model/rotor_head_cw/joint/servo_arm_2_joint/0/cmd_pos
/model/rotor_head_cw/joint/servo_arm_3_joint/0/cmd_pos

If there is anything blocking these messages, then the simulation will not get the commands to control the joints. Btw, if the ardupilot_plugin is disabled (commented out) in the model, you can publish to these topics directly to test the model is responding correctly. Useful when modifying or building the model or testing the rotor head.

But now there’s another problem, I set rc 8 2000, rc 3 1500 and higher, but the helicopter cannot takeoff, it is spinning around itself on the ground. The Command takeoff 5 is accepted in the loiter mode, but it moving around only.

The patches listed above should solve this - it will be a tail rotor config issue of some kind.

Thank you for your response, Rhys. It was very helpful. I have successfully built all the necessary components, and the helicopter is now flying! However, I am encountering a compilation error due to the following issue: [Werror=uninitialized]. This error occurs in the ardupilot project’s [cpp] file (ac_autorotation.cpp). To resolve this issue, I need to insert two lines into the specified file using the waf build system.

@Oleg88, good news! If you could provide more details and terminal output regarding the build error and waf changes that would help. I have not needed to do anything similar in my case, so am curious to see what the issue is.

errors

../../libraries/AC_Autorotation/AC_Autorotation.cpp: In member function ‘void AC_Autorotation::run_landed()’:
../../libraries/AC_Autorotation/AC_Autorotation.cpp:878:55: error: ‘desired_heading.AC_AttitudeControl::HeadingCommand::yaw_angle_rad’ is used uninitialized in this function [-Werror=uninitialized]
878 | _attitude_control->input_thrust_vector_heading_rad(_pos_control->get_thrust_vector(),
| ~~~~~~~~~~~~~~~~^
879 | desired_heading.yaw_angle_rad,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
880 | desired_heading.yaw_rate_rads);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
cc1plus: some warnings being treated as errors

insert lines to fix Werror-uninitialized errors:

sed -i ‘877i\desired_heading.yaw_angle_rad=0.0;’ ./libraries/AC_Autorotation/AC_Autorotation.cpp
sed -i ‘656i\desired_heading.yaw_angle_rad=0.0;’ ./libraries/AC_Autorotation/AC_Autorotation.cpp

./waf distclean
./waf configure --board sitl
./waf copte

Thanks, I’ll take a look at that case. Generally AP does not initialise variables to zero in order to save flash. If the variable can be used uninitialised that is an error, in which case it should be initialised at declaration. It does not show up compiling on macOS with clang, but the gcc defaults may be different if building on Ubuntu.