3. TP Planification: étude d’un pont roulant#

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Markdown, display
from validation.validation import info_etudiant
def printmd(string):
display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None
if type(NUMERO_ETUDIANT) is not int :
printmd("**ERREUR:** numéro d'étudiant non spécifié!!!")
NOM, PRENOM, NUMERO_ETUDIANT=info_etudiant()
NOM='Toto'
PRENOM='toto'
# parametres spécifiques
_uid_ = NUMERO_ETUDIANT
_precis_ = 1.0e-5
printmd("**Login étudiant {} {} uid={}**".format(NOM,PRENOM,_uid_))
np.random.seed(_uid_)
# parametres
_XF_ = 4.0 + np.random.randint(4)
_L0_ = 5.0 + np.random.randint(10)
_L1_ = 2.0 + np.random.randint(10)
_L2_ = _L1_ /2.
_ALPHA_ = np.round(0.1+np.random.rand(),1)
printmd("**parametres de la trajectoire**: Xf={} L0={} Lf={} Lm={} alpha={}".
format(_XF_,_L0_,_L1_,_L2_,_ALPHA_))
ERREUR: numéro d’étudiant non spécifié!!!
Login étudiant Toto toto uid=137764122
parametres de la trajectoire: Xf=7.0 L0=7.0 Lf=8.0 Lm=4.0 alpha=0.8
3.1. Modélisation#
3.1.1. objectif#
On veut déplacer, à l’aide d’un système de levage par câble (grue ou pont roulant), une charge d’un endroit à un autre en évitant les oscillations résiduelles à l’arrivée. L’objectif est de proposer une stratégie de commande simple et réaliste qui repose sur une structure de commande hiérarchisée, composée de régulateurs de bas niveau rapides, simples et découplés et d’une commande de haut niveau lente et prenant en compte les couplages. En outre, on mesure la position et la vitesse du chariot ainsi que la position et la vitesse du treuil, mais la position de la charge n’est pas mesurée. C’est pourquoi nous ne considérons que des bouclages qui ne dépendent que des positions et vitesses du chariot et du treuil.
Le cas d’une trajectoire simple avec un cable de longueur constante \(L_0\) sera traiter ensemble en début de TP et vous aurez à traiter ensuite les 2 cas suivants avec les paramètres individuels données plus haut.
trajectoire ascendente directe avec levage du cable de \(L_0\) à \(L_f\) (de A à B)
trajectoire avec un obstacle nécessitant un levage du cable à \(L_m\) (de A à B en passant par C) (optionnel)
On vous demandera de rédiger un CR succinct sur ces 2 cas dans le fichier monCR.tex sur la stratégie de contrôle mise en place pour minimiser les oscillations de la charge en fin de trajectoire.
3.1.2. modélisation#

modèle mécanique = masse ponctuelle P (masse) et chariot (C)
pendule P de masse m de longueur \(l(t)\) accroché à un chariot C de masse M se deplacant horizontalement \(x_c(t)\)
système à 3 ddl \(xc(t), \theta(t), l(t) \)
treuil de rayon \(\rho\)
rayon \(\rho\) (on néglige son inertie \(J_\rho\))
angle \(\phi = (l-l_0)/\rho\)
%matplotlib inline
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
plt.rc('font', family='serif', size='14')
from sympy.physics.vector import init_vprinting
init_vprinting(use_latex='mathjax', pretty_print=False)
from sympy.physics.mechanics import dynamicsymbols, Point, ReferenceFrame
from sympy.physics.mechanics import Particle, Lagrangian, LagrangesMethod
3.1.3. Définition des repères et ddl#
définir les ddl avec
dynamicsymbolsdéfinir les paramètres avec
symbolsdéfinir les repères RO, RP
ReferencePointet les points O, P et CPoint
# définition des parametres
theta, xc, l = dynamicsymbols("theta x_c l")
thetap, xcp, lp = dynamicsymbols("theta x_c l",1)
m,M,g = sp.symbols('m M g')
t = sp.Symbol('t')
3.1.4. cinématique#
calcul vitesse des points P et C
définition des masses ponctuelles Pc et Pa associées au chariot et à la masse m
Particlecalcul de l’energie potentielle
# definition des masses ponctuelles et calcul de l'énergie potentiel
Pa = 0
Pc = 0
### BEGIN SOLUTION
Pc = Particle('P_c',C,M)
Pa = Particle('P_a',P,m)
display(Pa.kinetic_energy(RO))
Pa.potential_energy = m*g*Pa.point.pos_from(C).dot(RO.y)
display(Pa.potential_energy)
### END SOLUTION
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 5
3 Pc = 0
4 ### BEGIN SOLUTION
----> 5 Pc = Particle('P_c',C,M)
6 Pa = Particle('P_a',P,m)
7 display(Pa.kinetic_energy(RO))
NameError: name 'C' is not defined
3.1.5. Lagrangien#
calcul du lagrangien du système chariot+masse dans La
Lagrangian
3.1.6. Bilan des forces#
force motrice \(F\) sur le chariot en C
force de tension \(T\) dans le cable (ne travaille pas)
couple sur un treuil de rayon \(\rho\)
couple \(C\)
travail \(C_t \rho \delta l \)
\(\alpha = \frac{M}{m}\) rapport des masses
adimensionalisation:
\( F = F_c M = F_c\alpha m \)
\( C = C_t m \rho \)
définition d’un repère Rt lié au treuil
calcul angle \(\phi_t\) en fct de \(l(t)\) (enroulement autour du treuil)
\(l_0\) longueur de référence
3.1.7. Equations de Lagrange#
calcul des équations de Lagrange LagrangesMethod avec le travail des forces extérieures
force de traction du chariot Fc
couple sur le treuil Ct
3.2. Chariot mobile, longueur fixe#
on applique une force motrice horizontale \(F_c\) avec un cable de longueur \(l_0\) fixe
adim: \( F_c M = F_c \alpha m \)
\(\alpha = \frac{M}{m}\)
objectif:
déterminer la force \(F_c\) pour avoir un ballant minimum
tests de différents contrôle
contrôle du chariot seule
asservissement de la trajectoire du chariot
couplage de haut niveau
calcul du nouveau lagrangien
calcul des equations de lagranges
introduction de \(\alpha = M/m\)
# calcul equation de Lagrange
Fc = sp.symbols('F_c')
LM = 0
### BEGIN SOLUTION
LM = LagrangesMethod(LLa,[theta,xc],forcelist=[(C,Fc*alpha*m*RO.x)], frame = RO)
eq = sp.simplify(LM.form_lagranges_equations())
display(eq)
### END SOLUTION
3.2.1. 1ere methode: contrôle simple du chariot#
On contrôle uniquement le chariot \(x_c(t)\) sans tenir compte de l’interaction avec la masse P: on suppose que \(\theta \approx 0=cste\)
L’équation du mouvement du chariot s’écrit alors
on impose une trajectoire simple au chariot tq. $\( x_c(0)=0, \dot{x_c}(0)=0, x_c(t_f) = x_f, \dot{x_c}(t_f)=0\)$
d’où \(x_c(t)\) polynôme de degré 3
d’où la force \(F_c\) sur le chariot
definition analytique
conversion fonction python avec
lambdify
3.2.2. 2ieme méthode: asservissement simple#
on applique un asservissement simple pour avoir la trajectoire précédente
asservissement $\( F_a(t) = -K_c \left( (x(t)-x_i(t)) + T_c(\dot x - \dot x_i) \right) \)$
3.2.3. 3ieme méthode: commande de haut niveau lente#
linéarisation des équations
contrôle du positionnement de la charge P
calcul de la commande en fonction du mvt de la charge
3.2.3.1. mouvement de la charge#
calcul des coordonnées de la charge P: \(\xi(t)\), \(\eta(t)\) dans le repère fixe
relation entre \(\theta\) \(\xi\) et \(\eta\)
# calcul de xi et eta
display(P.pos_from(O).express(RO))
xi, eta = dynamicsymbols('xi eta')
display(sp.Eq(xi,P.pos_from(O).dot(RO.x)))
display(sp.Eq(eta,P.pos_from(O).dot(RO.y)))
display(sp.Eq(sp.tan(theta),(-xi+xc)/eta))
3.2.3.2. paramétrisation / trajectoire#
équation d’équilibre de la charge en fonction de la tension T
réécrire les équations du mvt pour obtenir \(\theta\) et \(x_c\) en fct de \(\xi\) et \(\eta\)
# relation xc et xi et eta
T = sp.Symbol('T')
display(sp.Eq(m*xi.diff(t,t) , -T*sp.sin(theta)))
display(sp.Eq(m*eta.diff(t,t), T*sp.cos(theta) - m*g))
display(sp.Eq(sp.tan(theta), -xi.diff(t,t)/(eta.diff(t,t)+g)))
display(sp.Eq(xc, xi - eta*xi.diff(t,t)/(eta.diff(t,t)+g)) )
3.2.3.3. paramétrisation#
si on connait \(\xi(t)\) et \(\eta(t)\) jusqu’à leurs dérivées d’ordre 4, peut donc déterminer le mouvement et calculer la force \(F_c\) “on doit calculer \(\ddot{x_c}\) et \(\ddot{\theta\)}$
idée on va déterminer le mouvement de la masse M (i.e. \(\xi(t)\) et \(\eta(t)\)) pour pouvoir en déduire la force \(F_c\). Pour cela on va se placer dans le cas de petites oscillations (linéarisation)
3.2.3.4. linéarisation \(\theta\) petit#
\(\eta = - l_0\)
\(\theta = -\frac{\ddot{\xi}}{g}\)
\(x_c = \xi + \frac{l_0}{g} \ddot{\xi}\)
\(\omega_0 ^2 = \frac{g}{l_0}\)
calcul de la force \(F_c\) dans ce cas en fct de \(\xi(t)\) et \(\omega_0\)
3.2.3.5. choix de la trajectoire \(\xi(t)\) la plus régulière t.q.#
On veut que la masse M soit immobile au départ et à l’arrivée
trajectoire \(\xi(t)\) idéale tq. $\(\xi(0)=0, \frac{d\xi}{dt}(0)=0, \frac{d^2\xi}{dt^2}(0)=0, \frac{d^3\xi}{dt^3}(0)=0, \frac{d^4\xi}{dt^4}(0)=0\)\( \)\(\xi(t_f)=x_f, \frac{d\xi}{dt}(t_f)=0, \frac{d^2\xi}{dt^2}(t_f)=0, \frac{d^3\xi}{dt^3}(t_f)=0, \frac{d^4\xi}{dt^4}(t_f)=0\)$
\(\xi(t)\) polynome de degré 9 en t
# calcul de xi dans x, Fcx, xcx et thx (theta)
xf, tf = sp.symbols('x_f t_f')
x = xf*(t/tf)**5*(126-420*(t/tf)+540*(t/tf)**2-315*(t/tf)**3+70*(t/tf)**4)
display(sp.Eq(xi,x))
# verification
print("dérivées en tf:",x.diff(t,1).subs({t:tf}),x.diff(t,2).subs({t:tf}),x.diff(t,3).subs({t:tf}),x.diff(t,4).subs({t:tf}))
# contrôle Fc
Fcx=Fc1.subs({xi.diff(t,4):x.diff(t,4),xi.diff(t,2):x.diff(t,2)}).doit().simplify()
display(sp.Eq(Fc,Fcx))
# position chariot xc
xcx= xi + xi.diff(t,2)/omega0**2
xcx= xcx.subs({xi:x}).doit().simplify()
display(sp.Eq(xc,xcx))
# angle theta
thx= -xi.diff(t,2)/(l0*omega0**2)
thx= thx.subs({xi:x}).doit().simplify()
display(sp.Eq(theta,thx))
3.2.4. Parametres de la simulation#
définition des paramètres
attention valeur des parametres KC et TC
optimal si \(\Delta=0\) i.e. \(Tc^2 = 4/K_c\)
printmd("### parametres trajectoire: Xf={} L0={} Lf={} Lm={} alpha={}".
format(_XF_,_L0_,_L1_,_L2_,_ALPHA_))
3.2.5. tracée de la solution idéale \(\xi(t)\)#
# tracer de la solution optimal avec xi(t)
XXI = XI(tt,XF,TF)
XCX = XC(tt,XF,TF,OMEGA0)
FFX = FX(tt,XF,TF,OMEGA0,ALPHA)
TTHX= THX(tt,XF,TF,OMEGA0,L0)
plt.figure(figsize=(10,8))
plt.subplot(3,1,1)
plt.plot(tt,XXI,label="P")
plt.plot(tt,XCX,'--',label="C")
plt.legend()
plt.title("Solution planifiée: position P et C")
plt.subplot(3,1,2)
plt.plot(tt,FFX)
plt.ylabel("Force $F_c$")
plt.subplot(3,1,3)
plt.plot(tt,TTHX,'--')
plt.ylabel("angle $\\theta$")
plt.xlabel('t');
# tracer du mouvement associé
plt.figure(figsize=(12,12))
for i in range(0,len(tt),20):
X,Y = [XCX[i],XXI[i]],[0.,-L0]
plt.plot(X,Y,'-o',ms=20)
plt.axis('equal');
3.2.6. Simulation avec les 3 contrôles#
commande simple Fs
asservissement simple Fa
commande lente couplée F
définition du second membre des equations de lagrange sous forme EDO du 1er ordre
display("Equations Lagrange:",LM.form_lagranges_equations())
# calcul du 2nd membre en fonction de C
display("F(Y)=",sp.simplify(LM.rhs()).doit())
smb = sp.simplify(sp.simplify(LM.rhs()).doit().subs({l:l0,g:omega0**2*l0}))
display("F(Y)=",smb)
smbF = sp.lambdify([theta,xc,thetap,xcp,Fc,l0,omega0,alpha],smb,'numpy')
# simulation avec les 3 controles
from scipy.integrate import odeint
# psition initiale idéale
Y0 = [0.0, 0.0, 0., 0. ]
print(L0,OMEGA0,ALPHA,TF,XF)
# perturbation
#Y0 = [0.01,0.01, 0.,0.]
tt = np.linspace(0,TF,Nt)
sol = odeint(F,Y0,tt)
sols= odeint(Fs,Y0,tt)
sola= odeint(Fa,Y0,tt)
# solution avec couplage
THETA = sol[:,0]
XXC = sol[:,1]
print("Erreur sur la position finale")
print("commande 1 simple erreur xc={:.4f} \t theta={:.3f} deg".format(sols[-1,1]-XF,np.degrees(sols[-1,0])))
print("commande 2 asservie erreur xc={:.4f} \t theta={:.3f} deg".format(sola[-1,1]-XF,np.degrees(sola[-1,0])))
print("commande 3 couplée erreur xc={:.4f} \t theta={:.3f} deg".format(sol[-1,1]-XF ,np.degrees(sol[-1,0])))
# tracer des 3 solutions
plt.figure(figsize=(12,8))
plt.subplot(2,1,1)
plt.plot(tt,sols[:,0],label="cde1 simple")
plt.plot(tt,sola[:,0],label="cde2 asservie")
plt.plot(tt,THETA , label="cde3 couplée")
plt.plot(tt,TTHX,'--',label="traj. opt")
plt.legend()
plt.title('angle $\\theta(t)$')
plt.subplot(2,1,2)
plt.plot(tt,sols[:,1],label="cde1 simple")
plt.plot(tt,sola[:,1],label="cde2 asservie")
plt.plot(tt,XXC, label="cde3 couplée")
plt.plot(tt,XCX,'--', label="traj. opt")
plt.legend()
plt.title('Position $x_c(t)$');
3.2.7. analyse solution commande simple#
from validation.Chariot import Chariot
pas = 5
chariots = Chariot(L0,sols[::pas,1],sols[::pas,0],tt[pas])
chariots.trace(titre="commande simple",pas=4)
# animation
anims = chariots.calculanim(-0.5, XF+0.5, -1.2*L0, 0.5)
plt.rc('animation', html='jshtml')
anims
3.2.8. analyse solution commande asservie#
chariota = Chariot(L0,sola[::pas,1],sola[::pas,0],tt[pas])
chariota.trace(titre="asservissement simple",pas=4)
# animation
anima = chariota.calculanim(-0.5, XF+0.5, -1.2*L0, 0.5)
plt.rc('animation', html='jshtml')
anima
3.2.9. analyse solution commande couplée#
# tracer du mouvement cde lente couplee
chariotc = Chariot(L0,XXC[::pas],THETA[::pas],tt[pas])
chariotc.trace(titre="cde lente couplée",pas=4)
# animation
animc = chariotc.calculanim(-0.5, XF+0.5, -1.2*L0, 0.5)
plt.rc('animation', html='jshtml')
animc
3.3. Asservissement: regulateur bas niveau#
pour rendre la commande précédente robuste on ajoute un asservissement pour suivre la trajectoire idéale
trajectoire imposée \(x_i(t)\) à partir de \(\xi(t)\) $\(x_i(t) = \xi + \frac{l_0}{g} \ddot{\xi}\)$
au lieu d’imposer directement la trajectoire, on ajoute un régulateur à la cde précédente $\( F_c = F_i -K_c ( (x_c-x_i) + T_c(\dot{x_c}-\dot{x_i})) \)$
# definition du 2nd membre de l'EDO et de la force de controle Fca
smbF = sp.lambdify([theta,xc,thetap,xcp,l0,omega0,alpha,Fc],smb)
FCa = sp.lambdify([t,xc,xcp,tf,xf,omega0,Kc,Tc],Fca)
3.3.1. simulation#
calculer la commande FC = cde idéale + asservissement
# parametres
KC = 200
TC = np.sqrt(4/KC)
print("parametres:",KC,TC,TF)
# simulation
Y0 = [0.0, 0.0, 0., 0. ]
sol = odeint(F,Y0,tt)
THETA = sol[:,0]
XXC = sol[:,1]
print("Erreur sur la position finale")
print("commande couplée erreur xc={:.3f} \t theta={:.3f} deg".format(sol[-1,1]-XF ,np.degrees(sol[-1,0])))
# comparaison avec trajectoire idéale
plt.figure(figsize=(12,8))
plt.subplot(2,1,1)
plt.plot(tt,XXC)
plt.plot(tt,XCX,'--')
plt.ylabel("$\\xi$")
plt.title("comparaison avec traj. ideale")
plt.subplot(2,1,2)
plt.plot(tt,THETA)
plt.plot(tt,TTHX,'--')
plt.xlabel('t')
plt.ylabel("$\\theta$");
chariot = Chariot(L0,XXC[::pas],THETA[::pas],tt[pas])
chariot.trace(titre="asservisement + commande lente couplée",pas=4)
# animation
anim = chariot.calculanim(-0.5, XF+0.5, -1.2*L0, 0.5)
plt.rc('animation', html='jshtml')
anim
3.4. Chariot mobile et longueur de cable variable#
3.4.1. mouvement de la charge#
coordonnees \(\xi(t)\), \(\eta(t)\) dans le repere fixe (voir cours) $\(\xi = l \sin\theta + x-c \)\( \)\(\eta = -l \cos\theta \)$
équations d’équilibre $\( m\ddot\xi = -T \sin\theta\)\( \)\( m\ddot\xi = -T \sin\theta\)$
d’où l’expression de \(\theta\), \(l\) et \(x_c\) en fonction de \(\xi\) et \(\eta\)
trajectoire idéale
on planifie une trajectoire idéale pour \(\xi\) et \(\eta\) , et on en déduit la valeur de \(x_c(t)\) \(\theta(t)\) et \(l(t)\), et le contrôle associé
trajectoire rectiligne AB

xi, eta = dynamicsymbols('xi eta')
display(sp.Eq(sp.tan(theta), xi.diff(t,t)/(eta.diff(t,t)-g)))
display(sp.Eq(xc, xi - eta*xi.diff(t,t)/(eta.diff(t,t)-g)) )
3.4.1.1. trajectoire planifiée#
on utilise la trajectoire planifiée précédente pour \(\xi(t)\)
trajectoire \(\xi(t)\) tq. $\(\xi(0)=0, \frac{d\xi}{dt}(0)=0, \frac{d^2\xi}{dt^2}(0)=0, \frac{d^3\xi}{dt^3}(0)=0, \frac{d^4\xi}{dt^4}(0)=0\)\( \)\(\xi(t_f)=x_f, \frac{d\xi}{dt}(t_f)=0, \frac{d^2\xi}{dt^2}(t_f)=0, \frac{d^3\xi}{dt^3}(t_f)=0, \frac{d^4\xi}{dt^4}(t_f)=0\)$
\(\xi(t)\) polynome de degré 9 en t
pour la trajectoire \(\eta(t)\) (même condition que \(\xi\)) sauf sur la position
\(\eta=-l_0\) longueur à \(t=0\)
\(\eta=-l_f\) longueur à \(t=t_f\)
xf, tf = sp.symbols('x_f t_f')
x = xf*(t/tf)**5*(126-420*(t/tf)+540*(t/tf)**2-315*(t/tf)**3+70*(t/tf)**4)
display(sp.Eq(xi,x))
# verification
print("dérivées en tf:",x.diff(t,1).subs({t:tf}),x.diff(t,2).subs({t:tf}),x.diff(t,3).subs({t:tf}),x.diff(t,4).subs({t:tf}))
lf = sp.symbols('l_f')
y = - l0 - (lf - l0)*(x/xf)
display(sp.Eq(eta,y))
3.4.2. cas linéaire#
on suppose que \(\theta \approx 0\)
trajectoire idéale du chariot et du cable : $\(x_{ref}(t) \approx \xi(t) \)\( \)\(l_{ref}(t) \approx - \eta(t)\)$
d’ou l’asservissement de \(F_c\) et \(C_t\)
xref = x
lref = -y
display("trajectoire idéale:",xref, lref)
# asservissement
Kc, Tc = sp.symbols('K_c T_c')
Fca = -Kc*((xc-xref)+(xcp-xref.diff(t,1))*Tc)
Fca = Fca.simplify()
display(Fca)
Kt, Tt = sp.symbols('K_t T_t')
Cta = -g -Kt*((l-lref)+(lp-lref.diff(t,1))*Tt)
Cta = Cta.simplify()
display(Cta)
# fct python
FCa = 0
CTa = 0
Xref = 0
Lref = 0
### BEGIN SOLUTION
FCa = sp.lambdify([t,xc,xcp,xf,tf,Kc,Tc],Fca,'numpy')
CTa = sp.lambdify([t,l,lp,l0,lf,tf,Kt,Tt,g],Cta,'numpy')
Xref= sp.lambdify([t,xf,tf],xref,'numpy')
Lref= sp.lambdify([t,l0,lf,tf],lref,'numpy')
### END SOLUTION
3.4.3. Equation lagrange avec couple#
alpha = sp.Symbol('alpha')
La = sp.simplify(La.subs({M:alpha*m}))
display(La)
Fc, Ct = sp.symbols('F_c C_t')
LM = LagrangesMethod(La,[theta,xc,l],forcelist=[(C,Fc*alpha*m*RO.x),(Rt,Ct*m*rho*RO.z)], frame = RO)
eq = sp.simplify(LM.form_lagranges_equations())
display(eq)
# calcul du second membre
smb = sp.simplify(sp.simplify(LM.rhs()).doit())
display(smb)
smbF = sp.lambdify([theta,xc,l,thetap,xcp,lp,Fc,Ct,g,alpha],smb,'numpy')
3.4.4. Simulation de la trajectoire#
printmd("### parametres trajectoire: Xf={} L0={} Lf={} Lm={} alpha={}".
format(_XF_,_L0_,_L1_,_L2_,_ALPHA_))
# PARAMETRES NUMERIQUES
TF = 10.0
#TF = 8.0
XF = 0
L0 = 0
LF = 0
ALPHA = 0
### BEGIN SOLUTION
XF = 4.0
ALPHA = 0.5
L0 = 3.0
LF = 2.0
### END SOLUTION
GG = 9.81
#
KC = 50.0
TC = 20./KC
KT = 50.0
TT = 20./KT
Nt = 400
tt = np.linspace(0,TF,Nt)
# trajectoire idéale linéarisée
XREF = Xref(tt,XF,TF)
LREF = Lref(tt,L0,LF,TF)
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.plot(tt,XREF)
plt.title("Position ")
plt.subplot(1,2,2)
plt.plot(tt,LREF)
plt.title("Longueur")
3.5. cas non linéaire#
ddl fonction de la trajectoire (idéale) \(\xi\) \(\eta\) $\( x_{ref} = \xi - \frac{\eta\ddot{\xi}}{\ddot{\eta}-g}\)$
xref = x - y*x.diff(t,2)/(y.diff(t,2)-g)
xref = xref.doit()
lref = sp.sqrt((y*x.diff(t,2)/(y.diff(t,2)-g))**2 + y**2)
lref = lref.doit()
print(xref, lref)
# asservissement pour obtenir la trajectoire
Kc, Tc = sp.symbols('K_c T_c')
Fca = -Kc*((xc-xref)+(xcp-xref.diff(t,1))*Tc)
#Fca = Fca.simplify()
#display(Fca)
print(Fca)
Kt, Tt = sp.symbols('K_t T_t')
Cta = -g - Kt*((l-lref)+(lp-lref.diff(t,1))*Tt)
#Cta = Cta.simplify()
#display(Cta)
print(Cta)
# fct numpy
FCa = sp.lambdify([t,xc,xcp,xf,l0,lf,tf,Kc,Tc,g],Fca,'numpy')
CTa = sp.lambdify([t,l,lp,xf,l0,lf,tf,Kt,Tt,g],Cta,'numpy')
Xref= sp.lambdify([t,xf,l0,lf,tf,g],xref,'numpy')
Lref= sp.lambdify([t,xf,l0,lf,tf,g],lref,'numpy')
# trajectoire ideale
XREF = Xref(tt,XF,L0,LF,TF,GG)
LREF = Lref(tt,XF,L0,LF,TF,GG)
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.plot(tt,XREF)
plt.title("Position ")
plt.subplot(1,2,2)
plt.plot(tt,LREF)
plt.title("Longueur")
# fonction 2nd membre
def F(Y,t):
'''2nd mbre de l EDO dY/dt = F(Y,t) '''
global ALPHA,TF,XF
### BEGIN SOLUTION
FC = FCa(t,Y[1],Y[4],XF,L0,LF,TF,KC,TC,GG)
CT = CTa(t,Y[2],Y[5],XF,L0,LF,TF,KT,TT,GG)
FF = smbF(Y[0],Y[1],Y[2],Y[3],Y[4],Y[5],FC,CT,GG,ALPHA)
return FF[:,0]
### END SOLUTION
# simulation
Y0 = [0.0, 0.0, L0, 0., 0., 0. ]
print(F(Y0,0.))
sol = odeint(F,Y0,tt)
THETA = sol[:,0]
XC = sol[:,1]
LL = sol[:,2]
plt.figure(figsize=(12,6))
plt.subplot(1,3,1)
plt.plot(tt,THETA*180/np.pi)
plt.ylim(-10,10)
plt.title("Angle$\\theta$ en degré")
plt.subplot(1,3,2)
plt.plot(tt,XC)
plt.plot(tt,XREF,'--')
plt.title('Position $x_c(t)$')
plt.subplot(1,3,3)
plt.plot(tt,LL)
plt.plot(tt,LREF,'--')
plt.title('longueur $l(t)$')
# tracer du mouvement
plt.figure(figsize=(12,8))
for i in range(0,len(tt),20):
X,Y = [XC[i],XC[i]+LL[i]*np.sin(THETA[i])],[0.,-LL[i]*np.cos(THETA[i])]
plt.plot(X,Y,'-o',ms=20)
plt.axis('equal')
3.6. Evitement d’un obstacle (optionnel)#
au milieu de la trajectoire se trouve un obstacle et la charge doit avoir en ce point une hauteur \(l_m\).
Refaire la planification de trajectoire dans ce cas: trajectoire ACB

sans obstacle la trajectoire droite: $\( y = l_0 + (l_f-l_0) x \)$
avec obstacle tq \(y=y_a\): on xie par une parabole $\( y = l_0 + (l_f-l_0) x (a+bx+cx^2)\)$
avec 3 conditions:
\(y = l_f\) en x=1
\(y = l_a\) en x=1/2
\(\dot{y} = 0\) en x=1/2
pour \(l_a = 2l_f - l_0\) on trouve: