1
-
2
1
import math
3
2
import scipy .integrate
4
3
import scipy .optimize
7
6
from collections import namedtuple
8
7
from roboticstoolbox .mobile import *
9
8
9
+
10
10
def solvepath (x , q0 = [0 , 0 , 0 ], ** kwargs ):
11
11
# x[:4] is 4 coeffs of curvature polynomial
12
12
# x[4] is total path length
@@ -16,7 +16,7 @@ def solvepath(x, q0=[0, 0, 0], **kwargs):
16
16
def dotfunc (s , q , poly ):
17
17
# q = (x, y, θ)
18
18
# qdot = (cosθ, sinθ, ϰ)
19
- k = poly [0 ] * s ** 3 + poly [1 ] * s ** 2 + poly [2 ] * s + poly [3 ]
19
+ k = poly [0 ] * s ** 3 + poly [1 ] * s ** 2 + poly [2 ] * s + poly [3 ]
20
20
# k = ((poly[0] * s + poly[1]) * s + poly[2]) * s + poly[3]
21
21
22
22
# save maximum curvature for this path solution
@@ -31,11 +31,13 @@ def dotfunc(s, q, poly):
31
31
sol = scipy .integrate .solve_ivp (dotfunc , [0 , s_f ], q0 , args = (cpoly ,), ** kwargs )
32
32
return sol .y , maxcurvature
33
33
34
+
34
35
def xcurvature (x ):
35
36
# inequality constraint function, must be non-negative
36
37
_ , maxcurvature = solvepath (x , q0 = (0 , 0 , 0 ))
37
38
return maxcurvature
38
39
40
+
39
41
def costfunc (x , start , goal ):
40
42
# final cost of path from start with params
41
43
# p[0:4] is polynomial: k0, a, b, c
@@ -49,8 +51,9 @@ def costfunc(x, start, goal):
49
51
e = np .linalg .norm (path [:, - 1 ] - np .r_ [goal ])
50
52
51
53
return e
52
- class CurvaturePolyPlanner (PlannerBase ):
53
54
55
+
56
+ class CurvaturePolyPlanner (PlannerBase ):
54
57
def __init__ (self , curvature = None ):
55
58
"""
56
59
Continuous curvature path planner
@@ -81,7 +84,6 @@ def __init__(self, curvature=None):
81
84
super ().__init__ (ndims = 3 )
82
85
self .curvature = curvature
83
86
84
-
85
87
def query (self , start , goal ):
86
88
r"""
87
89
Find a path betwee two configurations
@@ -113,41 +115,51 @@ def query(self, start, goal):
113
115
self ._start = start
114
116
self ._goal = goal
115
117
116
- # initial estimate of path length is Euclidean distance
118
+ # initial estimate of path length is Euclidean distance
117
119
d = np .linalg .norm (goal [:2 ] - start [:2 ])
118
120
# state vector is kappa_0, a, b, c, s_f
119
121
120
122
if self .curvature is not None :
121
- nlcontraints = (scipy .optimize .NonlinearConstraint (xcurvature , 0 , self .curvature ),)
123
+ nlcontraints = (
124
+ scipy .optimize .NonlinearConstraint (xcurvature , 0 , self .curvature ),
125
+ )
122
126
else :
123
127
nlcontraints = ()
124
128
125
- sol = scipy .optimize .minimize (costfunc , [0 , 0 , 0 , 0 , d ],
129
+ sol = scipy .optimize .minimize (
130
+ costfunc ,
131
+ [0 , 0 , 0 , 0 , d ],
126
132
constraints = nlcontraints ,
127
133
bounds = [(None , None ), (None , None ), (None , None ), (None , None ), (d , None )],
128
- args = (start , goal ))
134
+ args = (start , goal ),
135
+ )
129
136
print (sol )
130
- path , maxcurvature = solvepath (sol .x , q0 = start , dense_output = True , max_step = 1e-2 )
137
+ path , maxcurvature = solvepath (
138
+ sol .x , q0 = start , dense_output = True , max_step = 1e-2
139
+ )
131
140
132
- status = namedtuple ('CurvaturePolyStatus' , ['length' , 'maxcurvature' , 'poly' ])(sol .x [4 ], maxcurvature , sol .x [:4 ])
141
+ status = namedtuple ("CurvaturePolyStatus" , ["length" , "maxcurvature" , "poly" ])(
142
+ sol .x [4 ], maxcurvature , sol .x [:4 ]
143
+ )
133
144
134
145
return path .T , status
135
146
136
- if __name__ == '__main__' :
147
+
148
+ if __name__ == "__main__" :
137
149
from math import pi
138
150
139
151
# start = (1, 1, pi/4)
140
152
# goal = (-3, -3, -pi/4)
141
- start = (0 , 0 , - pi / 4 )
142
- goal = (1 , 2 , pi / 4 )
153
+ # start = (0, 0, -pi/4)
154
+ # goal = (1, 2, pi/4)
143
155
144
- start = (0 , 0 , pi / 2 )
145
- goal = (1 , 0 , pi / 2 )
156
+ start = (0 , 0 , pi / 2 )
157
+ goal = (1 , 0 , pi / 2 )
146
158
147
159
planner = CurvaturePolyPlanner ()
148
160
path , status = planner .query (start , goal )
149
- print (' start' , path [0 ,:])
150
- print (' goal' , path [- 1 , :])
161
+ print (" start" , path [0 , :])
162
+ print (" goal" , path [- 1 , :])
151
163
152
164
print (status )
153
165
planner .plot (path , block = True )
@@ -163,4 +175,4 @@ def query(self, start, goal):
163
175
# c[i] /= sf ** (3-i)
164
176
165
177
# print(solvepath(np.r_[c, 1], start))
166
- # print(c)
178
+ # print(c)
0 commit comments