Ultrasonic Sensor/Gyroscope Programming

I’ve never programmed an ultrasonic sensor before and am needing some help figuring it out. Basically, we want to use it during our skills autonomous to “align” with the wall without touching the wall. We want to have a sensor on both the left and right side of our front end on our robot. This is so that if the left reaches the desired location first, it would stop until the right side reached the same location and vice versa. I am not sure how to program it though. So how would I program two ultrasonic sensors to do so?

well, there are plenty of great tutorials on how to use the ultrasonic sensor. but this may be more difficult than you’d think, you’ll probably need two ultrasonics on each side.

I was planning on aligning with the wall with only the front of my robot, so my plan was to have one sensor on the front left and one on the front right, and I couldn’t find any tutorials because I am using Robot Mesh Studio with C++. How should I got about programming the sensors to do this?

oh well then I don’t know. sorry, only use robotC

Then how would you program it in Robot C? I have a friend in my organization that could help sort of convert C to C++.

well, in robotC, ultrasonic sensors will return a value of 0-255, how far away the object it “sees” is, in centimeters. so, SensorValue[sonar] can tell you how far away something is.

Oh, that makes sense. So if I input it within my autonomous code where I need to “align” with the wall, will it matter if I use two sensors v one sensor? So I guess what I’m asking is there anything specific I need to do to use two sensors instead of one?

I don’t think you need to do anything special if you have 2.

If I am understanding your question correctly, you should be using two ultrasonic sensors. You could set it so that while the left sensor is greater than the right sensor, turn left and vice versa. But make sure that it turns slowly, or it will probably overshoot the wall.

The basic command to fetch a distance from an ultrasonic sensor is the distance(vex::distanceUnits units) method of a vex::sonar object. It will return the distance calculated by the sensor in the units you specify. Using two facing the same direction may or may not be entirely reliable, however, as the echoes of one may interfere with the other. Depending on where you’re trying to line up, facing them slightly apart can help avoid this. The algorithm that mkinh describes would work: just watching for the difference between them to fall within a certain range.

If there’s a problem with two sensors, the other way to line up to a wall with a single sensor would be to poll the sensor while turning, then wait for the value to start increasing. The minimum reading would be where the sensor was pointed straight at the wall. This will work if the sensor is in-line with the robot’s center of rotation.

You do have to be careful with this method. For starters the sensors really don’t handle sharp angles well, ±45 degrees would be the absolute limit with significantly better results at +=20 degrees.

Also if your searching for the minimum value you have to make sure you filter any erroneous readings, these might not be an issue with a simple control loop because 1 bad reading won’t be a big deal. However if the 1 bad reading was the smallest value you saw obviously it could be a problem for search.

Here is some code from a few years ago that I used for “squaring up” with the walls using 2 ultrasonic sensors.

ultra.error = (currentLeftUltra-currentRightUltra);
while(abs(ultra.error) > 5 || abs(ultra.lastError) > 5)
	currentLeftUltra = getLeftUltra();
	currentRightUltra = getRightUltra();
	//writeDebugStreamLine("Left1: %d Right1: %d",currentLeftUltra,currentRightUltra);
	ultra.error = (currentLeftUltra-currentRightUltra);
	ultra.derivative = ultra.error - ultra.lastError;
	ultra.lastError = ultra.error;

	AngleOut = ultra.kP*ultra.error + ultra.kI*ultra.integral + ultra.kD*ultra.derivative;
	AngleOut = limit(-1*maxSquareTurnSpeed,maxSquareTurnSpeed,AngleOut);
	//writeDebugStreamLine("Left: %d Right: %d Error: %d Out: %d",currentLeftUltra,currentRightUltra,ultra.error,AngleOut);
	if(abs(ultra.error) < 10 && abs(ultra.lastError) < 10 && abs(vel) == 0)

and just for completeness

ultra.kP = 1.5;
ultra.kI = 0.001;
ultra.kD = 2;

I ended up using bumper switches to align with the wall instead of the ultrasonic sensors and it works really well. I am however now having trouble programming a gyroscope. What’s the best way to program accurate turns and how do I calibrate it accurately?

@5SRobotics You’ll probably have better luck creating a new thread for that question

Yeah, I did.

I would think you could monitor the distance from the ultrasonic to the wall compared to a fixed dimension. say you were on the right side of the field, and measuring the distance to the right wall.

Say you want to be 3 inches from the wall.

If you are running the motors at ~100, you would monitor the ultrasonic, and if the ultrasonic is greater than 3 inches, change the right motor command to 90.
If the ultrasonic is less than the fixed distance, change the right motor command to 110.
keep monitoring this and modulating the motor speed until your encoder counts are where you want the move to be.

Just for a heads up. In the code you posted, I don’t believe integral is defined.

Ya its probably set to 0 somewhere and then never used, integral term is the part of PID used least often and I guess that day didn’t need it.