YukMingLaw / ArduinoJoystickWithFFBLibrary

An Arduino Joystick Library With Force Feedback Feature
GNU Lesser General Public License v3.0
208 stars 55 forks source link

Spring only works on one axis #14

Closed jmriego closed 3 years ago

jmriego commented 3 years ago

Hi! First of all thank you so much for this library. I'm making a lot of progress creating a joystick and I would have never been able without this!

I am trying to create a working example and test several effects. I can't manage to work the damper and inertia but that's probably just me having to learn. It seems like the spring effect does only work on one axis. I have created an example of a joystick with x and y axes and tried running a spring effect. It only seems to affect the Y axis. I have tested in both fedit.exe and ForceTest.exe.

#define DEBUG
#include <Joystick.h>

// --------------------------
// Joystick related variables
// --------------------------
#define minX 0
#define maxX 1023
#define minY 0
#define maxY 1023
int16_t posX;
int16_t posY;
#define default_gain 100
Gains gain[2];
EffectParams effects[2];
int32_t forces[2] = {0};

Joystick_ Joystick(
    JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK,
    2, 0, // Button Count, Hat Switch Count
    true, true, false, // X, Y, Z
    false, false, false, // Rx, Ry, Rz
    false, false, // rudder, throttle
    false, false, false); // No accelerator, brake, or steering

void setup() {
    // setup connections
    Serial.begin(9600);
    delay(2000); //Give the serial port time to catch up so we can debug

    // setupJoystick
    Joystick.setXAxisRange(minX, maxX);
    Joystick.setYAxisRange(minY, maxY);

    //set x axis gains
    gain[0].totalGain = 100;
    gain[0].springGain = 100;
    //set y axis gains
    gain[1].totalGain = 100;
    gain[1].springGain = 100;
    Joystick.setGains(gain);

    Joystick.begin();
}

void loop(){
    posX = 0; posY = 0;
    doJoystickStuff();
    delay(1);
}

void doJoystickStuff(){
    effects[0].springMaxPosition = maxX;
    effects[1].springMaxPosition = maxY;
    effects[0].springPosition = posX;
    effects[1].springPosition = posY;

    Joystick.setXAxis(posX);
    Joystick.setYAxis(posY);
    Joystick.setEffectParams(effects);
    Joystick.getForce(forces);

    //Get Force [-255,255] you can set PWM with this value
    #ifdef DEBUG
    Serial.println("");
    Serial.print(" - X: ");
    Serial.print(posX);
    Serial.print(" - Y: ");
    Serial.print(posY);
    Serial.print(" - XF: ");
    Serial.print(forces[0]);
    Serial.print(" YF: ");
    Serial.print(forces[1]);
    #endif
}

This is the code I'm using. You can see debug messages in serial about the x and y positions and the x and y forces. Thanks in advance!

ZockZock commented 3 years ago

I have the same Issue!!

YukMingLaw commented 3 years ago

Hi,can you provide ‘fedit.exe’ and ‘ForceTest.exe’ s downloadlink?

jmriego commented 3 years ago

sure, I got ForceTest.exe from this link: https://www.fs-force.com/support.php The fedit.exe is available in this other link: https://github.com/bobhelander/EDForceFeedback/tree/master/EDForceFeedback/FFUtils

Thanks for having a look!

ZockZock commented 3 years ago

Other Effects like damper, friction and inertia also not working on x [0] axis .

jmriego commented 3 years ago

This seems to be related to this line: https://github.com/YukMingLaw/ArduinoJoystickWithFFBLibrary/blob/45ee061d4e71ee2fea0028fa0f76bbae1a2398cf/src/Joystick.cpp#L557

It looks like spring, damper, inertia and friction don't really have direction but this part of the code sets the angle to 0 so sin(0)ends up making the X axis force zero

jmriego commented 3 years ago

I have investigated this issue a bit more and there are several reasons why this is happening:

  1. The line I showed in my previous comment will apply and it will calculate the sin and cos of the angle to apply to the x and y axes. When spring doesn't have a direction its value is 0. So it always will make the force 0 in the x direction.
  2. Reading this doc https://github.com/bobhelander/EDForceFeedback/blob/master/EDForceFeedback/FFUtils/pid1_01.pdf shows me the condition forces (spring, inertia, etc.) can use two conditions. So it needs to be able to read the x condition (which will be where the x spring center is and same for the y axis). The original driver used that this repo uses cannot read multiple conditions.
  3. There are some weirdness with the calculation of the forces in ConditionForce calculation. I don't totally understand this part but I made some changes based on what I saw on the pdf

I just sent a pull request #15 @ZockZock Let me know if it works for you!

YukMingLaw commented 3 years ago

@jmriego nice work!

jmriego commented 3 years ago

thanks! glad I could contribute something here