Adding IR sensor GP2D12 to Xan's code

Ok, so i have my sensor working with this script:

[code]’ ----- Program Description ]---------------------------------------------

’ This program demonstrates how to read the Sharp GP2D12 infrared analog output
’ detector with an Atom module and display the results in a terminal window.
’ Hardware Connections:

’ Atom Module Sharp Sensor
’ ------ --------------------------------
’ P16 Pin 1

'----- Variables ]------------------------------------------------------------

scanrange var word ’ A/D result variable
floating var float ’ Floating point math result storage
val var byte ’ Table conversion result storage

'---- Table Setup ] ----------------------------------------------------------

scantable bytetable 80,80,80,80,80,80,80,80,80,78, |
76,74,72,70,68,66,64,62,60,59, |
58,57,55,53,52,51,50,49,48,47, |
45,43,42,41,40,39,38,37,35,33, |
32,31,30,30,29,29,28,28,27,27, |
26,26,26,25,25,25,24,24,24,23, |
23,22,22,21,21,20,20,20,19,19, |
18,18,18,17,17,16,16,16,15,15, |
15,14,14,13,13,13,12,12,11,11, |
11,10,10,10,10,10,10,10,10,10

'---- Main Loop ] -----------------------------------------------------------

main

adin P19,scanrange ’ Read sensor value
if scanrange > 512 then ’ Test for obstacle to close to detector
serout s_out,I38400,“Too Close To Measure”, 13] ’ Send “Too Close” message
else
floating = tofloat( scanrange) / 5.12 ’ Limit value to <200 values
val = scantable(toint floating) ’ Convert A/D to measurement
debug [REAL floating," “,DEC val,13] ’ Output result to debug window
serout S_OUT,i38400,[REAL floating\2,” - “,DEC val,” cm",13]
endif ’ End If-Then-Else command
goto main ’ Loop back and get another reading[/code]

Now i want to add it in Xan’s code. I tried putting it right above the PS2 code but then it doesn’t react to the ps2 controller anymore.

I want the the hexapod to move back (legs stand still an body moves) when for example my hand goes forward. So about 30cm in between(all the time)

And then i want to make the bot STOP when there is something in the way. About 35cm

The rest of the code except the peace below, is already implemented. Now i just need to know where to put the code so it does it’s job without bugging the ps2 control.

[code] '---- Table Setup ] ----------------------------------------------------------

scantable bytetable 80,80,80,80,80,80,80,80,80,78, |
76,74,72,70,68,66,64,62,60,59, |
58,57,55,53,52,51,50,49,48,47, |
45,43,42,41,40,39,38,37,35,33, |
32,31,30,30,29,29,28,28,27,27, |
26,26,26,25,25,25,24,24,24,23, |
23,22,22,21,21,20,20,20,19,19, |
18,18,18,17,17,16,16,16,15,15, |
15,14,14,13,13,13,12,12,11,11, |
11,10,10,10,10,10,10,10,10,10

s_out,I38400,[TotalYBal = -10, 13] ’ Send “Too Close” message
else
floating = tofloat( scanrange) / 5.12 ’ Limit value to <200 values
val = scantable(toint floating) ’ Convert A/D to measurement
debug [REA; [SENSOR DATA CALCULATION]
SensorInput:
adin P19,scanrange ’ Read sensor value
if scanrange > 300 then ’ Test for obstacle to close to detector default and max =512
seroutL floating," “,DEC val,13] ’ Output result to debug window
serout S_OUT,i38400,[REAL floating\2,” - “,DEC val,” cm",13]
PAUSE 500
SOUND P9,[50\500]
endif [/code]

Hi Mano,

You are now in the fun part of figuring out how to make your code to work. What I have done with similar code for the rover was to first make the IR code into a subroutine. Mine looks like:

; This table is used to convert Sharp IR readings into CM
IRCMTable bytetable     80,80,80,80,80,80,80,80,80,78, | 
                        76,74,72,70,68,66,64,62,60,59, | 
                        58,57,55,53,52,51,50,49,48,47, | 
                        45,43,42,41,40,39,38,37,35,33, | 
                        32,31,30,30,29,29,28,28,27,27, | 
                        26,26,26,25,25,25,24,24,24,23, | 
                        23,22,22,21,21,20,20,20,19,19, | 
                        18,18,18,17,17,16,16,16,15,15, | 
                        15,14,14,13,13,13,12,12,11,11, | 
                        11,10,10,10,10,10,10,10,10,10 
;--------------------------------------------------------------------
;[GetIRSensorInCM]
IRPin		var byte
scanrange 	var word                 ' A/D result variable 


GetIRScanInCM[IRPIN]
                        
	; first read in the IRvalue.
	adin IRPin,scanrange
	
	; If it is greater than 512 it is out of range we will return 0
	IF scanrange > 512 THEN		; outside our table so return 0 to signal too close 
		return 0
	ENDIF 
	
	; now convert entry to cm from table.  Old program
	; divided value by 5.12 using floating point, but could simply multiply by 100 and divide by 512
	; in integer math, which should be a lot quicker.  512*100 < 65536 so fits in word...
	return IRCMTable((scanrange*100)/512)

Note: the code is more or less the same, I just got rid of the floating point. I also coded it with an input parameter of which pin I wanted to check as I may want to add multiple sensors…

When I want to use it, I use a gosub that looks like:

gosub GetIRScanInCM[IRSensorPin], IRDistance

Now how to integrate it, may take you awhile to figure out how to do it cleanly, which I don’t have the time to fully figure out for you, but should be fun. I will try to outline one approach to make it work, but there are a lot of other things you will need to think about.

Maybe choose an unused PS2 button like the cross button, that when you press it, you enter into a special mode. This could be as simple as toggeling a variable. You may want to consider how other buttons interact with this. For example if in this special mode and the user hits the start button, will you process it and turn on or off…

Change the main loop? Not sure what you are trying to do here, Use the current gait? Do some canned functions? If canned calls to Movement, you need to figure out how to disable the main code in the loop and call off to your movement routines. If you want it to do the movements with the current gait, maybe you don’t change it here, maybe you hack it into the PS2 input function. You probably mainly need to change the values of: TravelLengthX and TravelLengthZ and TravelRotationY.

The later part of the PS2 input function could do something like:

...
	ELSEIF (DualShock(2).bit0 = 0) 	;L2 Button test
	  BodyRotX = (Dualshock(6) - 128)/8
	  BodyRotY = (Dualshock(3) - 128)/6
	  BodyRotZ = (Dualshock(5) - 128)/8
	  BodyYShift = (-(Dualshock(4) - 128)/2)MIN-(BodyPosY-10)
	ELSEIF IRInputMode <> 0 ; we are in the IR mode
                  gosub GetIRScanInCM[IRSensorPin], IRDistance
                  ; compute what you want these values to be...
                  ; based on the value of IRDistance.
                  ; ****** TBD: ???????????? ***************				
	ELSE ;Walk
...

But remember this is just an outline of one possible solution. I hope you have fun!!!

Good Luck
Kurt

Thanks a lot Kurte.

I’m ill at the moment so i have plenty of time to have fun with it…
I do enjoy this part too…

By the way;

Is there a topic about the ps2 codes? I have on the left of my comtroller, up/down, but what about left and right? I want to use those.
But then i need the bits and stuff. Never been there…

I can’t get this to work…

I want the hexapod to move back when i come close, and forward when i move back. This is working fine.

Now i want him to stop at “BodyPosZ=0” So he can follow my obstacle but does not go further forward then 0.

Can someone help me with this? Below the code i wrote untill now.

SensorInput: adin P19,scanrange ' Read sensor value if scanrange > 300 then ' Test for obstacle to close to detector default and max =512 BodyPosZ = BodyPosZ-2 ' Move back Sound P9,[20\400] else if scanrange < 300 then BodyPosZ = BodyPosZ+2 'Move Front floating = tofloat( scanrange) / 5.12 ' Limit value to <200 values val = scantable(toint floating) ' Convert A/D to measurement debug [REAL floating," ",DEC val,13] ' Output result to debug window serout S_OUT,i38400,[REAL floating\2," - ",DEC val," cm",13] else IF BodyPosZ > 0 then BodyPosZ = 0 ENDIF ENDIF ENDIF

Hi Mano,

I hope you are fealing better.

As I mentioned in a previous post, this type of question may be hard to answer without having to spend a lot of time understanding how the current code is written and figuring out exactly what you want to do and how it fits in with the program… So the best you can probably hope for is some hints…

The code you included below loos like a complete hodge podge of stuff. It looks like you still have some of the stuff to convert the raw input from the adin into CM, yet it looks like for the most part you are not using that. So you should clean that stuff out of there .

Then you need to understand the different coordinate systems of the phoenix program. For example what is the difference between the variables BodyPosX/BodyPosZ versus TravelLengthX/TravelLengthZ? When the sensor sees something do you simply want it to move it’s body or walk? My guess is that depending on which you wish to do, may dictate which set of variables you wish to change.

So looking at the code you pasted, minus some stuff you have:

SensorInput: adin P19,scanrange ' Read sensor value if scanrange > 300 then BodyPosZ = BodyPosZ-2 ' Move back else if scanrange < 300 then BodyPosZ = BodyPosZ+2 'Move Front else IF BodyPosZ > 0 then BodyPosZ = 0 ENDIF ENDIF ENDIF
Some of this ifs and elses don’t make much sense. For example the 2nd else can only happn if scanrange is exactly 300, which is not what I think you wanted.

Assuming that using BodyPosZ is the right thing to use and that its coordinate system remains the same and for example if you want the body to move back when something gets too close and if it goes away you wish for the body to move back to center and stop at the center point of zero, then the code maybe should look something like:

SensorInput: adin P19,scanrange ' Read sensor value if scanrange > 300 then BodyPosZ = BodyPosZ-2 ' Move back if BodyPosZ < -42 then ; about the limit joystick code had... BodyPosZ = -42 endif elseif BodyPosZ < 0 ; scanrange is <=300 so start going back BodyPosZ = BodyPosZ+2 'Move Front ENDIF ENDIF

But again I am just guessing. Got to go.

Kurt

Thanx Kurt, This whas exactly what i needed.

again, Thank you!

will you be posting the Full code once you have worked things out. might get alot of interest with this. myself included! :wink:

Good luck.

Yeah Sure! If i can find the code to make the bot “stop” I’m practicly done…

LOL.
Are your intentions to run the bot semi-autonomously or Full Autonomy?
semi meaning you control its movements intill it detects and object
and it then reacts to it in the way you intend or does it just work
like an agent.

i think using the best of both worlds is better. using a mode switch
command to change between the two!

That will be the case but just figuring out the sensor. One step at a time hahah. if you might have any tips i would love to hear them.

I have a very nice “home” button on my remote. I want to use that to put the hexapod into autonomous mode.

Have got an idea how to make the bot stop in xan’s code?

what do you mean by “stop”?
usually no interaction with the remote works for me.
gotta let go of them sticks man. :laughing:

mode select might look like this:

IF "DualShock" THEN IF SensorInput = 0 THEN SensorInput = 1 sound P9,[100\4000] ELSE SensorInput = 0 sound P9,[550\1000] ENDIF ENDIF
or to that effect.

well i feel we may live on different corners of the globe (me UK) so its my turn to sleep but i will be back on tomorrow night at some point.
:wink:

I want the bot to stop from bumping into a moving object like a cat or so…
So it must stop while walking.

i’m living in the netherlands so not so far away :wink:

Just a night creature…

Thanx for the code!

If you want it to stop, you can probably just set

TravelLengthX = 0 TravelLengthZ = 0 TravelRotationY = 0
You might also want to set some of the BodyPosX/Z… values as well.
If you want to sledge hammer approach you could emulate the Start button being pressed… See the processing of it in the PS2Input function.

Kurt

I tried this:

IF scanrange > 5 then TravelLengthZ = 0 ENDIF

But that didn’t work.

Any other options? Or whas it maaybe the way i put it together?

Is TravelLengthZ the variable the program uses to move the robot forward/backward?

Also, debugging would help. when I have a problem with a program, I usually output information to the debug window to see whats really going on inside the program.

Also, in your the first post you say that you left out this block of code:

  '---- Table Setup ] ----------------------------------------------------------

scantable bytetable     80,80,80,80,80,80,80,80,80,78, |
                        76,74,72,70,68,66,64,62,60,59, |
                        58,57,55,53,52,51,50,49,48,47, |
                        45,43,42,41,40,39,38,37,35,33, |
                        32,31,30,30,29,29,28,28,27,27, |
                        26,26,26,25,25,25,24,24,24,23, |
                        23,22,22,21,21,20,20,20,19,19, |
                        18,18,18,17,17,16,16,16,15,15, |
                        15,14,14,13,13,13,12,12,11,11, |
                        11,10,10,10,10,10,10,10,10,10
 

You need this code in order for the sensor to measure properly.

Brandon

I can’t remember me sayin’ that i left that block out, but if i did, i lied.

I’t still in there, right above the rest of the script.

Yes travelleengthZ is for going for- and back-wards.

Ok i’m done! Well, it might be a bit smoother, so any help is welcome…

I didn’t get it to actually stop. But then i thought of what i intended to do next and that is walking back with slight rotation.

So it will mve the body backwards and walk backwards at the same time.(rather had it seperate, any tips?) and when object is out of sight the body position returns to 0.

This can be put in the “VAR BYTE” section above ;GAIT

scanrange var word ' A/D result variable floating var float ' Floating point math result storage val var byte ' Table conversion result storage

And this code must be placed under the “;R2 Button test” section

; [SENSOR DATA CALCULATION] SensorInput: adin P19,scanrange ' Read sensor value IF scanrange > 150 then GaitType = 1 TravelrotationY = 15 TravelLengthZ = 50 NomGaitSpeed = 90 ENDIF if scanrange > 200 then BodyPosZ = BodyPosZ-4 ' Move back if BodyPosZ < -42 then ; about the limit joystick code had... BodyPosZ = -42 endif elseif BodyPosZ < 0 ; scanrange is <=300 so start going back BodyPosZ = BodyPosZ+4 'Move Front ENDIF

Maybe this code can be added to:

lynxmotion.net/viewtopic.php?p=46797#46797

Xan: If you’d like to use this code to implement it in your code…YES PLEASE. I think there are a lot more people who are using this sensor…

For the rest i’d like to thank everyone who helped me out bigtime

Think you could create some cool youtube video? Sounds interesting! Bet lots would like to see the end result. :wink:

*EDIT

seemed like the table wasn’t nessesary at all. Is only for conversion to cm.

I will post a video as soon as possible.