It looks like you're new here. If you want to get involved, click one of these buttons!
I've hit a roadblock with my drone flight-simulator project and asking for a pointer or two to help get me back on track.
Description:
The drone is always located in the center of the screen. The point of view (POV) is always directly overhead. As you fly the drone the ground beneath translates and rotates giving the sensation of motion. All motion if controlled by two joysticks. Slight finger movement provides plenty of motion and motion stops when fingers are released.
At startup, fly the drone forward, backward, left and right by moving the RIGHT joystick up, down, left and right respectively. The ground appears to move opposite to the stick because in reality you are moving the ground and not the drone. The goal is that to fly the drone forward you push the RIGHT stick forward.
Next, yaw (rotate) the drone left and right by moving the LEFT stick left or right. Notice the ground rotating directly underneath the drone. Left stick provides altitude using scale so it's a bit primitive.
The Problem:
If you try to translate the drone with the RIGHT stick AFTER yawing the drone with the LEFT stick the control is messed up by what appears to be an amount equal to the Yaw amount. As an example: If Yaw is -45 degrees the drone should be facing NorthWest. If you wish to move to the NorthWest you should only have to push the stick forward. But instead if I push the stick forward the drone moves North rather than NorthWest.
Creating an image of the ground then translating and rotating it ahead of the sprite call works great as long as the drone was headed North. Adding yaw into the mix throws everything off. The drone needs to fly in the direction the RIGHT stick is pushed.
I've struggled with this problem for about two weeks and would greatly appreciate any leads to solving this problem.
I'm running this on a 3rd gen (iOs = 9.3.5) iPad that's getting close to ten years old. Too old for any Codea updates and unable to zip files.
I am looking forward to any advice offered.
Thank you very much.
Scotty
-- DroneSim V5
supportedOrientations(ANY)
displayMode(FULLSCREEN)
function setup()
X,Y = WIDTH/2, HEIGHT/2
LR,FB = 0,0
Alt,Yaw = 1,0
-- modes (stick sensitivity):
cine = .10
normal = .25
sport = .50
mode = normal
-- Set up common colors
commonColors()
-- JoyStick class setup:
JSYA = JoyStick(175, 200, green, "Yaw: < Left/Right >",
"Altitude: ^ Up/Down v")
JSFBLR = JoyStick(WIDTH-175,200,red, "Translate: < Left/Right >",
"Translate: ^ Forward/Backward v")
-- For ground definition
rows,cols,sizeGeo = 20,20,100
imgSize = vec2(cols*sizeGeo, rows*sizeGeo)
-- Create images using setContext()
createImageGround()
createImageDrone()
end
function draw()
background(40, 40, 50)
-- trig numbers (req'd?)
sinLR = math.sin(math.rad(Yaw)) -- x
cosFB = math.cos(math.rad(Yaw)) -- y
-- Left joystick:
Yaw=Yaw+JSYA.dX*mode/4
Alt=Alt-JSYA.dY*mode/1000
if Alt > 1 then Alt = 1 end
if Alt < .4 then Alt = .4 end
-- Right joystick:
LR=LR+JSFBLR.dX*mode -- left/right
FB=FB+JSFBLR.dY*mode -- foreward/backward
-- Manage ground image, landing zone and return-to-home line.
pushMatrix()
translate(X,Y)
rotate(Yaw)
pushMatrix()
scale(Alt) -- The illusion of altitude
sprite(myImageGround,-LR,-FB)
landingZone(-LR,-FB)
returnToHomeLine(-LR,-FB)
popMatrix()
popMatrix()
-- Drone is stationary while the ground moves underneath.
sprite(myImageDrone,X,Y) -- Drone w/o lights
drawDroneLights(X,Y) -- Lights w/o body
pushStyle()
fill(white)
fontSize(14)
text(string.format("%.f°",Yaw), X,Y+60)
popStyle()
-- Joysticks
JSYA:draw()
JSFBLR:draw()
-- Compass letters rotate around drone.
drawCompass()
end
function touched(t)
JSYA:touched(t)
JSFBLR:touched(t)
end
JoyStick = class()
--[[
JoyStick details:
-----------------
Left Stick:
U +altitude
D -altitude
L ccw yaw
R cw yaw
Right Stick:
U Foreward movement
D Backward movement
L Left movement
R Right movement
--]]
function JoyStick:init(x,y,clr,txt1,txt2)
self.x = x
self.y = y
self.clr = clr -- color
self.txt1 = txt1
self.txt2 = txt2
self.dia = 50
self.max = 25
self.dX = 0
self.dY = 0
self.id = {} -- touch id table
end
function JoyStick:draw()
pushStyle()
-- Escutcheon:
strokeWidth(4)
stroke(self.clr)
fill(black)
ellipse(self.x,self.y,self.dia)
-- Stick design:
fill(self.clr)
stroke(self.clr)
strokeWidth(10)
line(self.x, self.y, self.x+self.dX*.5, self.y+self.dY*.5)
fill(black)
strokeWidth(2)
ellipse(self.x+self.dX*.5, self.y+self.dY*.5, self.dia*.3)
ellipse(self.x+self.dX*.6, self.y+self.dY*.6, self.dia*.3)
-- Reference data and etc. that's not really important to the project:
fill(white)
text(string.format("(%.f, %.f)",self.dX,self.dY), self.x,self.y+self.dia)
text(self.txt1, self.x,self.y-self.dia)
text(self.txt2, self.x,self.y-self.dia*1.5)
popStyle()
end
function JoyStick:touched(t)
if vec2(t.x,t.y):dist(vec2(self.x,self.y)) <= self.dia*2 then
if t.state==BEGAN or t.state==MOVING then
table.insert(self.id,t.id)
-- Update deltas
self.dX=self.dX+t.deltaX
self.dY=self.dY+t.deltaY
-- Limit deltas to maximums
if self.dX> self.max then self.dX =self.max end
if self.dY> self.max then self.dY =self.max end
if self.dX<-self.max then self.dX=-self.max end
if self.dY<-self.max then self.dY=-self.max end
end
elseif vec2(t.x,t.y):dist(vec2(self.x,self.y)) > self.dia*2 or t.state==MOVING then
for z=#self.id,1,-1 do
if self.id[z]==t.id then
table.remove(self.id,z)
end
end
end
if t.state==ENDED then
-- Clear table
for z=#self.id,1,-1 do
if self.id[z]==t.id then
table.remove(self.id,z)
end
end
-- Kill motion of released joystick
if #self.id==0 then
self.dX=0
self.dY=0
end
end
end
Comments
@Scotty Looks interesting. Had no trouble copying and pasting the code. I see what you’re talking about with the joysticks. I’ll play with the code and see where the problem is.
@Scotty Ignore what I said previously. I deleted those posts. I think there’s an easier way, still working on it.
Will post an update shortly when I've had more time to play.
@Scotty I created a small program to show what I think you want to happen. Slide your finger up/down/right/left on the right side of the screen to move the ground. Slide your finger right or left on the left side of the screen to rotate the ground. Is that what you want to happen. If so, this might give you an idea of what you might need to look at. If not let me know. I’m looking thru your code while I’m watching football.
@Scotty I think this might work. Replace the draw function with this code. The returnToHome isn’t working right, but if this is what you’re after, I’ll let you fix the returnToHome.
@dave1707 thanks for the sample program. I'll play with it while watching the Vikings. Another dismal season for the Vikes.
@Bri_G As stated in my description the drone is always centered on the screen while the ground beneath translates and rotates using the two joysticks. All motion seems fine as long as you are facing North.
@Scotty Did you see the draw function that I posted after my sample program.
@scotty - oops my bad, it's the compass settings that rotate around the drone. The drone always stays vertical.
I take it you're from Minnesota who are playing the packers today. Just think yourself lucky - my team is Man U and they're on a real downer this year.
@Scotty In my draw function above, put the 3 lines below above the comment
I just have a white line from Home to the Drone. You can change it to add whatever you have in the function returnToHomeLine.
I think that should fix the problem.
@Scotty Heres what I came up with for the returnToHomeLine.
@dave1707 Sorry to say but these changes seem to get the project further from my goal. I place the blame all on my explanation of the problem.
Picture the Home base fixed to the ground. It moves along with the ground. When the drone translates and rotates the ground and Home base translates and rotates but in the opposite direction. But the important thing to remember is all rotation happens directly under the drone. If you are looking down from the drone and start rotating, the spot underneath is your pivot point and not some point off in the distance.
The one thing that was really out of whack was translating after some yaw was added. Your changes to draw() fixed the translation part -- translating in the direction the stick is pushed. But it messed up the rotation under the drone part. It's now rotating around the Home base.
I'll be up early hammering away at it.
@Bri_G no worries. Yes, I'm in Minnesota. The Vikings un-characteristically snatched victory from the yaws of defeat for a change.
Good night, guys.
@Scotty That makes more sense. I’ll start over and see what I can do.
These 2 statements are no longer supported.
Remove the supportedOrientations and replace the other one with viewer.mode=FULLSCREEN
@dave1707 describing the problem and project goals always seem to be the challenging part of this process. I put a great deal of effort into the description but still I fall short of the mark sometimes.
I've noodled around with the sample project you posted and have reposted it with some mods. Righthand translation works very well -- even with some lefthand rotation added. The main problem that remains if that rotation is not happening under the drone (UFO in this example).
My ultimate goal is to control motion using two joysticks.
As for the "viewer.mode" comment, I'll try and remember that when posting. Due to the age of iPad I'm running on my version of Codea is long out of date.
Thanks again for the assistance.
@Scotty @dave1707 - had a play with @dave1707 code and slimmed down @Scotty code by building sprites. Also added a compass and used a large graphic to add a realistic look to the app. Not intended as replacement just a few ideas to consider.
May not download due to size of graphic, if so will remove graphic and you can add your own.
Edit: removed large graphic and added one of blocks from assets in Codea. Have a few other ideas to add - will post later.
@Bri_G I appreciate the efforts you have put into this , however the age of my iPad prevents me from accessing zip files. I have a gen 3 that's close to 10 years old.
Thanks again.
@Scotty - ooops, my bad. Too busy trying to get some code to work in my window of opportunity. Here is the code and attached images:
Hope that’s OK.
@Bri_G thanks for the code.
I see what you were referring to for the compass. Very nice.
Pretty slick use of the drone sprites in myTimer(). I'm always learning something new. I'm curious to know how you created the images without the usual calls to setContext() from inside the project.
I've made some changes to your code, some minor due to, perhaps, screen size and some notated with uppercase "SPG". These "SPG" changes allow the ground to always rotate directly underneath the drone. That is what is desired.
That leaves one remaining problem: If you retate the drone in a direction other than North and attempt to go in that new direction the drone appears to head toward North. You can force it to go in the proper direction but you have to slide your right finger in a direction other than the +Y direction. It is off by the amount of angle drone is rotated.
Looking forward to when your "window of opportunity" is open again.
Thanks again.
@Scotty I’m still looking at your problem when I have time. I can make it go north, south, east, west no matter what the ground rotation angle is, but I haven’t figured out the calculations for the joystick positions in between the NSEW.
@Scotty - in short I used your code, listing attached - change the names to avoid clash with other project. The compass I drew myself, needs a little adjustment.
@Scotty Here’s my original example that might be closer to what you’re after. The drone can move forward or backward (up or down), but not side to side yet. You can rotate the ground under the drone and the drone will still go forward or backward. To move the drone, move your finger up or down on the top half of the screen. To rotate the ground, move your finger side to side on the bottom half of the screen. The drone will continue to move if you lift your finger. To stop the drone, double tap on the top half of the screen.
PS. I think I know how to move the drone side to side too. I’ll work on that next.
@Scotty Here’s the latest example for the drone movement. You can now move in any direction and rotate the ground under the drone. Some changes for this example. Move up/down/left/right on right side of screen. Rotate ground by moving up/down on left side of screen. Drone continues to move when your finger is lifted. Double tap to stop drone.
All the calculations are done in calcUDLR, so you can move that to your code and work it with your joysticks.
@dave1707 , @Bri_G
This is indeed getting close to the mark.
I've mashed Dave's example, which includes calcUDLR(), with Bri's. I've put in my touched() code so rotate and translate are controlled by left and right fingers respectively. When fingers are released motion stops.
I made some minor tweeks noted by lowercase "spg" that dose not change the overall by much. Has to do more with trading screen numbers for WIDTH or HEIGHT. I changed some sprite calls due to my ancient iPad. That sort of thing.
A more CONSEQUENTIAL change is noted by uppercase "SPG". This has all to do with moving the ground is under the driver.
The one sticky thing still remaining is diagonal motion seems to be off by about 90°.
I hope my explanation makes sense.
Thanks again for all the help and have a HAPPY THANKSGIVING.
@Scotty To fix the movement being off, make this change in your touched function.
Make it a + instead of a - .
@dave1707, @Bri_G and if you change
to
in draw() I believe it will then work perfectly.
I'll see if I can apply these concepts to my original drone project and see what happens.
Thank you very much for all the help.
And change
to an addition operation in touched()
That should do it.