Rover now has a primitive object finder program

I’ve been working on it all summer and I bet I’m not even half way there :unamused: but, I’m happy to be able start seeing everything finally coming together. :smiley:

Basically the arm is an al5c shortened up in length mounted on the base of a rover chassis on an LPA. Directly umder the LPA I have a panning servo with a Ping Ultrasonic sensor mounted on it. This initially detects the objects of course. On the gripper I have another Ping mounted on the wrist and a 2g buffered accelerometer on top of the gripper that is level when the gripper is pointing directly down.

My code is basically the arm version of the pheonix code with all of the PST input stuff stripped away and senosr input subroutines in their place. I would post my code but right now it looks even worse than the wires on my arm/rover :laughing: I’ll clean it up and comment it later.

Update
Its not as shaky now and I’ve gotten the accuracy up to about 65-75%

My goal is to get the accuracy up to 95% so anyone who sees something I could do to boost the accuracy a little bit please speak up.

Wouldn’t mind seeing some stills of your Ping and pan servo mountings, and of the claw.

Curious why you mounted the Ping vertically? I’m debating how to mount six SRF08’s in a hex ring for a table top 'bot (MicroMoose).

Nice job!

Alan KM6VV

My code works by trying to find the width of the object then by first detecting one side of the object then continue scanning until it finds the other side of the object.

[code]sensorpan
sensorpanangle = -10000
hservo[sensorpanpin\sensorpanangle-580\0]
hservowait[sensorpanpin]
pause 500

pan_loop_1
hservo[sensorpanpin\sensorpanangle-580\0]
hservowait[sensorpanpin]
gosub distance_check
if(mm_distance<160)and(mm_distance>50)then
object_distance = mm_distance
left_side = sensorpanangle
object_detected = true
initial_angle = sensorpanangle
sound p9,[1000\1000]
goto pan_loop_2
elseif (sensorpanangle = 12000)
object_detected = false
return
else
sensorpanangle = sensorpanangle + 100
goto pan_loop_1
endif

pan_loop_2
hservo[sensorpanpin\sensorpanangle-580\0]
hservowait[sensorpanpin]
;gosub distance_check
if(mm_distance>(object_distance))then
right_side = sensorpanangle
sound p9,[1000\1000]
goto pan_loop_3
elseif (sensorpanangle = 12000)
object_detected = false
return
else
sensorpanangle = sensorpanangle + 100
gosub distance_check
goto pan_loop_2
endif

pan_loop_3
sensorpanangle = ((right_side+left_side)/2)
;offset = (baseangle*10)/30
;baseangle = baseangle + offset

hservo[sensorpanpin\sensorpanangle-580\0]
hservowait[sensorpanpin]
gosub distance_check
baseangle = sensorpanangle

gosub base_driver
return[/code]

Early on I found that having the ping mounted horizontally caused it to initially detect the object with its right “eye” then detect the other side of the object with its “left” eye. This caused the sensor panning servo to have to rotate more to find the right side of the object than it should have making the baseangle (which is the average of the object’s right side detected angle and left side detected angle) a bit offset therefore making the arm less accurate. So to sum it up the ping is mounted vertically to make the detection “beam” narrower. Sorry if my explanation isn’t very clear. I’m planning on getting a laser range finder to raplace the ping sometime.

Still pictures are on their way.

Here they are



and more



and a few more


Thanks for posting the pix. I like the LP used to pan the Ping.

Didn’t quite make out the Ping on the jaw. Sounds like a good idea. But quite close for range. I’m thinking more of an IR sensor for that.

Alan KM6VV

If by jaw you mean gripper I took that Ping off. I found that since the surface is level it really wasn’t needed. However, I still have the bracket needed to mount the ping on the the wrist. I plan on putting it back on sometime and, I might even put a camera and wrist rotate on someday so the blocks it’s picking up can have different shapes and sizes. Of course using a camera on a BAP is still WAY out of the scope of my knowledge.

Jaw/gripper. I wondered how a Ping could work that close!

A camera is not that far out. Well, maybe a little…

I got one for Christmas, although I’ve done little then get it working on it’s own WLAN net. THAT was a lot of work (and some learning).

Alan KM6VV

From my experiance I’ve never had any trouble with a ping sensor at close range. :confused:

update

This demonstrates a subroutine I made that should get the target object in perfect position to be picked up after it has been found. So now I have basically three different behaviors: obstacle avoidance, shift to correct position, and pick up object. Now all I have to do is put all this stuff into one mega code and hopefully I’ll have a fully functioning obstacle avoiding, object finding rover.

Does your Ping scan to one side more then the other? Might have been just the angle.

So you align yourself a certain distance off the object; and then you’ll work your gripper/jaw to grab it?

sounds like a plan.

Although not a rover, I’ve worked out a jaw on my MicroMoose.

lynxmotion.net/viewtopic.php?f=17&t=6608

I wish I had a place to put a rangefinder (SRF08) down low like that to pick up the range to target! Of course, after I get camera stuff working, I wouldn’t need it. But I’d like to have the jaw working for our club’s “Table Top Challenge” coming up. Right now, I’d be content just not falling off the table!

Alan KM6VV

No, the program just exits the scanning subroutine whenever an object is found.

Hmmm, the only way I could think of to mount a sonar under the gripper would be to get slightly larger wheels so there would be some room for a sensor. Since all you need to do with the object is push it off the table you could probably just use an ir sensor though.

Why is it called micromoose anyways? It looks nothing like a moose but is still neat looking. I like the way the steel ball is used. I bet it turns pretty easy on even surfaces.

Are you familiar with the TableTop Challenge? It should be interesting!

Yeah, probably could have given it a little more ground clearance. I can get some forward looking IR sensors down there. I’m working out a pair of brackets to point a pair of QRB1134 IR Prox sensors at the table, fore and aft (a lot of brackets to be made for this 'bot).

The ball casters are from Pololu. The wheels are prototypes, I’ll machine them out of 6061-T6 Aluminum later (I’ve got the proper sized O-rings now).

I had started working on this size 'bot (5" dia) over a year ago. The size is convenient for making the disks on my CNC’d Sherline mill, and to accommodate the GHM16 drive motors with encoders end-to-end.

Then our club decided to start a MicroMouse project. Well, my already started 'bot was a little too big for the maze, so I redesigned the drive motors to be miter-gear driven, placed side-to-side to reduce the footprint. The disks above the drive system can remain the same. MicroMouse has turned out to be a long project, and I really wanted to put on a lot more sensors and get my original 'bot project running. the original 'bot became “MicroMoose”, because it’s a little too big to be a MicroMouse!

Since the pictures I’ve added a section with six SRF08 ultrasonic ranging modules, and a small PIC processor board in the middle to manage them.

I’m finally getting all the stuff I need mounted (I also added a rear-facing line camera on a tilt servo), It might work for sensing a target as well. But that would be a bit weird, you’d locate the target, then do a 180 to be able to approach with the jaws. But if I only need to push the target off of the table, then I could do that, with the camera! (note to self, add bumper)

The floor-sensing sensors should get me onto the table.

Alan KM6VV

lol, :laughing: now I get it.

I’ll keep watching that thread to see when the micromoose has any improvements made on it.

Well, as my signature says things are bound to screw up sometime and it is now.

I finally got around to putting my obstacle avoidance program and object finding program into one code. It compiles and runs fine until it gets to this subroutine.

[code];[WAITFORPREVMOVE] Loop that wait for the previous servo move to be finished
idle var byte
finished var byte
junk var word
WaitForPrevMove
finished = true
gethservo BasePin,junk,idle
if(NOT idle)then
finished=false
endif
gethservo ShoulderPin,junk,idle
if(NOT idle)then
finished=false
endif
gethservo ElbowPin,junk,idle
if(NOT idle)then
finished=false
endif
gethservo WristPin,junk,idle
if(NOT idle)then
finished=false
endif
gethservo GripperPin,junk,idle
if(NOT idle)then
finished=false
endif
gethservo WristRotatepin,junk,idle
if(NOT idle)then
finished=false
endif
sound p9,[500\500];first sound command that repeats over and over
if(NOT finished)then WaitForPrevMove
sound p9,[1000\4000];second sound command that I never here at all
_mPrev_BasePos1 = BasePosition1
_mPrev_ShoulderPos1 = ShoulderPosition1
_mPrev_ElbowPos1 = ElbowPosition1
_mPrev_WristPos1 = WristPosition1
_mPrev_GripperPos1 = GripperPosition1
_mPrev_WristRotatePos1 = WristRotatePosition1

return[/code]

Using sound commands I found that the code is going into an endless loop within the subroutine. The thing that’s really getting me is that this exact same code is used in my object finding program and it works perfectly! :confused: This is where the waitforprevmove subroutine is entered. Again, this is copied and pasted from another code where it works perfectly.

[code]servo_driver
;Inverse Kinematic calculations
GOSUB ArmIK [WristPosX, WristPosY, GlobalGripperAngle1]
ShoulderAngle1 = -IKShoulderAngle1+900
ElbowAngle1 = IKElbowAngle1+900
WristAngle1 = -IKWristAngle1

GOSUB CheckLimits

GOSUB WaitForPrevMove ;it enters right here
sound p9,[1000\1000];I never here this either
GOSUB Movement baseangle1,-ShoulderAngle1, -ElbowAngle1, -WristAngle1, -Gripper1, -WristRotateAngle1, 250]
return [/code]

I concluded that the only thing that could be the culprit was the gethservo commands malfinctioning for some reason beyond my understanding. Sorry if you don’t understand. This really hard for me to explain. Infinite thankyou to anyone that helps in any way.

fixed it

[code]idle var byte
finished var byte
junk var word
WaitForPrevMove
repeat

finished = true
gethservo BasePin,junk,idle
if(NOT idle)then
	finished=false
endif	
gethservo ShoulderPin,junk,idle
if(NOT idle)then
	finished=false
endif	
gethservo ElbowPin,junk,idle
if(NOT idle)then
	finished=false
endif	
gethservo WristPin,junk,idle
if(NOT idle)then
	finished=false
endif	
gethservo GripperPin,junk,idle
if(NOT idle)then
	finished=false
endif	
gethservo WristRotatepin,junk,idle
if(NOT idle)then
	finished=false
endif			

sound p9,[50\1000]
until (finished = true)
_mPrev_BasePos1 = BasePosition1
_mPrev_ShoulderPos1 = ShoulderPosition1
_mPrev_ElbowPos1 = ElbowPosition1
_mPrev_WristPos1 = WristPosition1
_mPrev_GripperPos1 = GripperPosition1
_mPrev_WristRotatePos1 = WristRotatePosition1

return[/code]

I don’t know how but the program worked perfectly the first time I tried this out. :confused:
I’m very happy that I actually got it working though. :smiley:

P.S.

if(NOT finished)then WaitForPrevMove
How exactly does this line of code get compiled without error. It doesn’t have an endif statement or a goto statement before waitforprevmove. I never really looked so closely at these parts of code until now and I notice several things that seem to break “rules” that I’ve learned from BAP syntax.


Accuracy is about 75-80% right now. It still has some bugs to work out.

Here’s some higher quality still images of the setup.



Nice pick-up!

Are you scanning the width of the object to be picked up as well?

Alan KM6VV