Flight-Mode Position Hold refused despite strong GPS signal

I am attempting to fly indoors using a Pixhawk 2.1, custom frame, ArduCopter 3.5.5, and Optitrack motion capture system. I can supply a fake gps signal from the mocap system using ROS and the MAVROS fake gps plugin. I am also supplying altitude information via the MAVROS distance_sensor plugin.

I am unable to switch into position hold mode, instead receiving the message “Flight mode change failed” and the error “Flight-Mode Pos Hold refused”. Stablized and Altitude Hold modes work as expected.

Why is position-hold mode refused, even though I have a strong (fake) GPS signal (10 satellites, HDOP=1.0)? How can I find the reason for a rejected flight mode?

Flight Logs
Log 1 (48 KB)

Log 2

Parameters:
with_mavros_rangefinder.param (15.7 KB)

ROS Configuration:
Launch File:
`

<!-- Optitrack node gets pose from the mocap system, publishes to /mavros/fake_gps/mocap/pose -->
<node
    pkg="mocap_optitrack"
    type="mocap_node"
    name="mocap_node"
    respawn="false"
    launch-prefix=""
    required="true">
    <rosparam file="$(find mocap_optitrack)/config/mocap.yaml" command="load" />
</node>

<!-- Launch a node that publishes a fake rangefinder message based on the above fake GPS signal -->
<node
    pkg="mavros_optitrack"
    type="fake_ranger.py"
    name="fake_ranger"
    output="screen" 
/>

<!-- Launch mavros, which (in Kinetic) will automatically generate a fake gps signal from /mavros/fake_gps/mocap/pose -->
<!--<arg name="fcu_url" default="/dev/ttyACM0:115200" />-->
<arg name="fcu_url" default="/dev/ttyUSB0:115200" />
<arg name="gcs_url" default="" />
<arg name="tgt_system" default="1" />
<arg name="tgt_component" default="1" />
<arg name="log_output" default="screen" />

<include file="$(find mavros)/launch/node.launch">
	<arg name="pluginlists_yaml" value="$(find mavros_optitrack)/launch/pluginlists.yaml" />
	<arg name="config_yaml" value="$(find mavros_optitrack)/launch/apm_config.yaml" />

	<arg name="fcu_url" value="$(arg fcu_url)" />
	<arg name="gcs_url" value="$(arg gcs_url)" />
	<arg name="tgt_system" value="$(arg tgt_system)" />
	<arg name="tgt_component" value="$(arg tgt_component)" />
	<arg name="log_output" value="$(arg log_output)" />
</include>

`

Fake GPS configuration:

fake_gps:
  use_mocap: true         # ~mocap/pose
  mocap_transform: false   # ~mocap/tf instead of pose
  use_vision: false       # ~vision (pose)
  # origin (default: Zürich)
  geo_origin:
    lat: 41.6994          # latitude [degrees]
    lon: -86.2372           # longitude [degrees]
    alt: 408.0            # altitude (height over the WGS-84 ellipsoid) [meters]
  eph: 1.0 
  epv: 1.0 
  satellites_visible: 10   # virtual number of visible satellites
  fix_type: 5             # type of GPS fix (default: 3D)
  tf: 
    listen: false
    send: false           # send TF?
    frame_id: "world"       # TF frame_id
    child_frame_id: "fix" # TF child_frame_id
    rate_limit: 10.0      # TF rate
  gps_rate: 5.0           # GPS data publishing rate

A quick guess without looking further, could be wrong: Despite 10 “virtual” satellites , the position/speed/altitude accuracy is not good enough for position hold, and the EKF therefore rejects the flight mode switch.

Also it doesn’t appear you are using the mag(s)?

AFAIK Loiter will not work without mags !!!

The mocap system is highly accurate (mm level), and qualitatively the GPS data looks good. Is there any way to check if the position/speed/altitude info is “good enough”?

I wasn’t using the compass since it’s an indoor environment, and so I figured any magnetic field would be unreliable. Is there a standard procedure for working in indoor environments? Enable mags anyway? Is there a way to supply “fake” compass information via MAVROS (the mocap system gives accurate orientation information)?

Depends on the place of course, but flying indoor with compass is usually no problem, (at least it hasn’t been for me) so this would probably be the first thing to try. You can calibrate the mag indoor and see what kind of offsets you are getting, those will determine whether you are good to go or not.

@vkurtz you can look at the bin log files to view GPS info. Also, look at the EKF innovations to see if anything looks funny. But, as mentioned, turn on the mag and see if thats the problem

I enabled the mags, and they seem to work fine indoors. But that didn’t fix the problem. I re-enabled all arming checks, and was able to take off and fly in altitude and stabilize modes. When attempting to arm in position hold mode, I got the error FCU: PreArm: Need 3D Fix.

I thought perhaps the problem was related to this issue, but after fixing that I am still unable to arm in position hold mode.

The ground station indicates that I do have a 3D fix, but I still get this pre-arm error. The HIL_GPS message does not include horizontal/vertical/speed accuracy. Is this a problem for the EKF?

Thanks all for your help!