Uni-Logo
Sie sind hier: Startseite Professuren Diehl, Moritz Events Dateien Template, exercise 8 (tracking)

Template, exercise 8 (tracking)

template_tracking.py — Python Source, 3Kb

Dateiinhalt

from casadi import *
from quadcopter import *
from casadi.tools import *
from pylab import *

show_3d = False

# Construct the quadcopter model
model = Quadcopter()

# Get the ode model function
f = model.f

T = 3.0
N = 200

DT = T/N

# This constructs an object that behaves like an MX,
# but has convenient accessors
# e.g  W["X",0] returns x_0 (the state at the first control interval)
# 
# For more information about this CasADi feature,
# you could consult an online tutorial
#    docs.casadi.org    ->   scroll to bottom
#                       ->   click tutorials
#                       ->   tools
#                       ->   structure.pdf
#
# At this point, do not attempt to fully
# understand this, but just proceed and learn by example
W = struct_symMX([
    (
     entry("X",struct=model.x,repeat=N+1),
     entry("Y",struct=model.x,repeat=N),
     entry("U",struct=model.u,repeat=N)
    )
])  

ts = [0]
t = 0

# Build up the list of constraints
g = []
for i in range(N):
  [xdot] = f([ W["Y",i], W["U",i] ])
  
  g.append(...) # TODO: fill in
  g.append(...)
  
  t = t + DT
  ts.append(t)
  
g = vertcat(g)

# Construct the reference to track
traj = [ array([sin(i*DT*2*pi/3),i*DT*2*pi/3,0]) for i in range(N) ]

# Construct the objective

# Fill in
#  Hint: build up a list of expressions first, and then vertcat 
R1 = ...
R2 = ...

alpha = 0.05

obj = (T/N) * ( mul(R1.T, R1) + alpha*mul(R2.T, R2) )

# Create the NLP
nlp = MXFunction( nlpIn(x=W), nlpOut(f=obj, g=g) )
nlp.init()

# Create an IPOPT NLP solver
solver = NlpSolver("ipopt",nlp)
solver.setOption("max_iter",100)
solver.init()

# All constraints are equality constraints in this case
solver.setInput(0, "lbg")
solver.setInput(0, "ubg")

# Construct and populate the vectors with
# upper and lower simple bounds
#
# lbx is an array in disguise.
# You can view the underlying array as lbx.cat
lbx = W(-inf)
ubx = W(inf)

#  0 <= u_k <= 0.5 
lbx["U",:] =  0
ubx["U",:] =  0.5

#  p_0 = [0,0,0]^T
lbx["X",0,"p"] = 0.0
ubx["X",0,"p"] = 0.0

#  v_0 = [0,0,0]^T
...
...


# Construct a vector with the initial guess
x0 = W(0)
x0["X",:] = model.x0
...
...

# Extra info: model.x0 is just an array in disguise,
# you can look through the disguise by doing:
# print model.x0.cat


solver.setInput(x0,  "x0")
solver.setInput(lbx, "lbx")
solver.setInput(ubx, "ubx")

# Solve the NLP
solver.evaluate()

# Cast the result vector in a form
# that we can easily access
sol = W(solver.getOutput("x"))


# Save solution to a file
import pickle
pickle.dump(sol,file('tracking.pkl','w'))

X = sol["X",:,"p","x"]
Y = sol["X",:,"p","y"]
Z = sol["X",:,"p","z"]

# 2D plots

figure()
plot(ts,X,label="p_x")
plot(ts,Y,label="p_y")
plot(ts,Z,label="p_z")
plot(ts[:-1],horzcat(traj)[0,:].T,label="p_ref_x")
plot(ts[:-1],horzcat(traj)[1,:].T,label="p_ref_y")
xlabel("Time [s]")
legend(loc="upper left")

title("State trajectories")

figure()
plot(X,Y,'.',label="optimized")
plot(horzcat(traj)[0,:].T,horzcat(traj)[1,:].T,'.',label="reference")
legend()

title("Top down trajectory view")
xlabel("x [m]")
xlabel("y [m]")
axis('equal')

figure()
step(ts, horzcat(sol["U",:]+[ sol["U",-1] ]).T,where='post')
xlabel("Time [s]")
title("Control trajectories")
ylim([-0.1,0.6])

if show_3d:
  # 3D plots
  from mpl_toolkits.mplot3d import Axes3D
  figure()
  ax = gca(projection='3d')

  ax.plot(array(X),array(Y),array(Z),"b.",label="optimized")

  Traj = array(horzcat(traj)) 
  ax.plot(Traj[:,0],Traj[:,1],Traj[:,2],'g.',label="reference")

  # Plot the rotors
  circle = array([ [cos(t),sin(t),0] for t in linspace(0,2*pi) ]).T*0.1

  for p, q in zip(sol["X",::20,"p"],sol["X",::20,"q"]):
    for offset in [ array([[1,0,0]]),array([[0,1,0]]),array([[-1,0,0]]),array([[0,-1,0]]) ]:
      circle_offset = circle + 0.1*offset.T
      circle_3D = mul(quat(*q), circle_offset)
      ax.plot(
        array(p[0]+circle_3D[0,:]).squeeze(),
        array(p[1]+circle_3D[1,:]).squeeze(),
        array(p[2]+circle_3D[2,:]).squeeze(),
        'k'
      )

  ax.set_xlim([-pi,pi])
  ax.set_ylim([0,2*pi])
  ax.set_zlim([-pi,pi])

  legend()

show()
« Mai 2025 »
Mai
MoDiMiDoFrSaSo
1234
567891011
12131415161718
19202122232425
262728293031
Benutzerspezifische Werkzeuge