Shop OBEX P1 Docs P2 Docs Learn Events
Help with robot — Parallax Forums

Help with robot

geoldrgeoldr Posts: 15
edited 2008-11-26 00:27 in BASIC Stamp
Hi, so here is the problem. I am using a Basic Stamp 2, and 2 servos and more things to control a car robot. It's kind of like a boe bot I guess, but its a truck. The BOE is mounted on the roof with all the IR sensors positioned just right so they look beyond the hood. I have batteries mounted on the back. Anyways here is the problem ( I will attach code). The car is made to turn left when the right sensor detects something. And if both sensors detect something at the same time, it needs to move back. This all works. But not like I want it to work. Here is what I would like, and I am sure with all the BS2 gurus on this website, we will be able to figure something out.

A) When the car detects an object with both left and right sensors it needs to do a U-turn.
- What it is currently doing, is (When both IR sensors are active) is moving back until it stops get detection, this doesnt work, because this causes it to move back for a bit, then move forward again, and it just spaazes out. This is not wanted.

B) Sometimes, when it senses something weird (oh, please note that I have 3 LEDS, 1 for when its turning left, 1 for when its turning right, and 1 for when its moving backwards) say for example the left light starts blinking a lot, which causes the car to spazz left, and not move like it should. What I would like, and I don't know if this is possible, is if it senses things continuously instead of just spazzing out, it should just do a U-Turn.

Please help you guys, I am stumped with this code.

BTW, I can't upload my program, there seems to be a "Server Error". Here it is.

' {$STAMP BS2}
' {$PBASIC 2.5}
' Roaming with IR

irdetectleft VAR Bit
irdetectright VAR Bit
pulseleft VAR Word
pulseright VAR Word
pulsecount VAR Byte

FREQOUT 4, 200, 3000
PAUSE 100
FREQOUT 4, 200, 3000

DO
FREQOUT 8, 1, 38500
irdetectleft = IN9
FREQOUT 2, 1, 38500
irdetectright = IN0
'---------------------

IF (irdetectleft = 0) AND (irdetectright = 0) THEN
HIGH 6
pulseleft = 650
pulseright = 850
ELSEIF (irdetectleft = 0) THEN
HIGH 1
pulseleft = 850
pulseright = 850
ELSEIF (irdetectright = 0) THEN
HIGH 10
pulseleft = 650
pulseleft = 650
ELSE
LOW 6
LOW 1
LOW 10
pulseleft = 850
pulseright = 650
ENDIF

PULSOUT 14, pulseleft
PULSOUT 12, pulseright

LOOP

Comments

  • SRLMSRLM Posts: 5,045
    edited 2008-11-23 03:23
    hmmm. Lost the formatting...

    Anyway, don't forget to refresh the servos every ~20 ms. It looks like you are doing it much faster, and this may result is some of your problems...

    Problem A: sees a wall a head, backs up, goes forward, ... : So, the simplest solution is simple to make one motor go faster when backing up. This will induce some turning action, and eventually it will get away from the wall.

    Problem B: What do you mean by "the left light starts blinking alot". If you want it to sense things continuously and know that it has done so, you want a counter with some code like the psuedo code below:

    IF Object Detected THEN objectCounter++
    ELSE ObjectCounter = 0
  • geoldrgeoldr Posts: 15
    edited 2008-11-23 03:48
    Hello, thank you for your response. For problem A, there is no way for the program to activate a function once it senses an obsticle in front of both IR sensors? And for B, what I mean by that is.. its not like sensing the wall 100% of the time. It like senses it every like .1 second. So basically, as you can see in the code when the left IR senses something, the right light turns on. According to the code, the light will be on 100% of the time as long as its sensing something. What's happening with the code right now, is that instead of the light being on 100% of the time, and continusly turning right, what it does is basically this: left, center, left,center. And same with the light. On, off, on, off, until the object is out of the way. This works, but i prefer it not to be like this. Also, what do you mean by refreshing the servos ?
  • SRLMSRLM Posts: 5,045
    edited 2008-11-23 06:17
    Problem A: A simple if statement will activate some code if both sensors see something

    IF(IN1 = 1 AND IN2 = 1) THEN
    GOSUB activeFunction

    Problem B: So, it sounds like the movement is too jerky... To smooth it out, you'll want a counter variable. Something like the following will "fill in the gaps" of your sensor, so, if your robot were to drive beside a picket fence it would register it as continuous. (Psuedo Code)

    leftCounter Byte

    if leftDetected is true, then leftCounter += 2
    else if leftCounter != 0 then leftCounter --

    'Is an object there?
    if leftCounter > 0 then an object is to the left

    Problem C: Servos should be refreshed every 20 ms. This means that you should pulse them every 20 ms. You can get away with less or more, but ideally, 20ms. It's because you can get away with less or more that you can run code during that 20ms. However, if your code is too short to take up 20 ms of time, then you'll want to add a PAUSE statement to make it up.
  • P!-RoP!-Ro Posts: 1,189
    edited 2008-11-23 06:54
    What I find with the servos is if the refresh rate is too fast, the servos won't go the speed expected. I would advise maybe at least 10ms pause in the spaces to make sure this doesn't happen. If you go longer than 20ms on your pauses, you might have your servo run a little slower, but that is OK too.

    As for your robot being jerky, that is because you have it set so the robot only turns when it sees an object. With IR being so inaccurate and sometimes missing objects, sometimes it will go back to trying to go straight before realizing it is still in the way of the object. This would make it very jerky. Try giving it a loop until command with 20ms pauses to make it turn a little farther before checking the sensors again.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pi Guy
  • geoldrgeoldr Posts: 15
    edited 2008-11-23 07:28
    Thank you everyone for the help, I have currently added a counter for the turning. It seems to be working OK so far. Less jerky, but in the same areas of my house its still having similar problems. How do I program in my servo refresh rate? You guys keep talking about it, and I have no clue what it is. Like a pause 20 at the end of the program?

    Also SRLM, I see you have the PING module, how is it? Is it better than the IR sensors?
  • SRLMSRLM Posts: 5,045
    edited 2008-11-23 15:55
    Have you checked your fluorescent lighting? Sometimes that can interfere with the IR receiver. Take a look in the BOE-BOT book to see how. It could be a cause (or a help towards) some of the robot jerkiness.

    To program the servo refresh rate, you'll want to figure out how long each block of code takes, then do a pause of 20 ms - timeInCode. If memory serves me right, the BS2 does 4000 commands a second, or 4 commands a ms. So count up the commands (and don't forget things in the output that take time), and get an average of how long your code takes. Don't forget that it will never do all the if-else statements in one loop, rather, it will choose one and do it (so you only need to count one section). This counting is a very aproximate solution, so don't stress too hard for it. Then just add a PAUSE somewhere in your code (the logical place is at the pulseouts, but it doesn't really matter a whole lot.)

    I quite like the ping, especially on a servo. It has a wider range of operating areas (indoors, out, fluorescent, incandescent) and it has a longer range. That said, it much more expensive than IR sensors and not as good for low cost applications.
  • P!-RoP!-Ro Posts: 1,189
    edited 2008-11-23 19:29
    Also, if you still plan to use the ir sensors instead of spending $30 on a Ping, something else you could do to improve the accuracy of your sensors it to have it check for objects 2+ times in the 20ms time period. If one of those times it detects an object, weather the second+ time detected it or not, it would still turn. This would help prevent jerkiness. Also, if you have fluorescent lighting, try placing something over the detector to shade it from the light.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pi Guy
  • geoldrgeoldr Posts: 15
    edited 2008-11-23 23:02
    Well, I am probably going to get a PING sensor, and how do you mean to check twice? What would I have to do to the code I posted above? Add another if statement into the if statement?
  • P!-RoP!-Ro Posts: 1,189
    edited 2008-11-26 00:27
    Sometimes the sensor will miss an object one time then the second time will pick it up again. This is the nature of ir, which is unpredictable and can vary from angle and object color, just like sonar doesn't work with some angles and objects that absorb sound. Because of this you just have to find a way to work around the sensor. To do this with ir, you can try this:

    irdetectleft = 0 
    irdetectright = 0 
    do x + 1 
    FREQOUT 8, 1, 38500 
    irdetectleft + IN9 
    FREQOUT 2, 1, 38500 
    irdetectright + IN0 
    loop until x = 2 
    
    IF (irdetectleft = 0) AND (irdetectright = 0) THEN...
    

    If there is a mistake in the code, please forgive me. I haven't programmed the BS2 in a while. Basically, though, what it should do is just check the sensor twice to make sure it didn't miss the object the first time. If you still have jerky problems, you could even space out the different checks with a pause command in-between or add more checks. Remember, you have 20ms to work with before you have to refresh the servos.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pi Guy
Sign In or Register to comment.