-->

main-navbar

Showing posts with label Actions. Show all posts
Showing posts with label Actions. Show all posts

Sunday, May 24, 2015

The Flightcontroller

Flying in 3d space with Newtonian physics is tricky. With modular space craft, the center of mass can shift at any time, but even worse, if the object is not symmetrical, then forces generate hard to predict rotational accelerations. On top of this, any force applied will cause the ship to move....and keep moving, until another force slows it down. These are all things the user would have to take into account when building a ship, and set each engines output and keybinding accordingly, or else the ship would be completely uncontrollable,

The goal of the flight controller is to handle all this in background. It does this through several methods and techniques that together work to make the controls easy to use and user friendly, no matter the ship configuration (Though some designs work better then others).
The flight controller consists of two main parts.

The first part: Give it a target force and torque, and have it fire the engines accordingly.

You may have many engines, but you can only go in one direction at a time. Its follows then, that it would be useful to find how much power to give each engine, to go in a particular direction. This sounds simple, but turns out to be extraordinarily difficult to program. However, this can be modeled as a linear program, and there are linear program solvers that have already done the hard part for you. For those interested, the solver I used is lp_solve, and the linear program used is on math_exchange.

To format the problem as a linear program, you need to set each engine throttle as a variable. You also need to calculate the force and torque each individual engine would exert on the spacecraft. You then simply plug these into the solver, along with a target force and torque, and the linear program solver returns the throttles each engine needs to be set too.

This gets further complicated by one thing: When rotating, torque is not equal to angular acceleration*mass. In 3d space, if you apply a torque on something, the resulting angular acceleration depends on the distribution of that mass, that's why if your spinning on a chair, and you pull your arms in, you spin faster, its also why if you rotate something, its better if its symetrical. The distribution of mass of a 3d object relative to a pivot point, is commonly represented as something called an Inertia Tensor. An inertia tensor is a 3x3 matrix, and by doing some math operations involving it and target angular acceleration, we can get the torque required to produce the given angular acceleration.

Using the above, we can feed the flight controller a target angular acceleration, and target force, and the flight controller will fire the engines to produce it as closely as it can. The problem now is to figure out which angular acceleration and force we want to produce.

The second part: finding a target angular acceleration and force.

Before this part can be solved, we need to consider how the player expects the controls to work. In most cases, you aim with the mouse, and use the arrow keys to move. So, given a direction (from the user aiming the mouse), the ships current direction (ie: which way it is looking), we need to find a force/torque to rotate the ship to point in the desired direction. For moving around, we need to, given a target movement direction, move in that direction, by producing a force in that direction.

Finding the target force is the easiest part. Simply map each arrow key to a vector which points in the expected direction. So "w" would be mapped to a forward vector, pressing it would call the flight controller with this vector*maximum_force as the force vector. The flight controller would then accelerate in the given direction.

Finding the target angular acceleration, to rotate from one direction to another is a bit more complex. I used a PD controller to solve this part. Essentially, the pd controller takes the angle between the desired direction and the current direction, and the current angular velocity, and returns an angular acceleration to try and minimize the errors. It takes into account the maximum angular acceleration and two tuning constants as well. The constants are for tweaking how much the controller responds to the error in angular velocity and the angle error.

That's the flight controller for the most part. It sounds simple enough explaining it like this, but the flight controller has been the toughest part of this project out of the 4 years since I came up with idea. Now that its working quite well, I can work on the things that wouldn't be possible without it. Specifically: gameplay elements, AI etc.









Saturday, December 21, 2013

The Action System

Been very busy during the college semester. Getting used to college, then trying to keep up, has left little room for this project. However, finals are now over and I have nearly a month off, so time to get some more stuff done.

This past week and in my spare time over the semester I have been working on the action system. In an earlier post I described the action system as a relationship between the user, the assembly, and the actions that the assembly is capable of executing through its modules. When I went to implement this, I discovered it would not be as simple as it first appeared. 

The action system was going to be broken into three parts: the easy to use simple logic system (this would allow direct designation of keys to specific actions), the logic/node editor (this would allow for very complex programming without the user writing any code), and the code editor (just like it sounds, you have to write code to program stuff). 

The first part, the easy to use logic system, was going to be implemented as fast and easy as possible while still allowing for expansion. Then later on, when more of the game functionality was added, the second part would be implemented, which would allow the complex node/logic editing in addition to the simple keybinding. The two are unfortunately inseparable. In order to implement the first part, the second part (or at least the underlying infrastructure) must exist first. 

So this past week, and in my spare time over the semester, I have been working on the underlying infrastructure for the node editor. If you are familiar with programming, you can see how a node editor can be used to do logic. Each node in the editor will be broken into as many as three different parts: an input, an activator, and an action. The input is some sort of trigger or change, so you could use a variable change as well as a keyboard press as an input. Each input can be connected to one or more activators. As well, each activator can be connected to one or more inputs. The purpose of the activator is to handle the inputs and activate actions based on them. Each activator can also connect to one or more actions. The action is simply a link to a premade function within the code of a module. Anything passed to the action upon its activation, will also be sent to its target function. This target function can also be an input, so upon its activation it can trigger another activator. This depends on the actual code inside the action function, but it allows for some very complex behaviors.
Each input/activator/action together makes a node. The user will be able to use these nodes to create the desired behavior.


The above system has been mostly implemented so far, with the exception of passing in or handling values, saving and loading the logic, and actual nodes. It works well for simple things like a keypress. One of the reasons that actions have to activate a target (predetermined) function on the module, instead actual in game functions that are required for the game to function is this: it limits the user to within the modules actual capabilities. ie: You cannot do something with the module unless it has been programmed to be able to do that. In this way you can controll the spacecraft however you like; your only limitation is its limitations. This makes sense, you wouldn't want someone changing, their max health, or making themselves indestructible, or other hacks.


Saturday, August 24, 2013

Actions

Been really busy the past few weeks, so haven't had much to show for the time. With college classes about to start in two weeks the available time is only going to decrease. However, I did manage to create and partially implement the action system.

What this system does, is handle module actions. This will be integrated into how the AI runs, how the user controls and configures input, and will basically give a framework for handling each modules actions. For example, an engine type module would have actions for controlling the engine. The actions for such a module would be something like: Activate, Deactivate, Set Power, etc. So to get such an engine configured, you could assign say, the spacebar, to Activate the engine when pressed, and Deactivate the engine when released.

The system works by storing a list of the modules actions in the module itself. An action in this system is a custom class that has an activate function, and a constructor. The constructor assigns the target of the action, so when the action is "activated" it calls the targeted function. in addition the constructor assigns a description and a name for the action, so that the user knows exactly what the action does. All the actions are assigned at start of the runtime to their parent module, and made available to all objects that have access to the module. The assembly itself will be the main object activating these actions, and assigning inputs to activate specific actions. These inputs will be stored on the assembly itself so that individual sets of controls can be isolated. (ie: the user controls one assembly, and an ai controls another. Their actions dont activate each other because they are assigned to separate assemblies) Basically the assembly will act as the distribution hub for all of its modules actions. Eventually it will be possible to create custom actions which would set off multiple others, sort of like programming.

With this system, it would be possible to practically let the user program the ship as they would a robot. One of the cool things about this, is a user could create a control system and share it with others who just want to fly the ship, and skip the whole configuring aspect. Or even better, a user could create their own AI. These are some of the major end goals. However, for the moment a simple "this key/button activates this action" sort of thing will be created, until after some sort of release. More complex layers of possible programming will be possible later on.

There are still some fine details to work out, like accessing module variables, but for now I hope just to be able to get a ship that is completely configured by the user.