Welcome to Synthiam!

Program robots using technologies created from industry experts. ARC is our free-to-use robot programming software that makes features like vision recognition, navigation and artificial intelligence easy.

Get Started
United Kingdom
Asked — Edited

Ir Object Avoidance

Another script I've been writing is for the IR object avoidance as the built in control for IR doesn't work correctly with my IR sensor. I'm also trying to get to grips with EZ-Script so playing around is always a great idea in my book.

Adjust and/or comment on as you see fit. I've written it so it can be easily adjusted to suit your settings (and to show how variables can be used to make for easy adjustment over different projects/people)

Code:


# IR Detector Script
# Object avoidance using IR sensor on ADC port

# Adjust values below for configuration
$iradcport = ADC6 # Change for ADC Port with sensor attached
$maxirdistance = 35 # Change for maximum distance from object before avoiding in units
$irreverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$irturndirection = 0 # Change 0 = left or 1 = right
$irturnamount = 500 # Change for how long to turn for in ms
$irreverseamount = 500 # Change for how long to reverse for in ms (if applicable)
$irmovementspeed = 255 # Change for movement speed


# -- Do not modify below this line --
Goto(detect)

:avoid
IF ($irreverseturn = 1)
reverse($irmovementspeed,$irreverseamount)
ELSEIF ($irturndirection = 0)
Left($irmovementspeed,$irturnamount)
ELSE
Right($irmovementspeed,$irturnamount)
ENDIF
Return()

:detect
$currirdistance = GetADC($iradcport)
IF ($currirdistance >= $maxirdistance)
Goto(avoid)
ENDIF
Sleep (50)
Goto(detect)


Also available on the EZ-Cloud here

AI Support Bot
Related Content
Synthiam
United Kingdom
#1  
The :Detect should be a label called detect but I guess the forum thought putting the d next to a : meant I was grinning;)
Canada
#7  
Rich, is it much work to make this script for two IR, one for each side, on a 45 facing in for a full view? Thanks. I have been trying. and im still new. lol, Thanks
#8  
Here's an example for 3 IR units and a front bump switch with thanks from Rich:

Code:

# Three IR units, Left_IR, Center_IR, and Right_IR will
# be monitored for possible collision from objects in
# front of a moving robot. If those IR units fail to
# detect then the single bump sensor will activate on
# a collision.

# Once detected then drive motor control will be adjusted
# to avoid collision

# Normal values for an ADC port are from 0 to 255
# Collision value should be 100 or less
$Collision = 100

# Any value below 100 will indicate a possible collision
# Also the robot is set to move Forward at a speed of 60
# Speed can be 0 - 255

# Read the port values of the 3 IR units as well as the
# one bumper sensor.

:Read_ADC
Forward(60)

$Read_Center_IR = GetADC(ADC0)
$Read_Left_IR = GetADC(ADC1)
$Read_Right_IR = GetADC(ADC2)
$Read_Bump = GetDigital(D8)

print(GetDigital(D8))
print(GetADC(ADC0))
print(GetADC(ADC1))
print(GetADC(ADC2))

IF ($Read_Left_IR <= $Collision)
Stop()
Goto(Avoid)

Elseif ($Read_Center_IR <= $Collision)
Stop()
Goto(Avoid)

Elseif ($Read_Right_IR <= $Collision)
Stop()
Goto(Avoid)

Elseif ($Read_Bump = 0)
Stop()
Goto(Avoid)
EndIf

GoTo(Read_ADC)

#Avoid subroutine
:Avoid
Reverse(60,500)
Left(60, 500)
#print(GetADC(ADC0))
#print(GetADC(ADC1))
#print(GetADC(ADC2))
#Sleep(200)
Return()
United Kingdom
#10  

Code:


# IR Detector Script
# Object avoidance using 2 IR sensors on 2 ADC ports

# Adjust values below for configuration
$iradcport1 = ADC6 # Change for ADC Port with sensor 1 attached
$iradcport2 = ADC7 # Change for ADC Port with sensor 2 attached
$maxirdistance = 35 # Change for maximum distance from object before avoiding in units
$ironlyforward = 0 # Only if moving forwards? 0 = no, 1 = yes
$irreverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$irturndirection = 0 # Change 0 = left or 1 = right
$irturnamount = 500 # Change for how long to turn for in ms
$irreverseamount = 500 # Change for how long to reverse for in ms (if applicable)
$irmovementspeed = 255 # Change for movement speed


# -- Do not modify below this line --

# The detection script
:detect
IF ($ironlyforward = 1)
IF ($Direction = "Forward")
GOTO (detectstart)
ELSE
GOTO (detect)
ENDIF
ELSE
:detectstart
$currirdistance1 = GETADC($iradcport1)
$currirdistance2 = GETADC($iradcport2)
IF ($currirdistance1 >= $maxirdistance OR $currirdistance2 >= $maxirdistance)
GOTO(avoid)
ENDIF
SLEEP (50)
GOTO(detect)
ENDIF

# The avoidance script
:avoid
IF ($irreverseturn = 1)
reverse($irmovementspeed,$irreverseamount)
ENDIF
IF ($irturndirection = 0)
LEFT($irmovementspeed,$irturnamount)
ELSE
RIGHT($irmovementspeed,$irturnamount)
ENDIF
RETURN()


That should do it I think, however it is untested (and I really need to revisit this code to change a few things I dislike about how I wrote it - which don't change how it works, it's just me being picky)

Edit: Or use Robot-Docs script (that'll teach me to post and eat dinner at the same time, I missed the updates...)
Canada
#11  
LoL thanks. I will try it out and see. The more I'm looking at it. The more sense the code makes. LoL know what I mean.
United Kingdom
#12  
Yep, I know exactly what you mean. That is what I try to achieve with my scripts too, hence the comments throughout most of them.

Give it a go, see what happens, I'm usually around to guide you if you get stuck.
Canada
#13  
:D hey Rich it works great. man, thanks, and i know i will be asking a few more questions later
#14  
Is the green face supposed to be:D or D
Is the yellow face supposed to be;) or )
Canada
#15  
green is : D
yellow is " )
Canada
#16  
no spaces, but it might not matter...
United Kingdom
#17  
Yeah, sorry that's an issue with the forum formatting for emoticons.

The:D should be : with a D next to it (no space)
The;) should be " with ) after it (no space) - the forums leave the " so just change the;) for a )

The;) I don't think the space matters but the:D does.

This is why I usually upload to pastebin too but didn't get chance last night.
#18  
Here are some pieces of code that was in servo Mag. You could do it smartly. But, this is all written in RobotBasic and would have to be converted to EZ-Script.

******a subroutine

Action5: // hard left
for i=1 to 10
rForward 1
if rFeel()then break
next
for i=1 to 70
rTurn -1
if rSense() then break
next
return
Action6: // hard right
for i=1 to 10
rForward 1
if rFeel()then break
next
for i=1 to 70
rTurn 1
if rSense() then break
next
return

**************************another sub

Action1: // easy left
rForward 1
rTurn -1
return
Action2: // easy right
rForward 1
rTurn 1
return
Action3: // medium left
rForward 1
rTurn -3
return
Action4: // medium right
rForward 1
rTurn 3
return
Action5: // Hard left
rForward 1
rTurn -6
return
Action6: // Hard right
rForward 1
rTurn 6
return

***************************another sub
main:
gosub Init
while 1
gosub RoamAndObserve
wend
end
RoamAndObserve:
// genetically turn away from walls
if rFeel() then rTurn (140+Random(80))
if rSense()
// something got our attention
gosub ReactAndAnalyze
else
if !rFeel() then rForward 1
endif
return
*******************Next program below

ReactAndAnalyze:
CurState = rSense()
// see if CurState is in memory
InMemory=false
if NumStates>0
for p=0 to NumStates-1
if GoodState[p]=CurState
InMemory = True
break
endif
next
endif
if InMemory
// react as expected based on past experience
// perform the action associated with the current state
gosub "Action"+ActionToTake[p]
// decide if the action still produces good outcome
NewState = rSense()
Reward=false
if NewState&2 then Reward=True
// Also reward if this NewState is in memory
if !Reward and NumStates>0
for i=0 to NumStates-1
if NewState=GoodState[i]
Reward=True
break
endif
next
endif
if !Reward
// old memory does not seem to be valid
ConfidenceLevel[p]--
if ConfidenceLevel[p]=0
for i=p to NumStates-1 // delete memory
GoodState[i]=GoodState[i+1]
ActionToTake[i]=ActionToTake[i+1]
ConfidenceLevel[i]=ConfidenceLevel[i+1]
next
NumStates--
endif
else
// increase confidence of memory (up to 2)
if ConfidenceLevel[p]<3 then ConfidenceLevel[p]++
endif
else
// try something new
NewAction = Random(6)+1
gosub "Action"+NewAction
// now see if the New Action produced good results
NewState = rSense()
Reward=false
if NewState&2 then Reward=True // gave direct reward
// Also reward if this NewState is in memory
if !Reward and NumStates>0
for i=0 to NumStates-1
if NewState=GoodState[i]
Reward=True
break
endif
next
endif
if Reward
// good result so add to memory if not there already
// CurState is what initiated this action so add to memory
// NewAction is what we did to get rewarding results
GoodState[NumStates]=CurState
ActionToTake[NumStates]=NewAction
ConfidenceLevel[NumStates]=1
NumStates++
endif
endif
return

Hope that this heled.
United Kingdom
#19  
@Mel, what does that code do? What does it do better than the code posted (or the ping roam code which is a more advanced method than the older IR code posted). And what is "Robot basic"? Any links to the language?
#20  
This code came from RobotBasic and the Robot Programmer's Bonanza, and servo Magazine.

Now, parts of it are just printing stufff on the screen. But, some of it are sniplets of A.I. programming where the robot has a confidense level and stores good moves in memory. Evently, it will become a self-programming robot programmed by it's environment. I would write the code myself, but I am not there yet. Read the article in Oct. 2013 servo magazine. Look at some of the code and you will see what i am talking about. Making intelligent decisions based on past mistakes. It is written in Basic, but could be transferred into EZ-Script, I am guessing. (That's where you or some top notch programmer comes in.) I am not saying that the other programs you wrote were bad. I just put this here to assist the robot to go further with A.I.

When I said "Smartly" I wasn't referring to you. I was referring to the robot. Your code is good and I respect you.
You can download RobotBasic Free and play with it. It does lots of good stuff on the screen, but I want the robot to do it, him or herself.


:)
United Kingdom
#21  
I still don't see why or how it would need to learn. The Ping Roam code, which is the advanced version of this IR code, detects obstructions and moves 100% correctly 100% of the time. There is no learning required, there is no guessing required. Either the obstruction is there or it isn't and the sensor(s) are enough for it to know which direction the obstruction is in.

The currently released version of the Ping Roam is intelligent enough to avoid objects, escape from a boxed in situation by itself and avoid getting stuck in loops bouncing backwards and forwards over the same area. The next version (which is still waiting to be tested properly) has "smart avoidance" where the turns are based on the sensor readings rather than the timings.

In other words, avoidance code shouldn't make a bad decision therefore learning is not required (unless you purposely code it to make bad decisions, which there is no benefit in at all), hence the confusion over why the code was posted as I cannot see it being required.
Canada
#22  
Hey Rich. Any of your ping roam scripts have the ping sensor stationary ? I like the IR code. And used your ping roam for a test bot. I will use the ping roam for my omnibot. But the IR was used in my wall-e. I will attach a picture of my wall-e and wear the sensors are. Need help with the scripts.
User-inserted image
#23  
Well, Rich, they say if it 'aint Broke, don't fix it. If it works good we will leave it alone. I am always trying to get a machine to Learn and demonstrate artificial intelligence. Evidently, this little program doesn't need it. It was just a thought. You did a good job. I am sorry about the confusion.

The link you asked for:

robotBasic

:)
United Kingdom
#24  
Don't get me wrong Mel, it wasn't a complaint or anything along those lines, all input is always welcome:) And thanks for the link, I'll have a look at robotBasic.

@vhs896, This original IR code was for a single fixed sensor. The Ping one hasn't been for fixed since it needs to "look" left and right too. You could adjust it for a fixed ping sensor pretty easily, rather than GetADC() use GetPing() and reverse the If statement (IR works backwards to Ping so any less thans need to be greater than and vice versa)
Canada
#25  
OK. Thanks. I will give it a go. .. I might try and get the ping to swing LoL with a micro servo.
#26  
I have one ping that pans and more will be stationary. All of my IRs do not pan.

@Rich, you are the man!