This repository has been archived by the owner on Apr 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpathHandler.py
147 lines (121 loc) · 4.87 KB
/
pathHandler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#
# Code common across shots to handle movement on paths
#
from pymavlink import mavutil
import location_helpers
import shotLogger
from shotManagerConstants import *
import math
import shots
logger = shotLogger.logger
#Path accel/decel constants
PATH_ACCEL = 2
ACCEL_PER_TICK = PATH_ACCEL * UPDATE_TIME
class PathHandler():
def __init__(self, vehicle, shotmgr):
self.vehicle = vehicle
self.shotMgr = shotmgr
# Automatic cruising of the cable
self.cruiseSpeed = 0.0
self.resumeSpeed = 0.0
def pause(self):
self.resumeSpeed = self.cruiseSpeed
self.setCruiseSpeed(0.0)
logger.log("[%s]: Pausing cruise" % shots.SHOT_NAMES[self.shotMgr.currentShot].lower())
def togglePause(self):
if self.isPaused():
self.resume()
else:
self.pause()
def resume(self):
self.setCruiseSpeed(0.0) # self.resumeSpeed to enable actual resume speed
logger.log("[%s]: Resuming cruise." % shots.SHOT_NAMES[self.shotMgr.currentShot].lower())
def isPaused(self):
return self.cruiseSpeed == 0.0
def setCruiseSpeed(self, speed):
self.cruiseSpeed = speed
# special case of PathHandler
class TwoPointPathHandler(PathHandler):
def __init__(self, pt1, pt2, vehicle, shotmgr):
PathHandler.__init__(self, vehicle, shotmgr)
self.pt1 = pt1
self.pt2 = pt2
self.curTarget = None
#for simulated acceleration
self.currentSpeed = 0.0
self.desiredSpeed = 0.0
# given RC input, calculate a speed and use it to
# move towards one of our endpoints
# return the speed we set for the copter
def MoveTowardsEndpt( self, channels ):
# allow both up/down and left/right to move along the cable
# use the max of them
if abs(channels[1]) > abs(channels[2]):
value = channels[1]
else:
value = -channels[2]
# user controls speed
if self.cruiseSpeed == 0.0:
self.desiredSpeed = value * MAX_SPEED
# cruise control
else:
speed = abs(self.cruiseSpeed)
# if sign of stick and cruiseSpeed don't match then...
if math.copysign(1,value) != math.copysign(1,self.cruiseSpeed): # slow down
speed *= (1.0 - abs(value))
else: # speed up
speed += (MAX_SPEED - speed) * abs(value)
# carryover user input sign
if self.cruiseSpeed < 0:
speed = -speed
# limit speed
if speed > MAX_SPEED:
speed = MAX_SPEED
elif -speed > MAX_SPEED:
speed = -MAX_SPEED
self.desiredSpeed = speed
# Synthetic acceleration
if self.desiredSpeed > self.currentSpeed:
self.currentSpeed += ACCEL_PER_TICK
self.currentSpeed = min(self.currentSpeed, self.desiredSpeed)
elif self.desiredSpeed < self.currentSpeed:
self.currentSpeed -= ACCEL_PER_TICK
self.currentSpeed = max(self.currentSpeed, self.desiredSpeed)
else:
self.currentSpeed = self.desiredSpeed
#Check direction of currentSpeed
goingForwards = self.currentSpeed > 0.0
if goingForwards:
target = self.pt2
else:
target = self.pt1
if target != self.curTarget: #switching target and logging
self.vehicle.simple_goto(target)
self.curTarget = target
logger.log("[%s]: Going to pt %d"%(shots.SHOT_NAMES[self.shotMgr.currentShot].lower(), 2 if goingForwards else 1 ) )
logger.log("[%s]: Target is %.12f, %.12f, %.12f."%
(shots.SHOT_NAMES[self.shotMgr.currentShot].lower(), target.lat, target.lon,
target.alt))
# should replace with a dronekit command when it gets in there
msg = self.vehicle.message_factory.command_long_encode(
0, 1, # target system, target component
mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, # frame
0, # confirmation
1, abs(self.currentSpeed), -1, # params 1-3
0.0, 0.0, 0.0, 0.0 ) # params 4-7 (not used)
# send command to vehicle
self.vehicle.send_mavlink(msg)
return abs(self.currentSpeed), goingForwards
# returns if we're near our target or not
def isNearTarget(self):
if self.desiredSpeed > 0.0 and \
location_helpers.getDistanceFromPoints3d( \
self.vehicle.location.global_relative_frame, \
self.pt2 ) < WAYPOINT_NEARNESS_THRESHOLD:
return True
elif self.desiredSpeed < 0.0 and \
location_helpers.getDistanceFromPoints3d( \
self.vehicle.location.global_relative_frame, \
self.pt1 ) < WAYPOINT_NEARNESS_THRESHOLD:
return True
return False