1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Software "Dampening" via Arduino RC Model Servo Code

Discussion in 'iRacing' started by markh777, Nov 28, 2020.

  1. markh777

    markh777 New Member Gold Contributor

    Joined:
    Dec 20, 2017
    Messages:
    1
    Location:
    United States
    Balance:
    - 29Coins
    Ratings:
    +0 / 0 / -0
    Software "Dampening"

    I am using the RC Model Servo Code that EAOROBBIE wrote for a traction loss seat.

    It is working remarkably well, except when I get in a very tight "spin", or a slow spin, it gets choppy.

    I can get some of it out by adjusting all the possible numbers, but I might lose a little speed and/or fidelity.

    I am using running iRacing and based on everything I have read tells me it is the telemetry causing the issue.

    Looking at the Arduino code, I'm wondering if there is a way to dampen choppy output?

    While I don't understand all of the code, so I'm just hypothesizing here, but if it could "smooth" on a curve, maybe based on speed, or abrupt change?

    Meaning more "smoothing" when an abrupt change happens, or at slower speeds.

    PS, I'm studying the code and trying to figure it out (having problems determining the input values), so any help with "dampening" code, or code lessons would greatly be appreciated.


    Thanks to EAORobbie and aarondc!




    //********************************************************************************************
    // RC Model Servo
    // Original code By EAOROBBIE (Robert Lindsay)
    // Completely mangled by aarondc
    // For free use for Sim Tool Motion Software
    //********************************************************************************************
    #include <Servo.h>
    //#define DEBUG 1 // comment out this line to remove debuggin Serial.print lines
    const int kActuatorCount = 2; // how many Actuators we are handling

    // the letters ("names") sent from Sim Tools to identify each actuator
    // NB: the order of the letters here determines the order of the remaining constants kPins and kActuatorScale
    const char kActuatorName[kActuatorCount] = { 'R', 'L' };
    const int kPins[kActuatorCount] = {4, 5}; // pins to which the Actuators are attached
    const int kActuatorScale[kActuatorCount][2] = { { 0, 179 } , // Right Actuator scaling
    { 179, 0 } // Left side Actuator scaling
    };
    const char kEOL = '~'; // End of Line - the delimiter for our acutator values
    const int kMaxCharCount = 3; // some insurance...
    Servo actuatorSet[kActuatorCount]; // our array of Actuators
    int actuatorPosition[kActuatorCount] = {90, 90}; // current Actuator positions, initialised to 90
    int currentActuator; // keep track of the current Actuator being read in from serial port
    int valueCharCount = 0; // how many value characters have we read (must be less than kMaxCharCount!!

    // set up some states for our state machine
    // psReadActuator = next character from serial port tells us the Actuator
    // psReadValue = next 3 characters from serial port tells us the value
    enum TPortState { psReadActuator, psReadValue };
    TPortState currentState = psReadActuator;

    void setup()
    {
    // attach the Actuators to the pins
    for (int i = 0; i < kActuatorCount; i++)
    actuatorSet.attach(kPins);

    // initialise actuator position
    for (int i = 0; i < kActuatorCount; i++)
    updateActuator(i);

    Serial.begin(9600); // opens serial port at a baud rate of 9600
    }

    void loop()
    {

    }

    // this code only runs when we have serial data available. ie (Serial.available() > 0).
    void serialEvent() {
    char tmpChar;
    int tmpValue;

    while (Serial.available()) {
    // if we're waiting for a Actuator name, grab it here
    if (currentState == psReadActuator) {
    tmpChar = Serial.read();
    // look for our actuator in the array of actuator names we set up
    #ifdef DEBUG
    Serial.print("read in ");
    Serial.println(tmpChar);
    #endif
    for (int i = 0; i < kActuatorCount; i++) {
    if (tmpChar == kActuatorName) {
    #ifdef DEBUG
    Serial.print("which is actuator ");
    Serial.println(i);
    #endif
    currentActuator = i; // remember which actuator we found
    currentState = psReadValue; // start looking for the Actuator position
    actuatorPosition[currentActuator] = 0; // initialise the new position
    valueCharCount = 0; // initialise number of value chars read in
    break;
    }
    }
    }

    // if we're ready to read in the current Actuator's position data
    if (currentState == psReadValue) {
    while ((valueCharCount < kMaxCharCount) && Serial.available()) {
    tmpValue = Serial.read();
    if (tmpValue != kEOL) {
    tmpValue = tmpValue - 48;
    if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
    actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue;
    valueCharCount++;
    }
    else break;
    }

    // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name
    if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    #ifdef DEBUG
    Serial.print("read in ");
    Serial.println(actuatorPosition[currentActuator]);
    #endif
    // scale the new position so the value is between 0 and 179
    actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    #ifdef DEBUG
    Serial.print("scaled to ");
    Serial.println(actuatorPosition[currentActuator]);
    #endif
    updateActuator(currentActuator);
    currentState = psReadActuator;
    }
    }
    }
    }


    // write the current Actuator position to the passed in Actuator
    void updateActuator(int thisActuator) {
    actuatorSet[thisActuator].write(actuatorPosition[thisActuator]);
    }
  2. Ads Master

    Ads Master

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
  3. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    16,041
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    117,037Coins
    Ratings:
    +9,360 / 46 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    If you consider it a game telemetry related problem then please post pictures and a video to show what you mean.

    But it sounds more like it could be resolved via SimTools configuration, specifically a combination of Axis Assignment, Tuning Center and if needs be Smoothing settings, again posting pictures of your settings would help..

    If you want global smoothing then you can do that in Game Manager -> Profile Manager and lower the Intensity Level %.

    You can add smoothing per axis in Axis Assignments using the Smoothing filter.

    Grab a copy of the SimTools manual and keep it handy for reference: https://www.xsimulator.net/community/faq/rtfm-start-with-the-official-simtools-documentation.117/
  4. SeatTime

    SeatTime Well-Known Member

    Joined:
    Dec 27, 2013
    Messages:
    2,608
    Location:
    Newcastle Australia
    Balance:
    27,927Coins
    Ratings:
    +2,876 / 37 / -0
    My Motion Simulator:
    DC motor, AC motor, Arduino, Motion platform, 6DOF
    Expect it to always be a touch choppy due to only 8 bit resolution (Max 256 positions).