How to make my robot move along a rectangular path along a black ribbon?

I work on a robot, it is part of the summer workshop of robotics in our college. We use C-STAMP microcontrollers from A-WIT. I was able to make him move, turn left, turn right, move back. I even managed to do this on a black tape using a contrast sensor.

I send the robot 30-45 degrees towards the black ribbon on the table, and it aligns and begins to move along the black ribbon. This twitches a bit, maybe due to my programming logic below, it starts a while loop and constantly checks if-statements, so it tries to try turning left and right every few milliseconds, which explains the shaking part. But everything is in order, it works, not as smoothly as I want it to work, but it works! The problem is that I can not get my robot to go along the rectangular path of the black ribbon. As soon as he reaches the corner of the black ribbon, he just keeps going straight, instead of turning left or right.

My 2 sensors are located directly below the robot, next to the front wheel, almost at floor level. It has a value of "index" in the range from 0 to 8. Eight is the brightest contrast, and zero is the darkest contrast. Therefore, when the robot enters the zone of the black ribbon, the index value drops, and on the basis of this, I have an if statement telling my robot to either turn left or right.

Here is my attempt. To avoid confusion, I did not publish the entire source code, but only the logical part responsible for moving my robot along the black tape.

while(1) { // don't worry about these. // 10 and 9 represent Sensor PIN location on the motherboard V = ANALOGIN(10, 1, 0, 0, 0); V2 = ANALOGIN(9, 1, 0, 0, 0); // i got this "formula" from the example in my Manual. // V stands for voltage of the sensor. // it gives me the index value of the sensor. 0 = darkest, 8 = lightest. index = ((-(V - 5) / 5) * 8 + 0.5); index2 = ((-(V2 - 5) / 5) * 8 + 0.5); // i've tweaked the position of the sensors so index > 7 is just right number. // the robot will move anywhere on the table just fine with index > 7. // as soon as it drops to or below 7 (ie finds black tape), the robot will // either turn left or right and then go forward. // lp & rp represent left-wheel pin and right-wheel pin, 1 means run forever. // if i change it from 1 to 100, it will go forward for 100ms. if (index > 7 && index2 > 7) goForward(lp, rp, 1); if (index <= 7) { turnLeft(lp, rp, 1); goForward(lp, rp, 1); // this is the tricky part. i've added this code last minute // trying to make my robot turn, but i didn't work. if (index > 4) { turnLeft(lp, rp, 1); goForward(lp, rp, 1); } } else if (index2 <= 7) { turnRight(lp, rp, 1); goForward(lp, rp, 1); // this is also the last minute addition. it same code as above // but it for the 2nd sensor. if (index2 > 4) { turnRight(lp, rp, 1); goForward(lp, rp, 1); } } } 

I spent all day trying to figure it out. I pretty much exhausted all the possibilities. Asking for a solution in stackoverflow is my last option.

Thanks in advance! If you have any questions about the code, let me know, but the comments should be clear.

This is my goForward function if someone is wondering:

 void goForward(BYTE lp, BYTE rp, WORD t) { WORD i; for(i = 0; i < t; i = i + 1){ PULSOUT(lp, 400, 1, 1); PULSOUT(rp, 800, 1, 1); PAUSE(17); } } 

UPDATE: this is what I have come up with so far. I deleted all my if statements I posted earlier and decided to write the logic from scratch:

 // if there enough bright light in both sensors at the same time // robot will move forward forever. if (index > 7 && index2 > 7) goForward(lp, rp, 1); // but if there not enough bright light anymore (ie reached black tape) // proceed to the else-statement. else { // if left sensor detects the black tape then turn right // if doesn't detect the black tape then keep going forward if (index2 <= 7) turnRight(lp, rp, 1); else goForward(lp, rp, 1); // if right sensor detects the black tape then turn left // if it doesn't detect the black tape then keep going forward if (index <= 7) turnLeft(lp, rp, 1); else goForward(lp, rp, 1); } // The reason for turnLeft and turnRight is to keep robot re-alligning // to the black tape. It will happen so fast (every 1ms) that the jerking // shouldn't even be noticeable. 
+4
source share
5 answers

You need to catch the sudden appearance: [cycle n] “I see the tape” → [cycle n + 1] “I do not see the tape”, which occurs when you encounter an angle.

A state machine is a good way to deal with this type of problem. Since the state machine code for a certain state is isolated, it runs only when the state is true. This isolation prevents “cross talk” and gives you one known code block for each state.

Given your example, a stream might look something like this:

 :Loop State == Moving forward and on tape. read sensors delta = abs(valueLastCycle - valueThisCycle); if (delta >= bigChangeValue){ // the tape was just gone. // change state and handle this situation. CurrentState = suddenValueChange; }else if (index <= 7) { turnLeft(lp, rp, 1); goForward(lp, rp, 1); else if (index2 <= 7) { turnRight(lp, rp, 1); goForward(lp, rp, 1); } ... State == suddenValueChange ... code that handles sudden value change event maybe: Stop Robot; Move backwards slowly until on tape or distance x etc... Goto Loop 

Increasing the scanning speed may seem useful ... but the faster the robot moves the scanning speed faster ... i.e. You can still jump from tape to tape → from tape, in which case your current code is violated.

+3
source

I assume goForward immediately after turnLeft / TurnRight "cancels" the turn? It depends on how the tinting is done, although

+2
source

Is your while loop fast enough to catch an angle? If both sensors report that they are on the tape, and in the next cycle both sensors are disconnected from the tape, you cannot detect this, right? Does the sensor report the same values ​​(8) that they are on the tape and on the tape?

Try to make your code faster. Not seeing all the code, it's hard to make a recommendation, but it looks like you can evaluate if statements are needed. Add an ELSE after the first IF as soon as you find out that you are going straight.

Your fast implementation seems to block the loop for too long. 1 does not mean running forever, it does one for-loop pass, and then you PAUSE 17 (msec?). Why PAUSE? Take it away. This probably causes jerking and prevents the next set of sensor values ​​from getting into.

+2
source

Make sure your “plan” makes sense before worrying about code.

Start by moving the robot manually and observing when the sensors pass through black and white areas. Try to come up with a behavior and simulate it manually. If this does not work as you need, you need to reconsider the behavior.

Sentence. You might want to add a few more cycles to make sure that if something seems wrong, the robot corrects itself before resuming normal behavior. (For example, instead of turning left / right 100 ms, do this if you want the sensors to see the right thing.)

+2
source

Right now, in the look of your code, every time a robot sees black, it advances forever. I'm not quite sure how it is moving forward.

In pseudo code, your code says:

 if you see black go forward forever if you don't see black turn left or right 

Do you see how your robot will move forward forever with such logic? Again, I have no idea how it is moving forward, so I could be wrong.

+1
source

Source: https://habr.com/ru/post/1312503/


All Articles