I’ve made a quad-copter drone model. Now I’m working on scripting it. I’m using AlignPosition
and AlignOrientation
to position and orient the drone. Now the problem that I’m having is moving the drone. When it moves, the leading edge dips down while the trailing edge rises a little bit. When it stop moving and hovers, the reverse happens. I can make it move with no problems, and I can make it rotate in place with no problems.
Code wise, I don’t even know where to begin on something like this. I have never coded flight control software before.
Here’s the idle routine that I have:
-- Flight Control: Idle Rotate
local function flightIdle()
local x, y, z = alignOrient.CFrame:ToOrientation()
y += math.pi / 2
alignOrient.CFrame = CFrame.Angles(0, y, 0)
end
This is called in a timed loop to rotate the drone 90° every half second or so and it does seem to work. Now it’s just the rest of it.
Here’s some pictures to illustrate what I’m talking about:
Moving Forward
In a real drone, the back pitches up so the drone moves forward.
Moving Backward
To move backwards, the front pitches up so the drone moves backwards.
1 Like
I can’t test it ATM, could you please try this and see if it works?
local clamp, cos, PI = math.clamp, math.cos, math.pi
local FULL_TILT_SPEED = 10
local drone = script.Parent
local headingAlignOrientation --Only rotates around the vertical axis of the drone, to make it point towards something
local tiltAlignOrientation --Only rotates around a different, horizontal axis of the drone (there are infinite, in a circle), to make it tilt in the direction it's moving
local function speedToTiltAngle(speed)
local speedPercent = clamp(speed / FULL_TILT_SPEED, 0, 1)
local tiltPercent = 0.5 * (1 - cos(speedPercent * PI)) --Varies smoothly from 0 to 1, in a sinusoidal way that I think is realistic
local tiltAngle = tiltPercent * PI
return tiltAngle
end
RunService.Heartbeat:Connect(function()
local primary = drone.PrimaryPart
local horizontalVelocity = primary.LinearVelocity * Vector3.new(1, 0, 1)
local speed = horizontalVelocity.Magnitude
local direction = horizontalVelocity.Unit
tiltAlignOrientation.CFrame = CFrame.fromAxisAngle(direction, speedToTiltAngle(speed))
end)
There was an error in it that I corrected. LinearVelocity
needs to be AssemblyLinearVelocity
. It kind of works, but it tilts in the wrong direction. I think it’s an orientation issue. I’ll play with it and see what I can come up with.
1 Like
Maybe add a BasePositon
A part that is in the center of the drone and only rotates along the y-axis. It should help with CFrames. And I woudl attach it to the drone by Hinge (because the assuming -z is front it should only be off by the x-axis)
And with the controls, you can just use a bit of trig to see how far to rotate it.
--Assuming 1-Dimensional controls with range of -1 to 1
local Speed=number
local Upspeed=number--Should be related to gravity, Idk how
---Tilt control bind by renderstep or something
local Control=number--Ranged from -1 to 1
local tilt=Math.atan(Control*Speed/Upspeed)
AlignOrientation.PrimaryAxis=CFrame.fromOrientation(tilt,0,0)
This is the type of approach I would take, I am not very familiar with this either.
1 Like
Hmm… AlignPosition
makes it hover and move. Although gravity is present, it’s cancelled out because of that. So I can make it rotate by the code that I posted. It’s called from a spawned while loop that runs on every heartbeat. I need to do more code work on it.
In reality, the props spin in different directions. The below image illustrates this:
As you can see, there are three weights of arrows. The really thin one represents a slowly turning prop. The medium one is a prop at normal speed. The heavy line arrows represents a prop that is rotating at high speed. As you can see, I did a bit of research on this because I was looking for source code for a quadcopter flight control system for a real drone and I was going to adapt it. But when I thought about it, that’s real hardware in a real world which does not translate to the physics simulation of Roblox.
But I did learn quite a bit about it.
I made a video to show you what it’s doing. You can view it here:
When it’s idle, it keeps tilting. Not sure what that’s about.
1 Like
Try checking every time if the direction is different than (0, 0, 0) (or check if magnitude is > 0) and only set the CFrame to that if it is.
Yeah. I’ve already solved that problem. The routine does not run if the drone position is within one stud of the target position. So that part is solved. The issue though is that it seems that the tilt angle is 90° off. The tilt code does work, but it tilts in the wrong direction and I’m not sure how to correct that. It needs to rotate 90° clockwise on the Y axis. I’ve tried rotating the attachment, but that just caused way more problems. I have tried other things, but it seems that the directional vector itself is off by the 90°. The attachment orientation is <0, 0, -90>. It had to be that because the part that it’s attached to is rotated -90° because it’s a cylinder and I needed it to be vertical so I wouldn’t have to worry about it spinning on the Y axis.
At this point, I’m willing to entertain suggestions.