Rover_v1.2 basic micro program update?

Hi roboteers!

Just finished up on the assembly of my robot project, a tracked rover with arm… and as I’m taking my first steps in programming, I discovered that the rover_v1.2 isn’t working out of the box.

After some reading, I discovered that the command gethservo is no longer in the command package, and is replaced by hservoidle and hservopos in the latest version.
I’ve worked out a bit of code using hservoidle to replace the obsolete bit, but I suspect something else is messed up aswell and thus I can’t test it. Besides, my programming skills are still nonexistant so I thought I’d offer it to more capable hands!

The bit that needs replacing is:

;[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	

	if(NOT finished)then WaitForPrevMove

	_mPrev_BasePos1			= BasePosition1
	_mPrev_ShoulderPos1 	= ShoulderPosition1
	_mPrev_ElbowPos1  		= ElbowPosition1
	_mPrev_WristPos1		= WristPosition1
	_mPrev_GripperPos1		= GripperPosition1
	_mPrev_WristRotatePos1	= WristRotatePosition1
	
return

Also, this is my first public post so a warm hello to all roboteers out there! I’m looking forward to spending months of problem solving, heh heh.

Welcome to the forum!

I’ve updated the code on the website. It now compiles and should work properly. :wink:

Thanks for pointing this out!

Yep, that does the trick! My ego has been patted as I had something similar, if a good deal less elegant, heh heh. Thanks for your speedy response.

This brings me to the next problem. I’m a bit less sure this is something that needs adjusting in the out-of-box program, but worth looking into I reckon.
I’ve got my tracked rover up and running, with an AL5D on top. I’m assuming all power and servo wiring is correct. I ran the offset program without problem, bringing the arm up to a nice straight angle at standard values. To get it perfect, only small offset adjustments are needed. I then proceeded loading ps2a4wd1.bas to test the PS2, all goes well. Significantly altered the program to add the arm, instead of the pan and tilt and gripper. (no IK, just simple direct control) Setting all servos to 1500 again brings me to a nice right angle, and all joints are easily controllable using PS2.

Now it gets interesting: I open up rover v1.2, select the correct arm, and on powerup, the arm immediately jerks back all the way to folded position, requiring me to hit the emergency poweroff.
Interesting thing is, if I play around with the offsets and change them to an extreme value, I can get it to initialise to a less destructive position. Once it’s initialised like this, I can move the arm (with very smooth working IK, nice programming there Xan!) and it works as it should.

Here’s what I did, these values just moved the arm up high enough not to crash into the base:

;Select Arm type
;NOTE: Enable only one arm!
;AL5A con 1
;AL5B con 1
;AL5C con 1
AL5D con 1
;--------------------------------------------------------------------
;[SERVO OFFSETS]	deg * 166.6
Base_Offset			con -2500
Shoulder_Offset		con -2500
Elbow_Offset 		con -2500
Wrist_Offset 		con -2500
Gripper_Offset 		con -2500
WristRotate_Offset 	con -2500

Now obviously this isn’t the solution, but it does tell me something’s wrong somewhere.
After some further research, I figured it might be this that’s a bit off:

#ELSEIFDEF AL5D
  HumerusLength		con 147	;Length of the Humerus [mm]
  UlnaLength		con 187	;Length of the Ulna [mm] 
  InitWristPosX 	con 55	;Init position X
  InitWristPosY 	con 120 ;Init position Y
  InitGripperAngle1 con -550;Init Angle gripper

The InitWristPos X and Y are the first values being loaded into the servo outputs. Is it possible that these are indeed supposed to fold the arm back, and maybe does so just a little too far?

I’m a bit hesitant to play around with this value, as I’d rather not park the claw in the battery compartiment :smiley:
Changing InitWristPosX to, say, 90, does this move the hand further away from the body? Is it in mm?
Changing InitWristPosY to, say, 150, does this move the hand higher? Is the height measured from the hub of the shoulder joint?

I think my AL5D is pretty out of the box standard for now, so I’m happy to test some values. If I’m not mistaking, it might be wise to maybe change these standard values a wee bit to allow some more room for error.

Then again, I could be completely wrong of course :smiley:

The program does indeed put the arm in a “parked” position. It may be that your build and ours is just a little off.

Hi Xraybroadcaster,

Welcome to the forum! From reading your posts it looks like you are having some good fun! :wink:

I’ve got my rover+AL5D setup ready to rock so I must be able to help you out.

Some quick things you should know.

  • All dimensions in the software are in mm. (I’m from europe. lol)
  • All angels are in degees unless mentioned otherwise.
  • The precision of a value can be found in it’s name. If a variable ends with one or more digits. ONLY the last digit tels the number of decimals. If a variable called Cos4 and contains a value of 23. It means that the value is 0.0023.

Once you power up the bot the arm will be positioned in the home (collapsed) position. After hitting start the arm can be moved around using IK. The IK is controls the arm from the center of the mounting plate (rover) to the center of the wrist servo. The gripper is NOT included in the IK software since this made it hard to control with a remote. X is horizontal movement. Y is vertical movement.

The home position uses IK. So this strongly depends on length of all the components. From your post I think your calibration should be right. The only thing what is missing for good help are some photo’s of your bot. For example there are some different wrist setups. Do you use a wrist rotate upgrade? And if yes, which one?
Wrist Rotate Upgrade (Light Weight)
Wrist Rotate Upgrade (Medium Duty)
Wrist Rotate Upgrade (Heavy Duty)

The software is tested with the AL5D including the Wrist Rotate Upgrade (Light Weight). When using another wrist setup it is possible that the home position doesn’t work for you. If you use one or another wrist you need to change the initial positions. Like you already showed in you previous post.:

InitWristPosX con 55 ;Init position X InitWristPosY con 120 ;Init position Y InitGripperAngle1 con -550;Init Angle gripper
You could start out by giving Y a high value and lower it down bit by bit until you get a satisfied result. Another method you could use is to get the IK excel file. Adjust the lengths of your arm and find a quick “home” position. This works fine for a rough setup. But you need to test it on the bot at well since the arm including servos is a bit bigger then the skinny lines on the drawing :wink:

I hope this information will help you out. Let me know if there is something else.

Xan

Hi Xan, yes, I’m having tons and tons of fun- rarely had anything that I could tinker with to this extent!

I have been playing around with the mentioned init positions, and you were indeed right. According to my tests, the floating point must’ve been just a millimeter off and into the base of the arm. I have the medium wrist rotate but it’s the wrist joint that’s touching the base so that’s not the cause. I suspect it’s either my construction that’s differing slightly, or the original rest position is a bit strict. Increasing both values slightly solves the problem, and increasing both by a bit more gives you abit of a buffer when returning to rest position.
Maybe worth cranking up the standard values in the out-of-box program a wee bit, while we’re at it? Just a thought.

Next problem! Another small one: in rover mode, one stick control. I get the impression there’s a glitch in two quadrants.

When turning in reverse, there’s a point where one track seems to stop illogically.
I need to do more testing, but so far it seems to happen in reverse only, when the stick passes 45 degrees, both left and right. So that must be the cutoff of the MIN and MAX commands. Maybe these need to be exchanged with one another? I’d test it myself but I seem to have forgotten all about dinner so that’ll have to wait til tomorrow

After a good few hours wasted on drawing up diagrams and graphs of how the sticks move compared to how you’d expect the bot to move, and the corresponding track movement, I figured it out! (Also I lost some time as here it appears the X axis is called Y and the Y axis is called X)
It’s just a problem with our way of thinking. The original code follows the logical path, and this leads to an unavoidable error unless we change our approach. Allow me to explain with a little theoretical example:

  1. Think tracked tank vehicle, one-stick control. We want to go forward, so we push the stick forward. Logical! We want to go off to the right, so we turn our stick clockwise, and the vehicle starts turning to the right. Also logical! As we keep turning the stick clockwise, we’ll eventually reach fully right on our stick (Y=127, X=0) and we’ll be turning our vehicle clockwise, so to the right. Still makes sense, no?

  2. back from standstill, we want to go backwards. So we push the stick backwards, and we’ll go backwards. Logic is fun! Now, we’ll want to go to the right, so we push our stick right, and lo and behold, we’ll start turning to the right, backwards. Miraculously logical. So as we keep turning our stick counterclockwise from fully backwards to right, our vehicle starts spinning in place counterclockwise. Our stick is fully to the right (y=127, x=0) and we’re turning counterclockwise. Very logical!

However! Behold, our previous example, with thesame stick position, we’re turning the exact, complete and utter opposite way!

The current standard code follows example 1 for the greatest part, giving you a 270 degree arc of forward logical movement, and a 90 degree arc of backward logical movement, with a glitch on the crossover, where the tracks switch around from full forward to full reverse instantly, and vice versa.

While this is probably the most logical way of moving, I thought I’d have a go at coming up with an alternative. I must admit I felt quite happy when my limited and rusty programming skills actually ended up with some working code :smiley:

So in this version, example one is fully valid, so forwards makes sense. When going backwards, left and right are swapped around, so a bit more like tank steering. While it’s a bit weird at first, it does allow for a full 360 degrees of smooth track motion without any glitches.

 IF SteeringMode = TANK_MODE THEN	;Tank steering mode
      RDrive = -RStickX
      LDrive = -LStickX     
    ELSE								;One stick steering mode
      IF RStickX>=0 AND RStickY>=0 THEN ;Quadrant 1
      	Rdrive = -(RstickX - RstickY)
      	Ldrive = -(Rstickx MIN Rsticky)
      	
      ELSEIF RStickX<0 AND RStickY>=0  ;Quadrant 2, backwards movement means left and right is inversed
      	Rdrive = -(RstickX MAX -RstickY)
      	Ldrive = -(RstickY + RstickX )
      
      ELSEIF RStickX<0 AND RStickY<0  ;Quadrant 3, backwards movement means left and right is inversed
      	Rdrive = -(RstickX - RstickY)
      	Ldrive = -(RstickX MAX RstickY)
      
      ELSEIF RStickX>=0 AND RStickY<0  ;Quadrant 4
      	Rdrive = -(RstickX MIN -RstickY)
      	Ldrive = -(RstickX + RstickY)
      
   ;   IF RStickX>=0 AND RStickY>=0 THEN ;Quadrant 1	-original code
   ;     RDrive = -(RStickX - RStickY)
   ;     LDrive = -(RStickX MIN RStickY)
   ;     
   ;   ELSEIF RStickX<0 AND RStickY>=0  ;Quadrant 2
   ;     RDrive = -(RStickX + RStickY)
   ;     LDrive = -(RStickX MAX RStickY)
   ;     
   ;   ELSEIF RStickX<0 AND RStickY<0  ;Quadrant 3
   ;     RDrive = -(RStickX MAX RStickY)
   ;     LDrive = -(RStickX - RStickY)
   ;   
   ;   ELSEIF RStickX>=0 AND RStickY<0  ;Quadrant 4
   ;     RDrive = -(RStickX MIN -RStickY)
   ;     LDrive = -(RStickX + RStickY)      
           

Anyone fancy giving this bit a try, and let me know what you think? I think it’s mostly preference, but it is quite nice not having that glitch in the backwards quadrants. After a bit of testing, I think I prefer it this new way. It might be interesting to find out how the Irobot bomb disposal robots do this. Maybe they just use two-stick control?

Same stick positions, we get two different rotations?

I’m not “tracking” your observations.

Nothing handy to try out your calcs.

Alan KM6VV

1 and 2 are how you’d EXPECT something to move (well, at least I would, hehe) It’s how a car responds.
My point is just that it’s practically impossible to reach that with tracks and one stick, as it depends on wether you’re thinking backward or forward. When moving forward, pressing to the right will make you turn clockwise. When moving backward, and you press to the right, you’d expect to go to your right, but then you’d be spinning counterclockwise. The two are opposites and thus hard to combine.

The standard rover_v1.2 code tries to remedy it a bit, but this causes a glitch- try setting a low speed, then push full forward. Then slooooowly spin your stick clockwise. you’ll notice a sudden jerk in motion halfway the 3d and 4th quadrant. Nothing horrendous, as it allows you to move backwards with logical steering, but it’s there :slight_smile:

The code I slapped down earlier removes the “fix” and thus the jerk. This allows for smoother movement when maneuvering around, but reverses left and right when going backwards.

Forgive me for rambling, it always sounds a lot better in my head, and my translation might be a it off too :smiley: