In [1]:
# This file is prepared by Dr. Heung Wing Joseph Lee
# as a demonstration
# 
# Apollonius pursuit
# 
# Pursuer and Target are travelling on 2D centered at the origin
# The target is travelling in constant speed 1 and fixed direction 
# start from (0,0)
# The pursuer is travelling in constant speed 0.8 (slower), and
# in constant direction (system parameter chosen by GEKKO), and
# start from (1,0)
# The problem is to find the minimum time (system parmeter) of intercept
# Note that the interception must be on the Apollonius Circle, if exist,
# for various values of target moving direction.
#
# if gekko is not installed, uncomment (delete #) in the following line
#! pip install gekko
# only need to do it once, and put it (#) back as comment once gekko is
# installed, e.g for anaconda python, you only need to do it once to
# install gekko
#
# however, if you are using Google CoLab to run python,
# then, you need to install it every time, if so, keep uncomment if you are
# using Google CoLab
In [2]:
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
In [3]:
def apollonius(tTheta,pThetaTry):
  print("tTheta=",tTheta,"pThetaTry=",pThetaTry)
  m = GEKKO()
  nt = 501
  m.time = np.linspace(0,1,nt)
  initialx=4
  initialy=0
  pspeed=0.8
  # (x1,x2) is the position
  x1 = m.Var(value=initialx)
  x2 = m.Var(value=initialy)
  # x3 is time
  x3 = m.Var(value=0)
  # (x4,x5) is the target
  x4 = m.Var(value=0)
  x5 = m.Var(value=0)
  p = np.zeros(nt) # final time = 1 
  p[-1] = 1.0
  final = m.Param(value=p)
  tf = m.FV(value=3,lb=0.1,ub=5.0) 
  tf.STATUS = 1
  ptheta = m.FV(value=pThetaTry,lb=-np.pi,ub=np.pi, fixed_initial=False) 
  ptheta.STATUS = 1
  m.Equation(x1.dt()==pspeed*m.cos(ptheta)*tf)  
  m.Equation(x2.dt()==pspeed*m.sin(ptheta)*tf) 
  m.Equation(x3.dt()==tf)
  m.Equation(x4.dt()==m.cos(tTheta)*tf)  
  m.Equation(x5.dt()==m.sin(tTheta)*tf) 
  m.Equation(((x1-x4)**2+(x2-x5)**2)*final<=0.00001)
  m.Obj(tf)
  m.options.IMODE = 6
  m.solve(COLDSTART=2,disp=False)
  print('Final Time: ' + str(tf.value[0]))
  print('angle (in radiant): ' + str(ptheta.value[0]))
  xx1=x1
  xx2=x2
  xx4=x4
  xx5=x5
  print('xx1[-1]=',xx1[-1],'xx2[-1]=',xx2[-1])
  print('xx4[-1]=',xx4[-1],'xx5[-1]=',xx5[-1])
  return xx1,xx2,xx4,xx5
In [4]:
xx11=np.zeros(501)
xx12=np.zeros(501)
xx14=np.zeros(501)
xx15=np.zeros(501)
[xx11,xx12,xx14,xx15]=apollonius(np.pi/4,np.pi/2)
#tm = np.linspace(0,tf.value[0],nt)
tTheta= 0.7853981633974483 pThetaTry= 1.5707963267948966
Final Time: 3.693100662
angle (in radiant): 2.0595090215
xx1[-1]= 2.6129019206 xx2[-1]= 2.608623031
xx4[-1]= 2.6114165217 xx5[-1]= 2.6114165217
In [5]:
xx21=np.zeros(501)
xx22=np.zeros(501)
xx24=np.zeros(501)
xx25=np.zeros(501)
[xx21,xx22,xx24,xx25]=apollonius(np.pi/6,np.pi/2)
#tm = np.linspace(0,tf.value[0],nt)
tTheta= 0.5235987755982988 pThetaTry= 1.5707963267948966
Final Time: 2.6808999402
angle (in radiant): 2.467639918
xx1[-1]= 2.3241995686 xx2[-1]= 1.3384754713
xx4[-1]= 2.3217274532 xx5[-1]= 1.3404499701
In [6]:
xx31=np.zeros(501)
xx32=np.zeros(501)
xx34=np.zeros(501)
xx35=np.zeros(501)
[xx31,xx32,xx34,xx35]=apollonius(-np.pi/6,-np.pi/4)
#tm = np.linspace(0,tf.value[0],nt)
tTheta= -0.5235987755982988 pThetaTry= -0.7853981633974483
Final Time: 2.6808999402
angle (in radiant): -2.467639918
xx1[-1]= 2.3241995686 xx2[-1]= -1.3384754713
xx4[-1]= 2.3217274532 xx5[-1]= -1.3404499701
In [7]:
xx41=np.zeros(501)
xx42=np.zeros(501)
xx44=np.zeros(501)
xx45=np.zeros(501)
[xx41,xx42,xx44,xx45]=apollonius(-np.pi/4,-np.pi/4)
#tm = np.linspace(0,tf.value[0],nt)
tTheta= -0.7853981633974483 pThetaTry= -0.7853981633974483
Final Time: 3.693100662
angle (in radiant): -2.0595090215
xx1[-1]= 2.6129019206 xx2[-1]= -2.608623031
xx4[-1]= 2.6114165217 xx5[-1]= -2.6114165217
In [8]:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set(xlim=(-1, 6), ylim = (-4, 4))
plt.plot(xx11, xx12, 'b--')
plt.plot(xx14, xx15, 'r--')
plt.plot(xx21, xx22, 'b--')
plt.plot(xx24, xx25, 'r--')
plt.plot(xx31, xx32, 'b--')
plt.plot(xx34, xx35, 'r--')
plt.plot(xx41, xx42, 'b--')
plt.plot(xx44, xx45, 'r--')
pspeed=0.8
ep1=xx14[0]*(pspeed/(1+pspeed))+xx11[0]*(1/(1+pspeed))
ep2=xx14[0]*(-pspeed/(1-pspeed))+xx11[0]*(1/(1-pspeed))
rrr=(ep2-ep1)/2
circle1=plt.Circle(((ep1+ep2)/2,0),rrr,edgecolor='c',linestyle='--',fill=False)
ax.add_patch(circle1)
ratio=1
ax.scatter((ep1),(0),color='r',s=100)
ax.scatter((ep2),(0),color='k',s=100)
ax.scatter((xx11[0],xx11[-1]),(xx12[0],xx12[-1]),color='b',s=100)
ax.scatter((xx14[-1],xx14[0]),(xx15[-1],xx15[0]),color='b',s=100)
ax.scatter((xx21[0],xx21[-1]),(xx22[0],xx22[-1]),color='g',s=100)
ax.scatter((xx24[-1],xx24[0]),(xx25[-1],xx25[0]),color='g',s=100)
ax.scatter((xx31[0],xx31[-1]),(xx32[0],xx32[-1]),color='m',s=100)
ax.scatter((xx34[-1],xx34[0]),(xx35[-1],xx35[0]),color='m',s=100)
ax.scatter((xx41[0],xx41[-1]),(xx42[0],xx42[-1]),color='c',s=100)
ax.scatter((xx44[-1],xx44[0]),(xx45[-1],xx45[0]),color='c',s=100)
fig.set_dpi(150)
plt.show()
In [9]:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set(xlim=(-1, 21), ylim = (-5, 5))
plt.plot(xx11, xx12, 'b--')
plt.plot(xx14, xx15, 'r--')
plt.plot(xx21, xx22, 'b--')
plt.plot(xx24, xx25, 'r--')
plt.plot(xx31, xx32, 'b--')
plt.plot(xx34, xx35, 'r--')
plt.plot(xx41, xx42, 'b--')
plt.plot(xx44, xx45, 'r--')
pspeed=0.8
ep1=xx14[0]*(pspeed/(1+pspeed))+xx11[0]*(1/(1+pspeed))
ep2=xx14[0]*(-pspeed/(1-pspeed))+xx11[0]*(1/(1-pspeed))
rrr=(ep2-ep1)/2
circle1=plt.Circle(((ep1+ep2)/2,0),rrr,edgecolor='c',linestyle='--',fill=False)
ax.add_patch(circle1)
ratio=1
ax.scatter((ep1),(0),color='r',s=100)
ax.scatter((ep2),(0),color='k',s=100)
ax.scatter((xx11[0],xx11[-1]),(xx12[0],xx12[-1]),color='b',s=100)
ax.scatter((xx14[-1],xx14[0]),(xx15[-1],xx15[0]),color='b',s=100)
ax.scatter((xx21[0],xx21[-1]),(xx22[0],xx22[-1]),color='g',s=100)
ax.scatter((xx24[-1],xx24[0]),(xx25[-1],xx25[0]),color='g',s=100)
ax.scatter((xx31[0],xx31[-1]),(xx32[0],xx32[-1]),color='m',s=100)
ax.scatter((xx34[-1],xx34[0]),(xx35[-1],xx35[0]),color='m',s=100)
ax.scatter((xx41[0],xx41[-1]),(xx42[0],xx42[-1]),color='c',s=100)
ax.scatter((xx44[-1],xx44[0]),(xx45[-1],xx45[0]),color='c',s=100)
fig.set_dpi(150)
plt.show()
In [ ]: