FRC2706 / 2017-2706-Robot-Code

The main robot code for our 2017 Steamworks robot.
3 stars 3 forks source link

Deceleration curve for approaching target distance? #27

Open kevlam2706 opened 7 years ago

kevlam2706 commented 7 years ago

We've been playing with different ways to solve the problem of "drive smoothly and quickly to a distance X away from the wall".

What about applying a simple deceleration factor with a curve?

Consider a DriveWithDecelerationCurve command:

The operator is driving at a set speed forward (e.g. 70%).

inputSpeed = 0.7

Measure the distance from the wall. Compare it to some threshold we can set (say, 1 meter). If we're nowhere near the wall, allow the motors to go at the full commanded speed.

If distance > Threshold outputSpeed = inputSpeed

If the distance is less than the threshold then start comparing the distance to the target and scale the input speed using a curve. For example:

outputSpeed = inputSpeed * (1 / distance)

or

outputSpeed = inputSpeed * (1 - (1 / distance) )

So the closer and closer we get to the target distance the more and more we slow down the target speed.

kevlam2706 commented 7 years ago

si_motion_curve_types 1

kevlam2706 commented 7 years ago

A graph of 1/x looks like the curve labeled "acceleration".

A graph of 1-1/x looks like the curve labeled "deceleration".

cnnradams commented 7 years ago

Cool I'll look into it tomorrow

On Feb 7, 2017 10:54 AM, "Kevin Lam" notifications@github.com wrote:

A graph of 1/x looks like the curve labeled "acceleration".

A graph of 1-1/x looks like the curve labeled "deceleration".

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/FRC2706/2017-2706-Robot-Code/issues/27#issuecomment-278042553, or mute the thread https://github.com/notifications/unsubscribe-auth/AKAIuNh2LY-8l2JjRitwvbNmYi4NVuTIks5raJPRgaJpZM4L5q2x .

ryanlarkin commented 7 years ago

@Stealth2994, do you think that it would work if did something similar to StraightenWithDistanceSensor?

double offset = Math.abs(Robot.driveTrain.getLeftDistanceToObstacle()
    - Robot.driveTrain.getRightDistanceToObstacle());

double turnSpeed =
    baseSpeed + (offset / speedIncrease) - (speedDecrease * currentStopCycles);
cnnradams commented 7 years ago

The currentStopCycles thing is pretty hacky so I'd prefer to use actual math equations to do it, while using an average of the two sensors to get the distance.

ryanlarkin commented 7 years ago

This is pretty similar to what you did with it, maybe it could work?

Init:

double initialDistanceToObstacle = Math.abs(targetReading - currentReading);
a = (speed - minimumSpeed) / (1 - (1 / (1 + initialDistanceToObstacle)));

Execute:

double distanceToObstacle = Math.abs(targetReading - currentReading);
double driveSpeed = a * (1 - (1 / (1 + distanceToObstacle))) + minumumSpeed;

// Drive backwards in same pattern if target is behind robot
if((targetReading - currentReading) < 0)
    driveSpeed = -driveSpeed;
cnnradams commented 7 years ago

Yeah maybe as long as it doesn't use currentStopCycles