使用 Dronekit 着陆后起飞
Takeoff after Landing using Dronekit
我在 Arducopter v3.6.4 上使用 Pixhawk 2.1 Cube 和 Raspberry Pi 3 Model B 运行ning dronekit 脚本。我想做的是起飞,到达一个点并在那里降落,一段时间后起飞并 return 到家或其他点。我尝试在 SITL 上 运行 但没有成功。
我所做的是在 dronekit 中将模式从 GUIDED 更改为 LAND 以将无人机降落在某个点,然后我 运行 arm_and_takeoff() 函数但它只是拒绝武装,一次电机在着陆后自行解除武装。我只能中断脚本,如果我再次 运行 代码,电机会照常启动。
所以我想做的是
- 手臂和起飞
-飞到航点 1
- 在第 1 点着陆并停留一段时间
-再次武装和起飞
-去另一个点或return家
但代码仅 运行 完成第 3 步,并且在解除电机后不会自行武装。
我读了 peterbarker https://github.com/peterbarker 写的 post 关于 RTL 模式在着陆时停止解除电机但我无法让它在 SITL 上工作。
https://github.com/ArduPilot/ardupilot/pull/6914
from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative, Command
from pymavlink import mavutil # Needed for command message definitions
import time
import math
# Set up option parsing to get connection string
import argparse
parser = argparse.ArgumentParser(description='Control Copter and send commands in GUIDED mode ')
parser.add_argument('--connect',
help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()
connection_string = args.connect
sitl = None
# Start SITL if no connection string specified
if not connection_string:
import dronekit_sitl
sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()
# Connect to the Vehicle
print 'Connecting to vehicle on: %s' % connection_string
vehicle = connect(connection_string, wait_ready=True)
def arm_and_takeoff(aTargetAltitude):
"""
Arms vehicle and fly to aTargetAltitude.
"""
print "Basic pre-arm checks"
# Don't let the user try to arm until autopilot is ready
while not vehicle.is_armable:
print " Waiting for vehicle to initialise..."
time.sleep(1)
print "Arming motors"
# Copter should arm in GUIDED mode
vehicle.mode = VehicleMode("GUIDED")
vehicle.armed = True
while not vehicle.armed:
print " Waiting for arming..."
time.sleep(1)
print "Taking off!"
vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude
# Wait until the vehicle reaches a safe height before processing the goto (otherwise the command
# after Vehicle.simple_takeoff will execute immediately).
while True:
print " Altitude: ", vehicle.location.global_relative_frame.alt
if vehicle.location.global_relative_frame.alt >= aTargetAltitude * 0.95: # Trigger just below target alt.
print "Reached target altitude"
break
time.sleep(1)
def set_velocity_body(vehicle, vx, vy, vz):
""" Remember: vz is positive downward!!!
http://ardupilot.org/dev/docs/copter-commands-in-guided-mode.html
Bitmask to indicate which dimensions should be ignored by the vehicle
(a value of 0b0000000000000000 or 0b0000001000000000 indicates that
none of the setpoint dimensions should be ignored). Mapping:
bit 1: x, bit 2: y, bit 3: z,
bit 4: vx, bit 5: vy, bit 6: vz,
bit 7: ax, bit 8: ay, bit 9:
"""
msg = vehicle.message_factory.set_position_target_local_ned_encode(
0,
0, 0,
mavutil.mavlink.MAV_FRAME_BODY_NED,
0b0000111111000111, # -- BITMASK -> Consider only the velocities
0, 0, 0, # -- POSITION
vx, vy, vz, # -- VELOCITY
0, 0, 0, # -- ACCELERATIONS
0, 0)
vehicle.send_mavlink(msg)
vehicle.flush()
def goto_location(waypoint):
vehicle.simple_goto(waypoint)
time.sleep(2)
reached = 0
while(not reached):
time.sleep(1)
a = vehicle.velocity
if (abs(a[1])< 0.2 and abs(a[2])< 0.2 and abs(a[0])< 0.2):
reached = 1
print "Waypoint reached!"
def battery_check():
if(vehicle.battery < 9.9):
print ("Battery Low. Landing")
print "Battery: %s" % vehicle.battery
land()
else:
print "Battery: %s" % vehicle.battery
def land():
print("Vehicle in LAND mode")
vehicle.mode = VehicleMode("LAND")
while not vehicle.location.global_relative_frame.alt==0:
if vehicle.location.global_relative_frame.alt < 2:
set_velocity_body(vehicle,0,0,0.1)
vehicle.armed = False
vehicle.close()
def temp_land():
print("Vehicle in LAND mode")
vehicle.mode = VehicleMode("LAND")
while not vehicle.location.global_relative_frame.alt==0:
if vehicle.location.global_relative_frame.alt < 2:
set_velocity_body(vehicle,0,0,0.1)
print ("Vehicle in AUTO mode")
vehicle.mode = VehicleMode("AUTO")
def rtl():
print("Vehicle Returning to LAND mode")
vehicle.mode = VehicleMode("RTL")
def delay(sec):
print "Hover for %s Seconds" % sec
time.sleep(sec)
###################################################################################
################################ START CODE #######################################
###################################################################################
############# POINTS ###############
p1 = LocationGlobalRelative(24.830125, 67.097387, 15)
############# TAKE OFF #############
arm_and_takeoff(15) # Vehicle takeoff
home = vehicle.location.global_frame #HOME
print "Reached Target Altitude"
print "Altitude: ", vehicle.location.global_relative_frame.alt
print "Home Location: %s" % home
delay(1)
battery_check()
############# POINT 1 ##############
print "Going to Point 1"
goto_location(p1)
print "Reached Point 1"
print "Location: %s" % vehicle.location.global_frame
delay(1)
battery_check()
############### LAND ################
temp_land()
############ RETURN TO HOME ##########
print "Going to Home"
goto_location(home)
print "Reached Home"
print "Location: %s" % vehicle.location.global_frame
delay(1)
battery_check()
############# LAND #################
rtl() # Land vehicle once mission is over
vehicle.flush()
vehicle.close()
print "Exiting Script"
###################################################################################
################################# END CODE ########################################
###################################################################################
有没有办法解决这个问题?
谢谢。
此致
找到了解决这个问题的方法。在代码中着陆后必须重新连接车辆,并在着陆后更改其名称。
如果我在不更改 vehicle 变量的情况下重新连接它,它会起飞但不会第二次降落。
不过我希望有另一种方法可以做到这一点。
我在 Arducopter v3.6.4 上使用 Pixhawk 2.1 Cube 和 Raspberry Pi 3 Model B 运行ning dronekit 脚本。我想做的是起飞,到达一个点并在那里降落,一段时间后起飞并 return 到家或其他点。我尝试在 SITL 上 运行 但没有成功。
我所做的是在 dronekit 中将模式从 GUIDED 更改为 LAND 以将无人机降落在某个点,然后我 运行 arm_and_takeoff() 函数但它只是拒绝武装,一次电机在着陆后自行解除武装。我只能中断脚本,如果我再次 运行 代码,电机会照常启动。
所以我想做的是 - 手臂和起飞 -飞到航点 1 - 在第 1 点着陆并停留一段时间 -再次武装和起飞 -去另一个点或return家
但代码仅 运行 完成第 3 步,并且在解除电机后不会自行武装。
我读了 peterbarker https://github.com/peterbarker 写的 post 关于 RTL 模式在着陆时停止解除电机但我无法让它在 SITL 上工作。 https://github.com/ArduPilot/ardupilot/pull/6914
from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative, Command
from pymavlink import mavutil # Needed for command message definitions
import time
import math
# Set up option parsing to get connection string
import argparse
parser = argparse.ArgumentParser(description='Control Copter and send commands in GUIDED mode ')
parser.add_argument('--connect',
help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()
connection_string = args.connect
sitl = None
# Start SITL if no connection string specified
if not connection_string:
import dronekit_sitl
sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()
# Connect to the Vehicle
print 'Connecting to vehicle on: %s' % connection_string
vehicle = connect(connection_string, wait_ready=True)
def arm_and_takeoff(aTargetAltitude):
"""
Arms vehicle and fly to aTargetAltitude.
"""
print "Basic pre-arm checks"
# Don't let the user try to arm until autopilot is ready
while not vehicle.is_armable:
print " Waiting for vehicle to initialise..."
time.sleep(1)
print "Arming motors"
# Copter should arm in GUIDED mode
vehicle.mode = VehicleMode("GUIDED")
vehicle.armed = True
while not vehicle.armed:
print " Waiting for arming..."
time.sleep(1)
print "Taking off!"
vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude
# Wait until the vehicle reaches a safe height before processing the goto (otherwise the command
# after Vehicle.simple_takeoff will execute immediately).
while True:
print " Altitude: ", vehicle.location.global_relative_frame.alt
if vehicle.location.global_relative_frame.alt >= aTargetAltitude * 0.95: # Trigger just below target alt.
print "Reached target altitude"
break
time.sleep(1)
def set_velocity_body(vehicle, vx, vy, vz):
""" Remember: vz is positive downward!!!
http://ardupilot.org/dev/docs/copter-commands-in-guided-mode.html
Bitmask to indicate which dimensions should be ignored by the vehicle
(a value of 0b0000000000000000 or 0b0000001000000000 indicates that
none of the setpoint dimensions should be ignored). Mapping:
bit 1: x, bit 2: y, bit 3: z,
bit 4: vx, bit 5: vy, bit 6: vz,
bit 7: ax, bit 8: ay, bit 9:
"""
msg = vehicle.message_factory.set_position_target_local_ned_encode(
0,
0, 0,
mavutil.mavlink.MAV_FRAME_BODY_NED,
0b0000111111000111, # -- BITMASK -> Consider only the velocities
0, 0, 0, # -- POSITION
vx, vy, vz, # -- VELOCITY
0, 0, 0, # -- ACCELERATIONS
0, 0)
vehicle.send_mavlink(msg)
vehicle.flush()
def goto_location(waypoint):
vehicle.simple_goto(waypoint)
time.sleep(2)
reached = 0
while(not reached):
time.sleep(1)
a = vehicle.velocity
if (abs(a[1])< 0.2 and abs(a[2])< 0.2 and abs(a[0])< 0.2):
reached = 1
print "Waypoint reached!"
def battery_check():
if(vehicle.battery < 9.9):
print ("Battery Low. Landing")
print "Battery: %s" % vehicle.battery
land()
else:
print "Battery: %s" % vehicle.battery
def land():
print("Vehicle in LAND mode")
vehicle.mode = VehicleMode("LAND")
while not vehicle.location.global_relative_frame.alt==0:
if vehicle.location.global_relative_frame.alt < 2:
set_velocity_body(vehicle,0,0,0.1)
vehicle.armed = False
vehicle.close()
def temp_land():
print("Vehicle in LAND mode")
vehicle.mode = VehicleMode("LAND")
while not vehicle.location.global_relative_frame.alt==0:
if vehicle.location.global_relative_frame.alt < 2:
set_velocity_body(vehicle,0,0,0.1)
print ("Vehicle in AUTO mode")
vehicle.mode = VehicleMode("AUTO")
def rtl():
print("Vehicle Returning to LAND mode")
vehicle.mode = VehicleMode("RTL")
def delay(sec):
print "Hover for %s Seconds" % sec
time.sleep(sec)
###################################################################################
################################ START CODE #######################################
###################################################################################
############# POINTS ###############
p1 = LocationGlobalRelative(24.830125, 67.097387, 15)
############# TAKE OFF #############
arm_and_takeoff(15) # Vehicle takeoff
home = vehicle.location.global_frame #HOME
print "Reached Target Altitude"
print "Altitude: ", vehicle.location.global_relative_frame.alt
print "Home Location: %s" % home
delay(1)
battery_check()
############# POINT 1 ##############
print "Going to Point 1"
goto_location(p1)
print "Reached Point 1"
print "Location: %s" % vehicle.location.global_frame
delay(1)
battery_check()
############### LAND ################
temp_land()
############ RETURN TO HOME ##########
print "Going to Home"
goto_location(home)
print "Reached Home"
print "Location: %s" % vehicle.location.global_frame
delay(1)
battery_check()
############# LAND #################
rtl() # Land vehicle once mission is over
vehicle.flush()
vehicle.close()
print "Exiting Script"
###################################################################################
################################# END CODE ########################################
###################################################################################
有没有办法解决这个问题?
谢谢。
此致
找到了解决这个问题的方法。在代码中着陆后必须重新连接车辆,并在着陆后更改其名称。
如果我在不更改 vehicle 变量的情况下重新连接它,它会起飞但不会第二次降落。
不过我希望有另一种方法可以做到这一点。