It looks like you're new here. If you want to get involved, click one of these buttons!
Hey all,
I am trying to use polar coordinates to make a guided missile, the concept is that the code works out the vector between the rocket and its target and works out the angle difference between this and the rockets velocity vector and then tries to slowly correct for this angle.
The code seems to work best to my knowledge, but then suddenly all my vector values become NaN and I don't know why, I have tried to check for reasons why such as a divide by 0 but no luck.
If anyone could share some light on this that would be greatly appreciated, Thanks!
I've posted the code for the missile logic below and have commented it all, if anyone wants to read it.
Ps I have also attached some pictures below to show the error
Rocket = class()
function Rocket:init(x,y)
-- you can accept and set parameters here
-- initial position
self.pos = vec2(x,y)
-- inital velocity
self.vel = vec2(0,1)
-- vector that links rocket position to its target
self.aim = target.pos - self.pos
self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5)
-- the rockets angle, a vector pointing directly up has an angle of 0
self.angle = 0
end
function Rocket:draw()
pushMatrix()
pushStyle()
ellipse(self.pos.x + 5,self.pos.y + 15,10)
-- the translation is used so that the rotate function rotates the rectangle from the centre
translate(self.pos.x + w/2 ,self.pos.y + h/2)
rotate(-self.angle)
fill(255, 0, 229, 255)
stroke(255, 255, 255, 255)
rect(-w/2,-h/2,w,h)
popStyle()
popMatrix()
end
function Rocket:update(target)
-- update position
self.pos = self.pos + self.vel
print(self.pos)
print(self.vel)
print(self.aim)
-- update vector connecting ship and target position
self.aim = target.pos - self.pos
-- magnitude of the aim vector
self.aimMag = math.pow(((self.aim.x)*(self.aim.x)+ (self.aim.y)*(self.aim.y)),0.5)
-- angle between the ships velocity and vector between the ship to its target
self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag)
self.out = math.deg(self.angleRelToTarget)
-- print(self.angleRelToTarget)
text(self.out , self.pos.x + 50, self.pos.y + 50)
pushStyle()
strokeWidth(2)
stroke(0, 0, 0, 255)
-- this line shows the vector connecting the rocket to its target
line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y)
popStyle()
-- this changes the ships velocity angle
self.angle = self.angle + self.angleRelToTarget/2
-- print(math.deg(self.angle))
-- updates velocity with this new angle
self.vel = vec2(math.sin(self.angle),math.cos(self.angle))*self.speed
end
Comments
@rydergaz Having an example with workable code would help a lot. Include minimum code for the setup, draw, and touched functions so your code can be run. That way anyone who wants to help doesn't have to figure out the other functions just to explain your problem.
Sorry
Here we go
@dave1707 here's the whole programme
You have a problem with math.acos() in rocket:update in the line
the result of the calculation
is greater than 1.0 which results in a nan when doing math.acos.
One way to fix this is to do something like
The result shouldn't be over 1.0 since I'm taking the dot product right?
I've sorted the Nan error now, the issue was that when relative angle between the missiles velocity vector and the vector connecting it to its target become nearly 180 degrees (i.e the rocket is flying away from target.) the code gets stuck at 180 and the rocket doesn't turn
The new code is
@rydergaz Here's an image from the guided missile program that I completed yesterday. The missile starts in the lower left corner and goes at a 45 degree angle to the right leaving a white trail. I'm using backingmode(RETAINED) to keep all the plotted point on the screen as the missile moves. When I tap the screen, a target point is created in red and a blue missile point is created where the missile was when the target point was created. After the missile passes thru a red target point, I tap the screen again creating another red target point and a blue missile position point. I did it several times to show the path of the missile as it seeked out each target point as I created them.
PS. I ran this in portrait mode.
Ah nice yours looks like it's working really smoothly, this is the latest update on mine it's almost there but for some reason the rocket chooses to turn away from the target sometimes. This screenshot shows you my rocket path, the orange dot is where I placed the target. You can see on the last target the rocket goes in the wrong direction.
Here is my rocket path
How are you guiding your rocket ?
@dave1707 this is the code for my latest rocket programme
Update: managed to get it fully functioning runs like a dream now.
@dave1707 I'm still interested to see how you went about designing your homing missile. I took the bearings from the velocity vector and the vector connecting the rocket position to the target position and changed the velocity vectors angle till it's at the same angle as the position vector. If that makes sense
@rydergaz Here's my version. I removed the blue dot since it isn't necessary. I left the backingMode in here. You can comment it out and uncomment background. The value of speed can be changed.
Thanks! Your programme works so well and it's very fluid. The move() function is so smart, would it be okay if I used this same concept in a bigger project of mine?
@rydergaz Anything that's posted in the forum is free to use by anyone unless it says that it's not. So go ahead and use it wherever you want.
@rydergaz I'm not sure how you're going to use the code, but here's another version. I removed things not used. Try holding the iPad in portrait and landscape position. This is just a missile targeting another missile.
~~~
--# Main
-- Rocket V3
displayMode(FULLSCREEN)
function setup()
mx,my=0,0
x,y=WIDTH/2,0
vx,vy=0,1
speed=4
gas = {}
--backingMode(RETAINED)
end
function draw()
aim = vec2(vx,vy)
angle = angleMachine(aim)
background(0)
fumes(x,y)
fill(255)
pushMatrix()
translate(x,y)
rotate(-angle)
rect(-5,-15,10,30)
popMatrix()
if px~=nil then
fill(255,0,0)
ellipse(px,py,10)
dx=px-x
dy=py-y
if not hit then
move()
if math.abs(dx) 0 then
angle = 360 + angle
end
return angle
end
function fumes(xx,yy)
randomNum = math.random(1,10)
if randomNum > 5 then
table.insert(gas,Smoke(xx,yy))
end
for a,b in pairs(gas) do
b:draw()
if b.status == "delete" then
table.remove(gas)
end
end
end
--# Smoke
Smoke = class()
function Smoke:init(xx,yy)
-- you can accept and set parameters here
self.startPos = vec2(xx,yy)
self.radius = math.random(1,30)
self.alpha = 255
self.angle = angle
self.timer = 0
self.status = "alive"
pushMatrix()
translate(x,y)
rotate(-angle)
fill(255,0,228,255)
ellipse(0,-15,self.radius)
popMatrix()
end
function Smoke:draw()
self.r = math.random(1,255)
self.g = math.random(1,255)
self.b = math.random(1,255)
pushMatrix()
translate(self.startPos.x,self.startPos.y)
rotate(-self.angle)
self.alpha = self.alpha*0.97
fill(self.r, self.g,self.b, self.alpha)
ellipse(0,-15,self.radius)
popMatrix()
self.timer = self.timer + 1
if self.timer > 800 then
self.status = "delete"
end
end
~~~