We have decided to try and use 2 ultrasonic range finders to square up with the trough in autonomous. The plan is to control the motors on each side with a seperate sensor in the event that there is any wheel slippage while making turns with our encoders.
I have looked but cannot find how to seperate the 2 without having each side caught in a loop of it’s own. Is it possible to have the 2 sensors working at the same time? I can do one at a time with no problem but that wont accomplish the desired task.
Thanks for the response! Given the fact that we have a whole 5 months experience, and only about 3 months experience with RobotC I’m still at a little bit of a loss. Some sample code (even for different sensors running in the same loop) would be super helpful! Prior to the teams programmer having an anxiety attack at our first competition and quiting the team I had not written a single line of code in over 20 years so I have a ton of cob webs to clear out!
I have been able to take the samples that JPearman has given me and master them enough to show them to my son who has written some nice encoder based routines but he has been too busy with the build to ask questions or try and figure it out himself.
bool leftExit = false;
bool rightExit = false;
while((leftExit == false) || (rightExit == false)) { // while the left OR right side is not on target, do the following
if(SensorValue[LeftEncoder] > goalValue) { motor[left] = -127; leftExit == false; } // we're not on target, so set the motor to go backwards and reset the leftExit variable back to false
if(Sensorvalue[LeftEncoder] < goalValue) { motor[left] = 127; leftExit == false; }
else { motor[left] = 0; leftExit = true; } // we're on target, so the left side is OK to exit
if(SensorValue[RightEncoder] > goalValue) { motor[right] = -127; rightExit == false; } // we're not on target, so set the motor to go backwards and reset the leftExit variable back to false
if(Sensorvalue[RightEncoder] < goalValue) { motor[right] = 127; rightExit == false; }
else { motor[right] = 0; rightExit = true; } // we're on target, so the right side is OK to exit
}
Basically, you create one while loop that sees whether both sides are on target (by using the leftExit or rightExit boolean). Inside the while loop is your standard motor control. You can adapt it however you want, using PID if you’d like. I didn’t include it because it’s not necessary to show you how to achieve what you’re asking here.
Here is the code I actually use: (the one above should be less confusing)
This code uses rudimentary tolerance control. I didn’t need to mess with refining a PID controller because what I have works. Besides, ain’t nobody got time fo dat. (jk, you should do PID if you have the time)
Quite possible, but there are many ways to skin a cat. You need to decide what you want the code to do before figuring out how to do it. Do you want to control motor speed or simply stop left and right at different times. Or you count rotate the robot until both sonars were reading the same distance.
Here is some code to get you going. First, not what you want to do but here is the function from our programming skills robot that we used to drive forwards a distance based on sonar readings.
A couple of features to note. It can drive forwards or backwards, driving is based on an offset from the current position. There is a timeout of DEFAULT_DRIVE_TIMEOUT (which was set to 2.5 seconds) so that we did not get blocked here if the sonar was not working.
So one way to achieve what you want may be something like this.
// placeholder, use slew rate control in reality
void
SetMotor( tMotor port, int speed )
{
motor port ] = speed;
}
void
DriveToTroughSonar( )
{
long cur_left_position;
long cur_right_position;
long currentTime;
cur_left_position = SensorValue LeftSonar ];
// already there
if( cur_left_position < 15 )
return;
// Start driving - assume forwards
SetMotor( LeftMotor, 100 );
SetMotor( RightMotor, 100 );
// wait for end - 5 seconds maximum
for( currentTime = nSysTime; currentTime > (nSysTime - 5000);)
{
cur_left_position = SensorValue LeftSonar ];
cur_right_position = SensorValue RightSonar ];
// at 15cm stop
if( cur_left_position < 15 )
SetMotor( LeftMotor, 0 );
if( cur_right_position < 15 )
SetMotor( RightMotor, 0 );
if( (cur_left_position < 15 ) && (cur_right_position < 15 ))
break;
wait1Msec(10);
}
// in case of timeout
SetMotor( LeftMotor, 0 );
SetMotor( RightMotor, 0 );
}
Start driving, check both sonars, stop left side and right side independently.
Another way.
// placeholder, use slew rate control in reality
void
SetMotor( tMotor port, int speed )
{
motor port ] = speed;
}
void
DriveToTroughSonar( )
{
long cur_left_position;
long cur_right_position;
long currentTime;
long sonar_diff;
cur_left_position = SensorValue LeftSonar ];
// already there
if( cur_left_position < 15 )
return;
// Start driving - assume forwards
SetMotor( LeftMotor, 100 );
SetMotor( RightMotor, 100 );
// wait for end - 5 seconds maximum
for( currentTime = nSysTime; currentTime > (nSysTime - 5000);)
{
cur_left_position = SensorValue LeftSonar ];
// stop at 15cm stop
if( cur_left_position < 15 )
break;
wait1Msec(10);
}
// Stop motors
SetMotor( LeftMotor, 0 );
SetMotor( RightMotor, 0 );
// Now rotate
for( currentTime = nSysTime; currentTime > (nSysTime - 5000);)
{
cur_left_position = SensorValue LeftSonar ];
cur_right_position = SensorValue RightSonar ];
sonar_diff = cur_left_position - cur_right_position;
// are we close enough?
if( abs(sonar_diff) < 2 )
break;
if( sonar_diff > 0 )
{
// left larger - rotate right
SetMotor( LeftMotor, 30 );
SetMotor( RightMotor, -30 );
}
else
{
// right larger - rotate left
SetMotor( LeftMotor, -30 );
SetMotor( RightMotor, 30 );
}
wait1Msec(10);
}
// Stop motors
SetMotor( LeftMotor, 0 );
SetMotor( RightMotor, 0 );
}
This drives forward and then rotates to align with the trough.
I did not test either of these functions so use with caution. Sonar was set to cm not inches.
Have you experienced this? I’ve used two before and never had any problems, although they were not pointing in the same direction. The Ultrasonic sensors are polled approximately 20 times per second but that varies depending on the distance. After the ping is initiated, the receiver will wait up to about 36mS for a reply, there is a delay of 50mS before the next ping. Each ultrasonic is polled in turn so with two sensors each will be updated about 10 times per second.
I have experienced this although they were facing in the same direction which was likely the problem in hindsight. I haven’t used the sonar sensors since last year so I don’t have any recent experience with them.
Here is what I have been trying, it seems as though both sensors have to be on target for it to stop, it does not control the wheels independently. I can wave my hand over either sensor and nothing happens, but if I wave over both then it stops. I am trying to get the 2 sides seperated so it will square up at the trough.
You are turning right, left motors at 63, right motors at -63. The first while loop ends, next the first sonar loop starts, you put the left motors at -63 BUT the right motors are still running at -63 as well so the robot backs up. The test says do that while the sonar is grater than 2, which is probably is, so the loop never ends unless you wave your hand. See if you can fix it, otherwise I will look at it again later.
Yes, I guess the code I posted yesterday didn’t help. I need to eat dinner now but let me try again with your code, I will post something for you later.
Thanks to both of you! I will try what was posted, but to be honest yesterdays code lost me a bit. To be honest we probably should have started with easyC with no more experience then we have in programming, but we are gradually working through it and have gotten a good handle on what has been taught to us so far.
Once we get past worlds we will be taking some time to try and learn the ins and outs of RobotC so we can work through more issues on our own.
This is my own personal opinion but honestly I really don’t see how "Easy"C is any easier than RobotC. The thing that people tend to have the toughest time with is thinking through step-by-step what the code is going to do, not typing vs dragging commands. I really don’t think that the right mentality is any easier to learn in one environment or another - it just takes some patience to learn things.
How far from the trough do you want the sonars to be? They don’t work that well close up, you had two inches in the code, are they really going to be that close? Are you starting further away than the final desired distance ?
We stuck 2" in as a random number to change later. We will be around 36" from the trough to begin with but will need to get pretty close since the robot is a “back dumper”. When we get to a field where we can test the finished code we will adjust the number accordingly. I am sure there will be some over-run so we will need to make that number bigger. We are toying with the idea of using encoders to get us about 5 or 6 inches away and then using the sonar at a lower travel speed to close in on the trough.
I tried Daniels code and it compiled after I added some braces. It still shuts down both motors with either sensor being close enough, I am sure I have missed something that would be simple to one with more knowledge than myself, but I can’t seem to get a handle on it. Below is what I have.