Updating Speed Using Ultrasonic Sensors

I am trying to create code that will slow down the robot as it gets closer to an object.

So far I have been able to write code that will stop the robot using an “if” statement with the conditional being the range as measured by sonar.

if(sonar.getRangeInches() < 40) {
             motor.stop(); 

However, when I modify the code such that I want to change the speed on approach, I get “robotDrive…output not updated enough”. Any ideas? I’ve gotten the code to run by disabling the motor safety, but the sensitivity doesn’t change at all.

if(sonar.getRangeInches() < 40) {
            driveTrain.setSensitivity(0.5)
          elseif(sonar.....<30){
            driveTrain.setSensitivty(0.25)......


  • Put your robot on blocks so it wont drive.
  • Add print statements to your code that lists the distance and motor output value for each loop itteration.
  • Run your code while moving an object in front of the ultrasonic sensor.

There’s got to be a case where your if/else logic doesn’t result in the motor.drive() method being called.

Also, why are you using the setSensitiviy method, that affects turning not rate of travel.
See: http://team2168.org/javadoc/edu/wpi/first/wpilibj/RobotDrive.html

You can also do something like this. It starts a linear deceleration of the magnitude for mecanum drive. Just change out the numbers and the drive base and it will be fine.


    		double counter, startDecelDistance, stopDistance, differenceInDistance;
    		
    		startDecelDistance = 20;
    		stopDistance = 40;
    		
    		differenceInDistance = Math.abs(stopDistance-startDecelDistance);
    		
    		while(sonar.getRangeInches() < startDecelDistance && sonar.getRangeInches() > stopDistance) {
    			counter= Math.abs(startDecelDistance - sonar.getRangeInches()) / differenceInDistance;
    			myRobot.mecanumDrivePolar(counter, 0, 0);
    		}
    			myRobot.mecanumDrivePolar(0,0,0);

If you’re using CammandBased java, you should take a look at Gearsbot. It uses PID control to move to a certain distance away from an object and stop, which seems to be exactly what you’re trying here.

You might be better off overriding the set method of your motor controller. If you do it there, you only have to do it once, and not worry about it anywhere else.

You may also want to only reduce the throttle if the applied voltage will push you towards the wall, but allow full throttle to push you away from the wall.

In addition to everyone else’s suggestions, the problem you are having is mostly from the structure of your if statement

if(sonar.getRangeInches() < 40) {
            driveTrain.setSensitivity(0.5)
          elseif(sonar.....<30){
            driveTrain.setSensitivty(0.25)......

remember that if an if statement returns true, the other elses aren’t always evaluated
What you wrote


If it's <40, then do something
If it's not <40 but is <30, do something else (this can't happen!)

try instead building from one direction to the other


if(sonar.getRangeInches() >= 40) 
{
            driveTrain.setSensitivity(1);
}
else if(sonar.....>= 30)
{
            driveTrain.setSensitivity(0.5);
}
else /*if(sonar.....< 30)*/
{
            driveTrain.setSensitivty(0.25);
}

you can also do it mathematically (y=mx+b)

driveTrain.setSensitivty(sonar.getRangeInches() / 40)