For the love of god, yaw thrusters please!

An area for discussing new ideas and additions to Oolite.

Moderators: another_commander, winston

drumz
Competent
Competent
Posts: 36
Joined: Thu Jan 18, 2007 6:18 am

Post by drumz »

Updated code for analog joystick yaw control.

I switched the yaw over to using a double, instead of NSPoint.

I also didn't include the code that makes default yaw action half as large as pitch action.

Also, I fixed what I'm pretty sure was a bug in the code. abs(virtualStick.x) (and y) were changed to fabs(virtualStick.x) (and y).

Code: Select all

~/pkgs/oolite/svn/trunk$ svn diff
Index: src/SDL/JoystickHandler.h
===================================================================
--- src/SDL/JoystickHandler.h   (revision 1510)
+++ src/SDL/JoystickHandler.h   (working copy)
@@ -40,6 +40,7 @@
 enum {
   AXIS_ROLL,
   AXIS_PITCH,
+  AXIS_YAW,
   AXIS_PRECISION,
   AXIS_THRUST,
   AXIS_VIEW,
Index: src/SDL/JoystickHandler.m
===================================================================
--- src/SDL/JoystickHandler.m   (revision 1510)
+++ src/SDL/JoystickHandler.m   (working copy)
@@ -386,6 +386,7 @@
          break;
       case AXIS_ROLL:
       case AXIS_PITCH:
+      case AXIS_YAW:
          if(precisionMode)
          {
             axstate[function]=axisvalue / STICK_PRECISIONDIV;
@@ -444,11 +445,13 @@
          {
             axstate[AXIS_PITCH] /= STICK_PRECISIONFAC;
             axstate[AXIS_ROLL] /= STICK_PRECISIONFAC;
+            axstate[AXIS_YAW] /= STICK_PRECISIONFAC;
          }
          else
          {
             axstate[AXIS_PITCH] *= STICK_PRECISIONFAC;
             axstate[AXIS_ROLL] *= STICK_PRECISIONFAC;
+            axstate[AXIS_YAW] *= STICK_PRECISIONFAC;
          }
       }
    }
Index: src/Cocoa/JoystickHandler.h
===================================================================
--- src/Cocoa/JoystickHandler.h (revision 1510)
+++ src/Cocoa/JoystickHandler.h (working copy)
@@ -60,6 +60,7 @@
 enum {
   AXIS_ROLL,
   AXIS_PITCH,
+  AXIS_YAW,
   AXIS_PRECISION,
   AXIS_THRUST,
   AXIS_VIEW,
Index: src/Core/Entities/PlayerEntityControls.m
===================================================================
--- src/Core/Entities/PlayerEntityControls.m    (revision 1510)
+++ src/Core/Entities/PlayerEntityControls.m    (working copy)
@@ -431,6 +431,7 @@
                                         out the joystick if the player runs to the keyboard)
                                         is reset */
                                        keyboardRollPitchOverride = NO;
+                                       keyboardYawOverride = NO;
                                }
                                else
                                {
@@ -2141,6 +2142,7 @@
 {
        MyOpenGLView    *gameView = [UNIVERSE gameView];
        NSPoint                 virtualStick = NSZeroPoint;
+       double                  reqYaw = 0.0;
 #define                        kDeadZone 0.02

        // TODO: Rework who owns the stick.
@@ -2177,11 +2179,22 @@
                        // cancel keyboard override, stick has been waggled
                        keyboardRollPitchOverride=NO;
                }
+               // handle yaw separately from pitch/roll
+               reqYaw = [stickHandler getAxisState: AXIS_YAW];
+               if(reqYaw == STICK_AXISUNASSIGNED)
+               {
+                       reqYaw=0;
+               }
+               else if(reqYaw != 0)
+               {
+                       // cancel keyboard override, stick has been waggled
+                       keyboardYawOverride=NO;
+               }
        }

        double roll_dampner = ROLL_DAMPING_FACTOR * delta_t;
        double pitch_dampner = PITCH_DAMPING_FACTOR * delta_t;
-       double yaw_dampner = PITCH_DAMPING_FACTOR * delta_t;
+       double yaw_dampner = YAW_DAMPING_FACTOR * delta_t;

        rolling = NO;
        if (!mouse_control_on )
@@ -2216,7 +2229,7 @@
                        if (flightRoll < stick_roll)
                                flightRoll = stick_roll;
                }
-               rolling = (abs(virtualStick.x) > kDeadZone);
+               rolling = (fabs(virtualStick.x) > kDeadZone);
        }
        if (!rolling)
        {
@@ -2265,7 +2278,7 @@
                        if (flightPitch < stick_pitch)
                                flightPitch = stick_pitch;
                }
-               pitching = (abs(virtualStick.x) > kDeadZone);
+               pitching = (fabs(virtualStick.y) > kDeadZone);
        }
        if (!pitching)
        {
@@ -2286,16 +2299,37 @@
                yawing = NO;
                if ([gameView isDown:key_yaw_left])
                {
+                       keyboardYawOverride=YES;
                        if (flightYaw < 0.0)  flightYaw = 0.0;
                        [self increase_flight_yaw:delta_t*yaw_delta];
                        yawing = YES;
                }
                else if ([gameView isDown:key_yaw_right])
                {
+                       keyboardYawOverride=YES;
                        if (flightYaw > 0.0)  flightYaw = 0.0;
                        [self decrease_flight_yaw:delta_t*yaw_delta];
                        yawing = YES;
                }
+               if(numSticks && !keyboardRollPitchOverride && !keyboardYawOverride)
+               {
+                       // I think yaw is handled backwards in the code,
+                       // which is why the negative sign is here.
+                       double stick_yaw = max_flight_yaw * (-reqYaw);
+                       if (flightYaw < stick_yaw)
+                       {
+                               [self increase_flight_yaw:delta_t*yaw_delta];
+                               if (flightYaw > stick_yaw)
+                                       flightYaw = stick_yaw;
+                       }
+                       if (flightYaw > stick_yaw)
+                       {
+                               [self decrease_flight_yaw:delta_t*yaw_delta];
+                               if (flightYaw < stick_yaw)
+                                       flightYaw = stick_yaw;
+                       }
+                       yawing = (fabs(reqYaw) > kDeadZone);
+               }
                if (!yawing)
                {
                        if (flightYaw > 0.0)
Index: src/Core/Entities/PlayerEntity.h
===================================================================
--- src/Core/Entities/PlayerEntity.h    (revision 1510)
+++ src/Core/Entities/PlayerEntity.h    (working copy)
@@ -125,6 +125,7 @@

 #define ROLL_DAMPING_FACTOR                            1.0
 #define PITCH_DAMPING_FACTOR                   1.0
+#define YAW_DAMPING_FACTOR                     1.0

 #define PLAYER_MAX_WEAPON_TEMP                 256.0
 #define PLAYER_MAX_FUEL                                        70
@@ -448,6 +449,7 @@
                                                        isSpeechOn: 1,

                                                        keyboardRollPitchOverride: 1,
+                                                       keyboardYawOverride: 1,
 waitingForStickCallback: 1;

        // Note: joystick stuff does nothing under OS X.
Index: src/Core/Entities/PlayerEntity.m
===================================================================
--- src/Core/Entities/PlayerEntity.m    (revision 1510)
+++ src/Core/Entities/PlayerEntity.m    (working copy)
@@ -3452,6 +3452,7 @@

        flightRoll = 0.0;
        flightPitch = 0.0;
+       flightYaw = 0.0;
        flightSpeed = 0.0;

        hyperspeed_engaged = NO;
@@ -6377,6 +6378,7 @@
        ADD_FLAG_IF_SET(mouse_control_on);
        ADD_FLAG_IF_SET(isSpeechOn);
        ADD_FLAG_IF_SET(keyboardRollPitchOverride);
+       ADD_FLAG_IF_SET(keyboardYawOverride);
        ADD_FLAG_IF_SET(waitingForStickCallback);
        flagsString = [flags count] ? [flags componentsJoinedByString:@", "] : @"none";
        OOLog(@"dumpState.playerEntity", @"Flags: %@", flagsString);
Index: src/Core/Entities/PlayerEntityStickMapper.m
===================================================================
--- src/Core/Entities/PlayerEntityStickMapper.m (revision 1510)
+++ src/Core/Entities/PlayerEntityStickMapper.m (working copy)
@@ -289,6 +289,11 @@
                       axisfn: AXIS_PITCH
                        butfn: STICK_NOFUNCTION]];
    [funcList addObject:
+      [self makeStickGuiDict: @"Yaw"
+                   allowable: HW_AXIS
+                      axisfn: AXIS_YAW
+                       butfn: STICK_NOFUNCTION]];
+   [funcList addObject:
       [self makeStickGuiDict: @"Increase thrust"
                    allowable: HW_AXIS|HW_BUTTON
                       axisfn: AXIS_THRUST
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6552
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander »

After having been confirmed as working by at least one Windows user, the analog joystick yaw control code by drumz is now in the trunk. Anyone with trunk access willing to test it, please have a go at it and let us know if it plays well enough for you.
drumz
Competent
Competent
Posts: 36
Joined: Thu Jan 18, 2007 6:18 am

Post by drumz »

I found one other issue related to yaw control (this time not joystick specific). Currently, when the player switches to an "info" screen (F5-F8) while flying, the pitch and roll slowly decrease to 0. Yaw doesn't. This small patch makes yaw decrease to 0, like pitch and roll. This behavior can be tested with keyboard and/or joystick.

(This goes at the very end of the pollGuiArrowKeyControls function.)

Code: Select all

Index: src/Core/Entities/PlayerEntityControls.m
===================================================================
--- src/Core/Entities/PlayerEntityControls.m    (revision 1514)
+++ src/Core/Entities/PlayerEntityControls.m    (working copy)
@@ -1778,6 +1778,16 @@
                if (flightPitch < -delta_t)     [self increase_flight_pitch:delta_t];
                else    flightPitch = 0.0;
        }
+       if (flightYaw > 0.0)
+       {
+               if (flightYaw > delta_t)        [self decrease_flight_yaw:delta_t];
+               else    flightYaw = 0.0;
+       }
+       if (flightYaw < 0.0)
+       {
+               if (flightYaw < -delta_t)       [self increase_flight_yaw:delta_t];
+               else    flightYaw = 0.0;
+       }
 }

Edit: removed smiley.
User avatar
Commander Mysenses
Deadly
Deadly
Posts: 214
Joined: Sat Mar 08, 2008 9:30 am
Location: Devon, a backward little planet scourged by evil weather

Post by Commander Mysenses »

Was ondering if joystick response could be modified? ATM I find that fine adjustments are a tad jumpy, it is helped somewhat by use of the sensitivity toggle, but it isn't the ideal solution. I was thinking a kind of logarithmic response scale, for roll,pitch and yaw would be nice. So that the initial deflections of the stick produce small movements, and further deflections gradually make increasingly large movements, up to the ships maximum roll/pitch rate at full deflection.

Does that make sense?
Is it possible?
drumz
Competent
Competent
Posts: 36
Joined: Thu Jan 18, 2007 6:18 am

Post by drumz »

Yeah, it makes sense. Basically you want the option of having different responses besides just linear. I don't think logarithmic is want you want, though.

I've a made a few plots of the cubic function
y = (1-c)*x^3 + c*x
where c varies between 0 (slope at the origin is 0 - maximum non-linearity) and 1 (purely linear).

blue: c=0
green: c=1/3
red: c=2/3
cyan: c=1
Image

The benefits of using a cubic function is there's one user-tunable variable to change the amount of linearity, plus being continuous and differentiable, and all that good stuff.

Currently I'm adding null zone, maximum range, and hysteresis, so I can add this into the mix without too much trouble.
User avatar
Commander Mysenses
Deadly
Deadly
Posts: 214
Joined: Sat Mar 08, 2008 9:30 am
Location: Devon, a backward little planet scourged by evil weather

Post by Commander Mysenses »

Give that man a Huzzah!

That's grrrrreat!
(as Tony might say)
User avatar
Captain Hesperus
Grand High Clock-Tower Poobah
Grand High Clock-Tower Poobah
Posts: 2312
Joined: Tue Sep 19, 2006 1:10 pm
Location: Anywhere I can sell Trumbles.....

Post by Captain Hesperus »

Commander Mysenses wrote:
Give that man a Huzzah!

That's grrrrreat!
(as Tony might say)
Huzzah!

What's he done? :?

Captain Hesperus
The truth, revealed!!
Image
User avatar
Cmdr. Maegil
Sword-toting nut-job
Sword-toting nut-job
Posts: 1294
Joined: Tue Feb 27, 2007 10:28 pm
Location: On the mend in Western Africa

Post by Cmdr. Maegil »

He perfected a hyperdrive cruise control algorithm that also mixes drinks!
You know those who, having been mugged and stabbed, fired, dog run over, house burned down, wife eloped with best friend, daughters becoming prostitutes and their countries invaded - still say that "all is well"?
I'm obviously not one of them.
User avatar
Commander Mysenses
Deadly
Deadly
Posts: 214
Joined: Sat Mar 08, 2008 9:30 am
Location: Devon, a backward little planet scourged by evil weather

Post by Commander Mysenses »

drumz wrote:
Currently I'm adding null zone, maximum range, and hysteresis, so I can add this into the mix without too much trouble.

Any news?
drumz
Competent
Competent
Posts: 36
Joined: Thu Jan 18, 2007 6:18 am

Post by drumz »

Not yet. School's been real busy lately. I'll get to it eventually, though.
User avatar
Dr Beeb
Dangerous
Dangerous
Posts: 127
Joined: Sun Mar 23, 2008 10:28 pm
Location: Mt. Vista, Oosa, Biarge System, Galaxy 1

slower yaw

Post by Dr Beeb »

nijineko wrote:
i use the yaw constantly. especially helpful once i've got a vert/hor lock on a thargian carrier and then i just spin the ship sideways to bring all four lasers to bear in sequence til.... BOOM. =D works very nicely against targets that don't move all that fast for whatever reason. or at least don't leave the horizontal plane of your ship.

i played descent 1, 2, and 3 a whole lot before playing here, so i'm used to being able to thrust in any axis as well as spin along any axis. (but that takes up a whole lot of keymapping on the keyboard!) i'd vote for it, but fear that it's not *lite enough. ^^

I resisted the yaw buttons for a while after introduced but capitulated and found them useful for things like swinging a (port) mining laser around to blast a target and swinging it back out of the way again.

One idea for Oolite is to edit the shipdata to match moment of inertia/engine designs of each craft. For instance a Cobra Mk III is so wide and (restrictive drive design) that its max yaw rate could be as slow as a Boa! This would make yaw not useful in a Cobra Mk III for close combat (but makes long distance precision aiming easier with a keyboard) and rebalancing gameplay re thargian carrier destruction ...
White dots were so much easier to hit
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

But the width also provides superior leverage. :-)
User avatar
nijineko
---- E L I T E ----
---- E L I T E ----
Posts: 353
Joined: Wed Jul 04, 2007 3:37 pm
Location: two strange quarks short of a graviton....
Contact:

Post by nijineko »

hmmmm, i'm going to have to try to calibrate the joystick and see how that goes....
arukibito ga michi wo erabu no ka, michi ga arukibito wo erabu no deshou ka?

Image
Play games. Win Amazon gift cards! Brag. Repeat.
User avatar
Commander Mysenses
Deadly
Deadly
Posts: 214
Joined: Sat Mar 08, 2008 9:30 am
Location: Devon, a backward little planet scourged by evil weather

Post by Commander Mysenses »

drumz wrote:
Currently I'm adding null zone, maximum range, and hysteresis, so I can add this into the mix without too much trouble.
Has RL allowed you to address this yet?
User avatar
drew
---- E L I T E ----
---- E L I T E ----
Posts: 2189
Joined: Fri May 19, 2006 9:29 am
Location: In front of a laptop writing a book.
Contact:

Post by drew »

Yaw... :cry:

Don't like it, doesn't feel like Elite at all. Infact, I dislike it so much I'm going to put an oblique reference into Mutabilis to that effect.

Fair enough if people like it, but I won't be using it.

Cheers,

Drew.
Drew is an author of SF and Fantasy Novels
WebsiteFacebookTwitter
Post Reply