Vibrate the brake pedal when wheel's blocking

Here you can show and share your design ideas and ask questions about them

Vibrate the brake pedal when wheel's blocking

Postby RacingMat » Thu 27. Jun 2013, 16:38

Hello !

This post is about braking !!
I'm looking for more realistic feedbacks in order to improve my driving "performance" ;-) and increase the immersion feeling.

Considering a load-cell brake pedal, it's lacking of feedback from the wheels and in particular when they are blocking...

If I can feel in my pedal when the wheels are blocked : I could release a bit of pressure and hence being the closest to the best braking.

In the case of a car with ABS, if I can feel the rumble in my foot : it'd increase the immersion feeling !

A commercial product does this : the Fanatec CSP V2 (motor + plugin). When the wheels are blocked, a motor is vibrating.

How can I implement this in my DIY pedals with Xsim ?

I've looked for wheel's speeds or ABS activation in the sender's data (rFactor) but I haven't seen this information...

Someone has developped an external plug-in for rFactor http://www.richardjackett.com/brakemodproject
but may be (certainly) Xsim could do this natively :?:

Thanks :!:
Mat
___________________________________________________________________

edit : Okay, here is the result.
It not completely finalised but effective.

General setup:
so I went the ISI C++ "internal plugin" way : programming a plugin to send infos via USB to arduino
Inside the rFactor plugin, I open a serial communication directly to my Arduino nano through USB cable : no need of Xsim in this case.
directly from game plugin to Arduino board.

An .ini file is used to setup the parameters (grip level, mode...)
USB Comport selection via ini file is not effective : you have to manually force Windows to reassign your arduino on COM19 @115200

Plugin telemetry data available:
Inside the plugin example from rFactor, you can see a slip ratio :
Code: Select all
TelemWheel
.mRotation; (float) // radians/sec
.mGripFract; (float) // an approximation of what fraction of the contact patch is sliding


so I can check the slip ratio of each wheel = mWheel[i].mGripFract
if mGripFract > 80% then the wheel is blocked and is sliping

I customised the internal rFactor plugin and I coded 2 modes:
- wheel.mGripFract above a %
- difference between wheel.mRotation and vehicle speed above a %

There are also more possibilities in the computing (still pending):
using the 4 wheel's maximum or the 4 wheels mean value or the 2 front wheels or ...


The code of plugin:
I'm using a library "serialib" to implement my serial com port
and "Readini" to parse my ini file to get some user parameters.

Racingmat brakeplugin rFactor sources.zip
(10.81 KiB) Downloaded 415 times


This code is the source. It allows you to understand what is really done inside the plugin.
This code needs to be compiled by Microsoft Visual C studio into a .ddl file. See next chapter

Code: Select all
//ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
//Ý                                                                         Þ
//Ý Module: Internals Example Source File                                   Þ
//Ý                                                                         Þ
//Ý Description: Declarations for the Internals Example Plugin              Þ
//Ý                                                                         Þ
//Ý                                                                         Þ
//Ý This source code module, and all information, data, and algorithms      Þ
//Ý associated with it, are part of CUBE technology (tm).                   Þ
//Ý                           PROPRIETARY                                   Þ
//Ý Copyright (c) 1996-2006 Image Space Incorporated.  All rights reserved. Þ
//Ý                                                                         Þ
//Ý                                                                         Þ
//Ý Change history:                                                         Þ
//Ý   tag.2005.11.30: created                                               Þ
//Ý   jmm.2006.01.06: modified for public                                   Þ
//Ý                                                                         Þ
//ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß

//***************************************************************************//
#include "Example.hpp"          // corresponding header file
#include <math.h>               // for atan2, sqrt
#include <stdio.h>              // for sample output
//***************************************************************************//
//RacingMat
#include "serialib.h"   // Library described above
#include "ReadIni.h"
#include <tchar.h>
#include <stdlib.h>
//create the serial communication SerialCom
serialib SerialCom;   

   char *cpMode; // grip lost or blocked wheel
   char *cpLevel; // grip loss level
   char *cpApproxDiam; // approximative wheel diameter
   double level;
//***************************************************************************//
// plugin information
// Change this information to siut your needs. rFactor will use this information
// to ensure that it is using the most recent version
unsigned g_uPluginID          = 2;
//RacingMat
char     g_szPluginName[]     = "RacingMat Brake Pedal - 2013-07-12";
//RacingMat
unsigned g_uPluginVersion     = 002;
unsigned g_uPluginObjectCount = 1;
InternalsPluginInfo g_PluginInfo;
//***************************************************************************//

//***************************************************************************//
// interface to plugin information
extern "C" __declspec(dllexport)
const char* __cdecl GetPluginName() { return g_szPluginName; }

extern "C" __declspec(dllexport)
unsigned __cdecl GetPluginVersion() { return g_uPluginVersion; }

extern "C" __declspec(dllexport)
unsigned __cdecl GetPluginObjectCount() { return g_uPluginObjectCount; }

// get the plugin-info object used to create the plugin.
extern "C" __declspec(dllexport)
PluginObjectInfo* __cdecl GetPluginObjectInfo( const unsigned uIndex )
{
  switch(uIndex)
  {
    case 0:
      return  &g_PluginInfo;
    default:
      return 0;
  }
}
//***************************************************************************//

//***************************************************************************//
// InternalsPluginInfo class
InternalsPluginInfo::InternalsPluginInfo()
{
  // put together a name for this plugin
  sprintf( m_szFullName, "%s - %s", g_szPluginName, InternalsPluginInfo::GetName() );
}
//***************************************************************************//

//***************************************************************************//
const char*    InternalsPluginInfo::GetName()     const { return ExampleInternalsPlugin::GetName(); }
const char*    InternalsPluginInfo::GetFullName() const { return m_szFullName; }
// Change this to suit your needs
const char*    InternalsPluginInfo::GetDesc()     const { return "RacingMat Brake Pedal"; }
const unsigned InternalsPluginInfo::GetType()     const { return ExampleInternalsPlugin::GetType(); }
const char*    InternalsPluginInfo::GetSubType()  const { return ExampleInternalsPlugin::GetSubType(); }
const unsigned InternalsPluginInfo::GetVersion()  const { return ExampleInternalsPlugin::GetVersion(); }
void*          InternalsPluginInfo::Create()      const { return new ExampleInternalsPlugin(); }
//***************************************************************************//

//***************************************************************************//
// InternalsPlugin class
const char ExampleInternalsPlugin::m_szName[] = "RacingMatBrakePedalPlugin";
const char ExampleInternalsPlugin::m_szSubType[] = "Internals";
const unsigned ExampleInternalsPlugin::m_uID = 1;
const unsigned ExampleInternalsPlugin::m_uVersion = 1;
//***************************************************************************//

//***************************************************************************//
PluginObjectInfo *ExampleInternalsPlugin::GetInfo() { return &g_PluginInfo; }
//***************************************************************************//

//***************************************************************************//
void ExampleInternalsPlugin::Startup()
{
 // Open ports, read configs, whatever you need to do.
 // Read the windows COM Port of the Arduino
 // in the ini file

// default enabled to true
    mEnabled = true;
    int Ret;      // Used for return values

// path of the ini file (same directory as this plugin)
   LPCSTR localPath="Plugins\\BrakePlugin.ini";

   char *cpComPort;
   char *cpBaudRate;


 // read a string value of a key in a section of the ini file
 //                            section        key        default value        ini file path
   cpComPort=ReadKeyString(_T("Serial"), _T("Port"), _T("\\\\.\\COM6"), _T(localPath));
   // Beware !! if the address is given by the ReadKey function (from ini file), no double \\ before com port address
   // inside the ini file, only \\ ? or \\\\ ?

    cpBaudRate=ReadKeyString(_T("Serial"), _T("Baudrate"), _T("115200"), _T(localPath));
   // Open serial link Com Port at BaudRate
//   Ret=SerialCom.Open(cpComPort,atof(cpBaudRate));
//      Ret=SerialCom.Open(cpComPort,115200);
   Ret=SerialCom.Open("\\\\.\\COM19",115200);

    cpMode=ReadKeyString(_T("Parameters"), _T("Mode"), _T("1"), _T(localPath));
    cpLevel=ReadKeyString(_T("Parameters"), _T("Level"), _T("0.6"), _T(localPath));
    level = atof(cpLevel);

   cpApproxDiam=ReadKeyString(_T("Parameters"), _T("ApproxDiam"), _T("0.5"), _T(localPath));


}
//***************************************************************************//

//***************************************************************************//
void ExampleInternalsPlugin::EnterRealtime()
{
  // start up timer every time we enter realtime
  mET = 0.0f;
}
//***************************************************************************//

//***************************************************************************//
void ExampleInternalsPlugin::UpdateTelemetry( const TelemInfo &info )
{
  const unsigned short cusBufferSize = 1024;
  char* cpTemp = new char[cusBufferSize];

    const float metersPerSec = sqrtf( ( info.mLocalVel.x * info.mLocalVel.x ) +
                                    ( info.mLocalVel.y * info.mLocalVel.y ) +
                                    ( info.mLocalVel.z * info.mLocalVel.z ) );
    //RacingMat
  int noGripWheels = 0;   
  int lockedWheels = 0;   

  float approxDiam = 0.5 ; // toDo convert char cpApproxDiam into float
//  double level = 0.80; // toDo convert char cpLevel into float
//  level = 0.80 -> wheels must have less than 80% of the grip
  char* vibrate;
  int Ret;

  vibrate="0"; // false
  if ((metersPerSec>0.1) & (info.mUnfilteredBrake >= 0.4 ))
  {
  if (cpMode="1")
    {
   for( long i = 0; i < 4; ++i )
    { // for each wheel
      // Wheels (i==0)"FrontLeft"
      // (i==1) "FrontRight"
      // (i==2) "RearLeft"
      // (i==3) "RearRight"
      const TelemWheel &wheel = info.mWheel[i];

     // count how many wheels are blocked
     // check if wheel rotates less than expected by the vehicule speed (minus 50%)
     if ((3.14*approxDiam*abs(wheel.mRotation))<(0.50*metersPerSec))  { ++lockedWheels; }
   }
     if (lockedWheels>=2) 
       vibrate="1"; //true
  } else
    {
   for( long i = 0; i < 4; ++i )
    { // for each wheel
      // Wheels (i==0)"FrontLeft"
      // (i==1) "FrontRight"
      // (i==2) "RearLeft"
      // (i==3) "RearRight"
      const TelemWheel &wheel = info.mWheel[i];

     // count how many wheels lost its grip
     if (wheel.mGripFract<level) { ++noGripWheels; } // coupler avec freinage en cours et avec vitesse rel non nulle
   }
      //envoie le signal perte de grip ou non
      if (noGripWheels>=2)
       vibrate="1"; //true
   }
  }
  Ret=SerialCom.WriteString(vibrate);       // Send the command on the serial port
      
  if(cpTemp)
    delete [] cpTemp;
}
//***************************************************************************//

//***************************************************************************//
void ExampleInternalsPlugin::UpdateGraphics( const GraphicsInfo &info )
{
//
}
//***************************************************************************//

//***************************************************************************//
bool ExampleInternalsPlugin::CheckHWControl( const char * const controlName, float &fRetVal )
{
  return( false );
}
//***************************************************************************//

//***************************************************************************//
bool ExampleInternalsPlugin::ForceFeedback( float &forceValue )
{
  return( false );
}
//***************************************************************************//


The code of .ini file:

Code: Select all
[Serial]
Baudrate=115200
Port=\\.\\COM19

[Parameters]
; Mode=1 is blocked wheels
; Mode=2 is grip loss
Mode=1
;level of grip loss
Level=0.4
;approximative diameter of wheels
; if greater, vibration will arise sooner
ApproxDiam=0.6



The .dll and .ini files:

RacingMatBrakePlugin.zip
(140.57 KiB) Downloaded 391 times


the .dll and .ini files have to be put into the rfactor plugin directory

Arduino code:
extremely simple

for debugging/tuning purpose, you can light a LED
but next, just plug your relay instead of LED to drive the solenoid.

Code: Select all
int ledPin = 13;                       // Sortie où sera branchée la LED
int ledState = LOW;                    // Etat de la LED (LOW par défaut)

void setup() {
  Serial.begin(115200);                  // On initialise la connexion
  pinMode(ledPin, OUTPUT);             // Et la sortie de la LED
}

void loop() {
  int received;                        // Variable servant à récupérer
                                       // les données reçues

  if (Serial.available()>0) {          // Si des données sont disponibles
    received = Serial.read();          // On les récupère
    if(received == '1')               // Si "0" est reçu
        ledState = HIGH ;                // On éteinds la LED
      else                             // Sinon
        ledState = LOW;               // On l'allume

      digitalWrite(ledPin, ledState);  // Enfin on change l'état de la LED
     
  }
}


The actuator:

the solenoid is the best, the most reactive! compared to excentric DC motors
This solenoid comes from a steptronic

Here are the results of my tests of driving Solenoid from Arduino:
Last edited by RacingMat on Thu 6. Nov 2014, 23:28, edited 1 time in total.
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 454
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 124 times

Re: Vibrate the brake pedal when wheel's blocking

Postby yokoyoko » Thu 27. Jun 2013, 17:21

http://x-sim.de/forum/viewtopic.php?f=65&t=422

It is working for me. But it is very hard to configure to get the maximum brake forces when locking starts. I have to do it for every car/track/game seperate.
User avatar
yokoyoko
 
Posts: 392
Images: 28
Joined: Tue 7. Aug 2012, 03:16
Location: Germany / Bad Eilsen
Has thanked: 33 times
Been thanked: 12 times

Re: Vibrate the brake pedal when wheel's blocking

Postby RacingMat » Thu 27. Jun 2013, 17:48

Hi Yokoyoko !

If I've understood what I've read in your post, my purpose is a bit different :
I'd like to get vibration when wheels are blocked in the game
not at a certain amount of pressure from the foot...

PS1 : i'm working on a DIY load cell pedal + circuit just as yours from Derek http://simrace.hgsitebuilder.com/circuits
more to see soon (I hope)

PS2 : other subject : I'm feeling as if your 3DOF virus has contaminated me ... :lol:
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 454
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 124 times

Re: Vibrate the brake pedal when wheel's blocking

Postby Racerr87 » Thu 27. Jun 2013, 18:50

Try this for interface i have also made my own loadcell pedals.

http://www.leobodnar.com/shop/index.php ... cts_id=183

The board works like it should and is cheaper 8-) .
Racerr87
 
Posts: 40
Images: 7
Joined: Mon 7. May 2012, 17:01
Has thanked: 3 times
Been thanked: 5 times

Re: Vibrate the brake pedal when wheel's blocking

Postby yokoyoko » Thu 27. Jun 2013, 19:36

Racerr87 wrote:Try this for interface i have also made my own loadcell pedals.

http://www.leobodnar.com/shop/index.php ... cts_id=183

The board works like it should and is cheaper 8-) .


BUT the derek speare is better :D in my opinion. You have a pot for adjusting the brake. Leo's board does not have this feature and he has his own politic on "when to ship" ... derek is much faster (just my experience). And to be honest - we have such expensive simulators - that I don't look where I can save ~10€ ;)

Back to topic - it is about pedal vibration here!

If I've understood what I've read in your post, my purpose is a bit different :
I'd like to get vibration when wheels are blocked in the game
not at a certain amount of pressure from the foot...


No we mean the same thing. My words to explain it - are not the best for sure...
I only get this work if I can find the exact amount of pressure (value of the load cell in x-sim) where the wheels start to lock. From there on the shaker starts to vibrate the pedal. The problem is that not every car has the same value for that lock point. A miata mx5 locks earlier than a radical sr8... The grip (tarmac) at limerockpark is not as high as in silverstone and so on....

Would be cool to have this feature "locked wheels" as shared memory value BUT I don't know if any game supports this. Do you have further informations for us?
User avatar
yokoyoko
 
Posts: 392
Images: 28
Joined: Tue 7. Aug 2012, 03:16
Location: Germany / Bad Eilsen
Has thanked: 33 times
Been thanked: 12 times

Re: Vibrate the brake pedal when wheel's blocking

Postby RacingMat » Thu 27. Jun 2013, 20:04

Yep ! I got your point : we are looking for the same thing !

- You try to calculate the lock depending on car and road grip parameters : it needs to "guess and try" for each combination of car and road grip

- I've read in Richard website that he managed to extract wheels speed from ISI games : so he got direct information of blocked wheels !
if(3.0*abs(wheel.mRotation)/metersPerSec<=.5) // if wheel is rotating slower than 50% vehicle spd

that's this wheel's rotation information that I'm looking for :-)

@Racerr87 : I'd love to see pictures of your works <3 as I'm currently building mine http://www.gamoover.net/Forums/index.php?topic=28158.msg445132
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 454
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 124 times

Re: Vibrate the brake pedal when wheel's blocking

Postby Racerr87 » Thu 27. Jun 2013, 21:36

RacingMat wrote:
@Racerr87 : I'd love to see pictures of your works <3 as I'm currently building mine http://www.gamoover.net/Forums/index.php?topic=28158.msg445132


No problem, i made a new post to not go offtopic in your post.

viewtopic.php?f=40&t=1090

Questions? Just ask 8-) .
Racerr87
 
Posts: 40
Images: 7
Joined: Mon 7. May 2012, 17:01
Has thanked: 3 times
Been thanked: 5 times

Re: Vibrate the brake pedal when wheel's blocking

Postby RacingMat » Wed 3. Jul 2013, 15:17

I'm looking further into the ISI's plugin http://rfactor.net/web/rf1/devcorner/

in the example's documentation http://rfactor.net/web/dl/rf1/rFactorExamplePlugin.zip,
I can see that wheel's rotational speed is known individually :shock:

but I don't see what is the next brick : what would be between the ISI plugin and my pedal ?
X-sim ? another software ?
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 454
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 124 times

Re: Vibrate the brake pedal when wheel's blocking

Postby RacingMat » Wed 3. Jul 2013, 15:49

here are the two proposals :
1741

1740
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 454
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 124 times

Re: Vibrate the brake pedal when wheel's blocking

Postby yokoyoko » Wed 3. Jul 2013, 19:39

I think x-sim can do this job for us/you.
It is a really good idea Mat!

Do you know if it is working for Richard (the one with the blog)?
if(3.0*abs(wheel.mRotation)/metersPerSec<=.5) // if wheel is rotating slower than 50% vehicle spd


---> Meter/sec is the speed of the vehicle but what is the rotation of the wheel in? I would guess [rad/sec] or [rotations/sec] ....
Do you know why he is using 3.0*abs(wheel rotation) - abs = radical - why the value of 3xradical of wheel rotation. I can't get it at the moment...

If we know the radius of the wheels!? Do we?
For example:
Car is 72km/h fast ---> 20m/s and the tire has a radius of 0,25m and does 80 rotations/sec
The circumferential speed of the wheels is 20m/s too.
w=v/r -->angular speed --> w= 20m/s / 0,25m = 80 u/s

I think we have to look to get the circumferential speed ... if this value is smaller than the vehicles speed = the wheels are blocking.???

Kindly ask sirnoname if he has time to assist us with the coding for the rfactor plugin - and you will have to do the beta tests.
User avatar
yokoyoko
 
Posts: 392
Images: 28
Joined: Tue 7. Aug 2012, 03:16
Location: Germany / Bad Eilsen
Has thanked: 33 times
Been thanked: 12 times

Next

Return to Motion simulator designs

Who is online

Users browsing this forum: No registered users and 2 guests