RC receiver signal processing for traction control system

I’m making a traction control system for a RC car I built , there is not much grip on the rear end of the car and it spins out on high speed cornering. The traction control will be optional and switched on/off via the third channel on the RC radio, I’ve been using the 3rd channel as a switch in a few projects, so got this part sort of figured out.

What I’m trying to do is, when the throttle is too high for a given steering input, the code must automatically override the manual throttle signal and reduce the throttle in proportion to the steering signals.
Of course, in what proportions the throttle must be reduced will be user defined through testing. What I am not able to figure out is what functions and/or logic I must be using. I used the pulseIn() function to read signals from the RC receiver and a map too which I don’t know if it’s appropriate.

#include <Servo.h>

Servo steer, esc;

unsigned long steerPulse; //steering output
unsigned long escPulse; //Throttle output
unsigned long steerRx = 6; //steering input
unsigned long escRx= 5; //throttle input


void setup()
{
  pinMode (steerRx, INPUT);
  pinMode (escRx, INPUT);
  steer.attach (11);
  esc.attach (10);
  Serial.begin (9600);
}

void loop()
{
  steerRx = pulseIn(6, HIGH);        //read steering signal from Rx
  escRx = pulseIn(5, HIGH);          //read throttle signal form RX

  escPulse = map(steerRx,1500, 990, 1720, 1426); //1500-990 is lefthand range of steering & 1500-1750 is righthand range
                                                                          // 1426-1720 is the total forward throttle range i.e, min-max, respectively
  esc.write(escPulse); 

  steer.write(steerRx); // Steering input directly goes to steering output without any processing 

  esc.write(escRx); // added this because I was not able to control throttle with the manual throttle control on the radio
                                 // It still doesn't work though.

  Serial.println("Start");
  Serial.println(steerRx);
  Serial.println(escRx);
  Serial.println(escPulse);
  Serial.println("END");

}

// It still doesn't work though.

This isn't enough information. You need to find some way to tell us what is currently happening in way that we can use. Either add serial prints of values you are sending to the motor or servo and capture serial prints using a terminal capture program like Clear Terminal and post the capture file or post a screenshot of the serial prints . Without more information there is not much we can do. We need more information to help us find out why it isn't working. Right now we have nothing. We really don't even know why it is spinning out. You haven't posted a schematic. If you are using an RC ESC and the command is coming from a receiver to the ESC, where is the command originating from ? Post a block diagram.

Your logic used to calculate escPulse doesn't look right to me. I would have thought you would want to convert the steering pulse into an offset from straight ahead, take the absolute value of that and use it to constrain the throttle output.

It's not related to your project but I wonder if you've considered trying to make a yaw stabiliser for your vehicle based on a gyro. I would expect that to make the vehicle much easier to control when it's sliding. Without detecting actual wheelspin, I suspect the algorithm you're proposing is only going to have limited benefit because the amount of throttle that can be tolerated for a given steering input will vary enormously with conditions.

What @Anjanbabu seems to be proposing is not actually a traction control system, is more like a drive by wire system, to make up for the driver's lack of ability to reduce throttle when cornering.

If he has a half decent remote controller, they normally have mapping tables built into them, specifically to control throttle settings, based on other inputs.

AFIK, real traction control systems, normally monitor the actual rotation of each wheel to determine if a specific wheel is rotating quicker than it should do, the take the appropriate action (possibly applying the break to the wheel that has lost traction, as well as reducing the engine power output until traction has been regained.

@Anjanbabu doesn't really say what is not working, i.e there may be no data going to the motor control (ESC) at all. Or the PulseIn stuff may not be working. Who knows ;-)

I suspect that linear mapping is probably no good, he'd need to use a look-up table of non-linear values with interpolated sub-points (linear interpolation would probably suffice)

However, simple 1 dimensional look-up may not be sufficient, as as loosing traction is almost certainly going to be a function of both speed and radius of turn, and unfortunately the ESC value (motor power) is not going to give you speed, (it only gives you acceleration when at rest). So without further sensors, he'd need to write some sort of inertial speed calculation based on the ESC (motor power). But I suspect this would be very inaccurate.

If Anjanbabu really wants to go down this route, he will really need to buy loads more sensors and not just rely on command inputs to determine require outputs.

If Anjanbabu really wants to go down this route, he will really need to buy loads more sensors and not just rely on command inputs to determine require outputs.

How about using an accelerometer instead of Load sensors ?

Know i’m a little late to the party here, But this is a basic active throttle control. Real cars will have this to an extent built into there traction control system, Basically it will restrain/reduce the throttle in accordance to steering angle.

Try this formula if you are still playing around with this, Anjanbabu.

Inside the Loop

thrIn = map(escRx, 1000, 2000, -500, 500)
steerIn = map(steerRx, 1000, 2000, -500, 500)

if(thrIn > 200){
trac = thrIn-((sqrt(steerIn)+(sqrt(thrIn)*(thrIn/45)
thrOut = map(trac, -500, 500, 1000, 2000)
}
esle(thrIn < 200){
thrOut = thrIn
}

This will reduce the output of the throttle by a percentage of the combined steering and throttle inputs.

for example if Steer input is 300 and throttle is 450, so high speed med-high steer the reduction factor would be 380 so throttle output would be 70.
I had to add the * thrIn/45 as my first attempted used simple result of sqrt thrIn+ sqrt steerIn/10 but this resulted in a braking situation or reverse if the steering input was higher than the throttle.
If you invert the two used in the previous example, so, steerIn 450 + thrIn 300 * thrIn/45 = a reduction of 253, thrOut = 47
where as with *10 (instead of thrIn/45) it would of been a reduction of 380 = thrOut -80.<<Not good.

Obviously this is just a basic equation I came up with so it will need some fiddling to get it working in the real world. Also just be aware that a car reducing its wheel speed by 90% at high speed with simultaneous high angle steering input will make it very unstable.

It may pay to create two or more formulas, or reduce the reduction with multiple if else statements as the throttle increases towards the higher end.

To wire this up I would use a ‘Y’ harness for the steering Servo, so the Arduino is only using it a reference and the RX still has control of it. This way you can keep this loop running as all it is doing is mapping the throttle to steering. otherwise you may have to use interrupts to keep it happening together.

I have only just started playing around with Arduino, so my code will need work if copied and pasted, It was mainly to supply a formula and roughly how to use it. I am currently working on a Traction control code that uses accelerometer data with a NanoWii board, I have all the components figured out, I think, I just need to assemble and test them together. Hopefully it should be done in a few weeks with no bugs. I will start a thread when it is.

Cheers