I am using a very simple python script from within MP to arm, takeoff and climb to 50m, then descend, land, and disarm. The script arms the virtual quad (sitl) successfully, then begins a climb by setting RC3 to 2000 and watching the altitude.
The problem is, once the vquad climbs to about 10m, the HUD shows “potential thrust loss”, and the virtual quad presumably “falls from the sky”. I am seeing the following messages:
Why is the quad attempting to enter AUTO mode by itself, if the mode is set to Stabilize? I have no such logic in my python script.
What’s with the SaveWaypoint LOW/MIDDLE messages? I am not manipulating any waypoints from my script.
Why is the climb to 50m being aborted automatically after the initial first few meters (anywhere from 5 - 11m)?
Here’s my simple script for reference, if it helps…
print 'Starting script'
cs.messages.Clear()
# Reset all channels to midpoints, and throttle to min
for chan in range(1,9):
Script.SendRC(chan,1500,False)
Script.SendRC(3,Script.GetParam('RC3_MIN'),True)
Script.Sleep(2000)
# Wait until GPS is acquired
while cs.lat == 0:
print 'Waiting for GPS'
Script.Sleep(1000)
print 'Got GPS!'
# Arm the quad
print 'Arming the quad...'
MAV.doARM(True)
while not(cs.armed):
Script.Sleep(50)
Script.WaitFor('Arming motors',10000)
print 'Armed!'
# Current mode
print 'Current mode is ' + cs.mode
# Climb to 50m altitude
print "Climbing..."
Script.SendRC(3,2000,True)
while cs.alt < 50:
Script.Sleep(50)
print 'Quad is now at target altitude!'
# Throttle back to descend and land
print 'Descending...'
Script.SendRC(3,1300,True)
while cs.alt > 0.1:
Script.Sleep(300)
# Disarm the quad
print 'Disarming the quad...'
MAV.doARM(False)
while cs.armed:
Script.Sleep(50)
Script.WaitFor('Disarming motors',10000)
print 'Disarmed!'
print 'Mission complete!!!'
Any ideas anyone? Why do I see a “potential thrust loss” error, followed by a crash?
This is all with SITL, not using a real quad just yet until I figure out the scripting part 100%.
Weird clue, arming works fine and the quad stays in armed mode indefinitely. After arming, as soon as MP executes any python statement that references “Script.” or “cs.”, it immediately reports “Mode change to AUTO failed: initialisation failed”, and the subsequent climb starts but immediately fails – and the quad hits the ground.
Stetting all rc inputs to the center is changing the flight mode via the flight mode channel and also setting the save waypoint switch. I suspect it is then crashing because the joystick override of RC is timing out. You just need to re-send RC every second or two.
That’s interesting, thanks.
That would be doable in Java or C#… it would require a background thread, no? I am not sure if that’s even a thing in a python script
Perhaps I can change the joystick override behavior somehow for the SITL craft? Disable changing of flights mode via the sticks?
Thanks! Now those errors went away, but the quad doesn’t climb. It just stays on the ground, armed, and the altitude in the HUD remains at 0 indefinitely.
# Climb to 50m altitude
print "Climbing..."
Script.SendRC(3,1800,True)
while cs.alt < 50:
Script.SendRC(3,1800,True)
Script.Sleep(50)
@iampete I can’t thank you enough. It all worked flawlessly end to end once I made that last change you suggested, and also changed the descent logic to Script.ChangeMode(“LAND”) instead of the one I was using before that relied on just a fixed throttle value.
@iampete, another quick question for you: since RC_OVERIDE_TIME is now set to -1, once I start a script like this for a real quad instead of just SITL, is there any way for me to regain RC control in an emergency?
Say, if the script makes the quad behave unexpectedly, I would want to immediately resume manual control and fly the craft back or land. Is there any prescribed way to do that? Would I need to build that affordance/logic into the script itself, for example by detecting RC input from Python and aborting the rest of the script? Or is that something that’s supported by MP or AP already?
Interesting, thank you. Let me see if I understand the flow then.
RC7_OPTION=46
Set up a corresponding TX switch for RC7
When the switch is LOW (closer to 1000), normal RC override is disabled
When the switch is HIGH (closer to 2000), RC override is re-enabled
After flipping the switch, I regain RC control, so I can RTL or LAND
Is that what you meant?
If so, then what happens to the python script after the switch is flipped? Presumably it’s still running and fighting for control at the same time, no?
Yup, that’s exactly what I am trying to do. The Python script switches the copter to Guided mode and controls it programmatically. However, I still need to be able to abort and take control with a flip of a switch if the Guided mode flight goes haywire.
I am thinking that in addition to RC7_OPTION=46, I could perhaps use a background thread in the Python script to detect when the corresponding switch is being flipped, and automatically abort in that case (terminate the script via an exception, for example).
I don’t know if the real (TX) RC input is detectable from Python though… For example, via CurrentState.chx7in, or CurrentState.rcoveridech7, or CurrentState.hilch7… or some other piece of state. Do you know?