fix:新增例程

This commit is contained in:
2025-07-25 17:54:28 +08:00
parent 78481c265e
commit 637343d716
108 changed files with 5755 additions and 0 deletions

View File

@@ -0,0 +1,197 @@
# import required libraries
import time
import numpy as np
import cv2
# import RflySim APIs
import PX4MavCtrlV4 as PX4MavCtrl
import ScreenCapApiV4 as sca
import UE4CtrlAPI
ue = UE4CtrlAPI.UE4CtrlAPI()
# Function to calculate the location and radius of red ball
def calc_centroid(img):
"""Get the centroid and area of Red in the image"""
low_range = np.array([0,0,80])
high_range = np.array([100,100,255])
th = cv2.inRange(img, low_range, high_range)
dilated = cv2.dilate(th, cv2.getStructuringElement(
cv2.MORPH_ELLIPSE, (3, 3)), iterations=2)
cv2.imshow("dilated", dilated)
cv2.waitKey(1)
M = cv2.moments(dilated, binaryImage=True)
if M["m00"] >= min_prop*width*height:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
return [cx, cy, M["m00"]]
else:
return [-1, -1, -1]
# Function to obtain velocity commands for Pixhawk
# according to the image processing results
def controller(p_i):
# if the object is not in the image, search in clockwise
if p_i[0] < 0 or p_i[1] < 0:
return [0, 0, 0, 1]
# found
ex = p_i[0] - width / 2
ey = p_i[1] - height / 2
vx = 2 if p_i[2] < max_prop*width*height else 0
vy = 0
vz = K_z * ey
yawrate = K_yawrate * ex
# return forward, rightward, downward, and rightward-yaw
# velocity control sigals
return [vx, vy, vz, yawrate]
# Process image to obtain vehicle velocity control command
def procssImage():
img_bgr=sca.getCVImg(ImgInfo1)
p_i = calc_centroid(img_bgr)
ctrl = controller(p_i)
return ctrl
# saturation function to limit the maximum velocity
def sat(inPwm,thres=1):
outPwm= inPwm
for i in range(len(inPwm)):
if inPwm[i]>thres:
outPwm[i] = thres
elif inPwm[i]<-thres:
outPwm[i] = -thres
return outPwm
# Create MAVLink control API instance
mav = PX4MavCtrl.PX4MavCtrler(1)
# Init MAVLink data receiving loop
mav.InitMavLoop()
isEmptyData = False
lastTime = time.time()
startTime = time.time()
# time interval of the timer
timeInterval = 1/30.0 #here is 0.0333s (30Hz)
flag = 0
# parameters
width = 720
height = 405
channel = 4
min_prop = 0.000001
max_prop = 0.3
K_z = 0.003 * 640 / height
K_yawrate = 0.005 * 480 / width
# send command to all RflySim3D windows to switch to the blank grass scene
# by default, there are two windows, the first is front camera
# for vison control, and the second window for observation
ue.sendUE4Cmd('RflyChangeMapbyName VisionRingBlank')
time.sleep(1)
# create a ball, set its position and altitude, use the default red color
ue.sendUE4Pos(100,152,0,[3,0,-2],[0,0,0])
time.sleep(0.5)
# Change the target vehicle to copterID=1's vehicle
ue.sendUE4Cmd('RflyChangeViewKeyCmd B 1',0)
time.sleep(0.5)
# Switch its viewpoint to oboard #1 (front camera view)
ue.sendUE4Cmd('RflyChangeViewKeyCmd V 1',0)
time.sleep(0.5)
# move the camera to the position [0.3,0,0.05] related to the body
ue.sendUE4Cmd('RflyCameraPosAng 0.3 0 0.05 0 0 0',0)
time.sleep(0.5)
# set the RflySim3D window size to 720x405
# Send command to UE4 Window 1 to change resolution
ue.sendUE4Cmd('r.setres 720x405w',1)
time.sleep(2)
# Send command to UE4 Window 1 to change resolution
ue.sendUE4Cmd('r.setres 720x405w',0)
time.sleep(2)
# Get handles of all UE4/RflySim3D windows
window_hwnds = sca.getWndHandls()
try:
# Move UE4 windows 0 to desired position and keep top
xx,yy=sca.moveWd(window_hwnds[0],0,0,True)
time.sleep(0.5)
# Move UE4 windows 0 to desired position (next to windows 0) and keep top
xx,yy=sca.moveWd(window_hwnds[1],xx,0,False)
except Exception as e :
print('Please move the window manually')
xx=720
yy=405
# Get the info of the first window (index=0)
ImgInfo1 = sca.getHwndInfo(window_hwnds[0])
num=0
lastClock=time.time()
# Start a endless loop with 30Hz, timeInterval=1/30.0
ctrlLast = [0,0,0,0]
while True:
lastTime = lastTime + timeInterval
sleepTime = lastTime - time.time()
if sleepTime > 0:
time.sleep(sleepTime) # sleep until the desired clock
else:
lastTime = time.time()
# The following code will be executed 30Hz (0.0333s)
num=num+1
if num%100==0:
tiem=time.time()
print('MainThreadFPS: '+str(100/(tiem-lastClock)))
lastClock=tiem
if time.time() - startTime > 5 and flag == 0:
# The following code will be executed at 5s
print("5s, Arm the drone")
mav.initOffboard()
flag = 1
mav.SendMavArm(True) # Arm the drone
print("Arm the drone!, and fly to NED 0,0,-5")
mav.SendPosNED(0, 0, -5, 0) # Fly to target position [0, 0, -5], i.e., take off to 5m
if time.time() - startTime > 15 and flag == 1:
flag = 2
# The following code will be executed at 15s
mav.SendPosNED(-30,-5, -5, 0) # Fly to target position [-30,-5, -5]
print("15s, fly to pos: -30,-5, -5")
if time.time() - startTime > 25 and flag == 2:
flag = 3
# Show CV image and set the position
img_bgr=sca.getCVImg(ImgInfo1)
cv2.imshow("dilated", img_bgr)
cv2.waitKey(1)
time.sleep(0.5)
cv2.moveWindow("dilated",0,yy)
print("25s, start to shoot the ball.")
if time.time() - startTime > 25 and flag == 3:
ctrlNow = procssImage()
ctrl = sat(ctrlNow,5)
# add a inertial component here to restrain the speed variation rate
if ctrl[0]-ctrlLast[0] > 0.5:
ctrl[0]=ctrlLast[0]+0.05
elif ctrl[0]-ctrlLast[0] < -0.5:
ctrl[0]=ctrlLast[0]-0.05
if ctrl[1]-ctrlLast[1] > 0.5:
ctrl[1]=ctrlLast[1]+0.05
elif ctrl[1]-ctrlLast[1] < -0.5:
ctrl[1]=ctrlLast[1]-0.05
ctrlLast = ctrl
# if control signals is obtained, send to Pixhawk
if not isEmptyData:
mav.SendVelFRD(ctrl[0], ctrl[1], ctrl[2], ctrl[3])