Monday, November 16, 2009

Rocket steering methods

My primary lunar lander prototype (not the one shown below) does not have true rigid body dynamics yet. The rocket's heading is driven directly by mouse movement. This makes it really easy to steer the nozzle but I have been unsure about how to alter it once the rocket can actually collide with the terrain in a way that applies torque. If you are able to directly rotate the rocket that could introduce unwanted interpenetration or arbitrary launch velocities.

I have a separate prototype at the moment where I am testing out the rigid body dynamics. The rocket, at the moment, has a single steerable nozzle. It will probably be necessary to add steering jets to make it easier to fly. Right now when you apply a torque to the rocket you are also applying a hefty linear acceleration as well.



The first control method is very simple to implement. The mouse rotates the rocket nozzle; the mouse button fires it. This is demonstrated in the first clip above.

In the second control method (shown in the latter half of the movie) the mouse sets a desired thrust direction. While the rocket is firing, an autopilot steers the rocket nozzle to align thrust in the specified direction. At the moment it's snapping the nozzle to one of three positions: extreme left, extreme right, and center. This is not terribly realistic; I'm still figuring out how to make it more natural.

4 comments:

Scott said...

I always love reading your blog posts. Your recent post about raycasting collisions against your procedurally generated planets get me to finally finish raycast collisions in Chipmunk. :)

I had made a game prototype once of 2D freeflight ship controls using 6 thrusters. 2 pairs of rotation thrusters, a large main thruster and a retro thruster. It was rather fun to implement a bunch of fly by wire controls for it.

It had braking, it would fire the appropriate set of thrusters to slow you down without adding rotation or changing the heading. It had what I called velocity compensation where it would allow you to rotate the ship and it would fire the appropriate thrusters needed to point your velocity forward again at 5 km/s (or any other speed or relative direction). When you locked onto an object in the game, your velocity would be calculated relative to that object. This made it easy to approach and brake next to an asteroid for instance.

I also implemented an auto pilot system that would thrusters at their full strength to match the velocity and position of another object in minimal time. I never did figure out how to get it to rotate the ship to be able to effectively use the main engine though.

James McNeill said...

Thanks!

I had a question for you, actually, if you see this. The demo above uses a C++ conversion of your Chipmunk library. I recently integrated in the latest Chipmunk release and noticed that you'd switched the integration order. It used to integrate velocity, constrain it, then integrate position. (Box2D follows this order as well.) Now it appears to integrate position, then velocity. I was wondering what your reason was for the switch?

Jotaf said...

This is awesome, keep it up :)

I have a question for you, you mentioned a different method for smooth camera zoom/location. Did you manage to implement that, and is it an improvement? This is a fairly annoying issue in many games, so it's always nice to hear about other approaches.

James McNeill said...

Camera control is always a problem in games. You want to try and predict what the player will need to see, while also keeping a stable frame of reference for their actions.

What I've got right now is suited for landing but not much else. There are a variety of things. It frames the action in a circle and then fits that circle onto the screen. I found that framing in a circle gave smoother results as the view rotated; framing in a rectangle would cause things to zoom in and out a bit as the constraints migrated around the edges.

The view is oriented with vertical running through the planet center and the rocket center, with the rocket above the planet. This works well until I want a hollow-core planet, or a binary system like Earth/Moon. Once I've got that, who knows.

At low rocket energies, the view frames the future ballistic trajectory. It integrates forward in time until it collides with the terrain and fits the circle to that. This works great for landings. Takeoffs, not so much.

At higher rocket energies, it transitions to frame the ellipse of the orbit. This is equivalent to the ballistic trajectory in some ways except that it is cheaper to compute for the long time periods involved in complete orbits. This works OK until the orbit changes to an open trajectory (parabolic/hyperbolic), at which point I don't have any great ideas about what to frame.

There are other complications on the horizon. I want to add orbital rendezvous. The current algorithm is zoomed in close to the rocket when it's parked on the surface, which doesn't allow you to see the mother ship in orbit. I think I may need to add some manual input to the camera to hint at what you'd like to see. Perhaps a target selection system, with the camera deciding what your relationship to the target is and framing things accordingly.

At the moment my focus is on getting the vehicle movement right, though, as the camera is good enough to get around.