Tri-track/Rover with Basic Micro Roboclaw+++

For the fun of it I also installed the Parallax USB oscilloscope on the two channels as well, to make sure the signal looked reasonably clean. Here is an output:


The interesting thing is it said in the right hand values that the frequency was twice as fast as I saw in the logic analyzer, and when I measured the times for the pulses it matches the logic analyzer. So I think some of their calculations are off…

As Nathan asked if it was always off by a factor of 2, I tried checking the outputs at different speeds. So I tried in 1st and 2nd gear…

So 2nd gear which should give us about half speed. Looking at the logic analyzer it looks like the period is right around 4khz, so *4 = ~16000

Values displayed:
Left Encoder: 269022 80 Speed: 33325 0 Right Encoder: 301141 80 Speed: 35670 0
Left Encoder: 289322 80 Speed: 33290 0 Right Encoder: 315557 80 Speed: 35840 0
Left Encoder: 302896 80 Speed: 33650 0 Right Encoder: 337142 80 Speed: 35860 0

Now for 1st gear: I was getting somewhere near a frequency of about 1.53khz so expect about 6012 values printed:
Left Encoder: 25445 80 Speed: 12755 0 Right Encoder: 27023 80 Speed: 15445 0
Left Encoder: 33725 80 Speed: 14025 0 Right Encoder: 36153 80 Speed: 14735 0
Left Encoder: 41568 80 Speed: 12975 0 Right Encoder: 48579 80 Speed: 15670 0

Next, I am going to try to use some different commands to tell it to go at some specific speed and I will try to stop it at certain distance like 2 feet. If the numbers on a different tri-track thread are correct that at 200rpm the tri-track would move at 28.9 inches per second. From this you can calculate that it should move about 8.67 inches per revolution, which also matches if the diameter of the driver is 2.75 inches then 2piR = 8.64"

So for 24" I would expect encoders to be: 24/8.64 * 400 * 30 = 33,333

Now back to playing with the code.

Kurt

This is probably it for today:
My first attempt at moving both motors at a set speed by the encoders for a distance is not working as well as I would hope for yet: Probably coding issues or my lack of understandings or expectations.

The first attempt is:

[code] IF (DualShock(2).bit0 = 0) and LastButton(1).bit0 THEN ;L2 Button test
; lets try starting both motors foreword and then go into a query loop and try to read in the encoders and see if we can stop automatically
; after maybe two feet…
; Reset the encoder counts
serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 20, (RCLAW_ADDRESS + 20) & 0x7f] ;Reset both encoders

	; Start both wheels going foreword...
	RencoderSpeed = 4000	;	It appeared like maybe 4700+ was max so lets try this.
	CRC = (RCLAW_ADDRESS + 36 +  REncoderSpeed.Byte3 + REncoderSpeed.Byte2 + REncoderSpeed.Byte1 + REncoderSpeed.Byte0 + |
			255) & 0x7f
	sound p9, [50\4000]
	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 36, REncoderSpeed.Byte3, REncoderSpeed.Byte2, REncoderSpeed.Byte1, REncoderSpeed.Byte0, |
		255, CRC];
	
	; now lets loop reading in the current distance and stop when we think we are there.
	do
		serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 16] ;read command for M1 encoder
		serin RCLAWSerinPin, RCLAW_BAUD, [REncoderCnt.Byte3, REncoderCnt.Byte2, REncoderCnt.Byte1, REncoderCnt.Byte0, REncoderStat, CRC]
	while (RencoderCnt < 34000)	 ; roughly 24 inches ???

	; and then stop...
	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 0, 0, ((0 + RCLAW_ADDRESS) & 0x7f)]	; Stop
	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 4, 0, ((4 + RCLAW_ADDRESS) & 0x7f)]	; Stop
	sound p9, [50\5000]		
		
ENDIF[/code]

I first cleared the encoder counts. Then I told both motors to go forward at speed: 4000. I then looped on reading the right encoder until it was no longer less than 34000 which should be around 24 inches and then I tell both motors to stop. My expectation was that it would go in a straight line, but it did not. When I then after each run hit the R2 button to print out the encoder counts, you can see that the left and right were not the same.

Left Encoder: 18515 82 Speed: 0 1 Right Encoder: 42072 80 Speed: 0 0 Left Encoder: 18515 82 Speed: 0 1 Right Encoder: 42072 80 Speed: 0 0 Left Encoder: 39902 82 Speed: 0 1 Right Encoder: 41099 80 Speed: 0 0 The first two runs shown were with the tracks off of the ground. Visually the two tracks appeared like they moved reasonably close. On the third run I put it on the ground. In this run it did make what appeared to be a slow left turn, which is consistent with the encoder counts seen above. Another interesting thing is that it was to stop at > 34000 but the runs all went up to 42000. Hard to measure how far it went but probably at least 22 inches.

I am Also wonder if the roboclaw firmware is setup to support handling all of the encoder transition’s as well as receiving and responding to commands from the serial port…

That is all for now.
Kurt

Kurt,

You probably need to implement dual PID controllers.

Alan KM6VV

Just a quick update.

I ran into several issues when I was trying out the current version of the Roboclaw. The good news is Basic Micro is about to release updated firmware for it, which will hopefully fix all of these issues. There is more information about this update on the thread: forums.basicmicro.net/electronic … 5df#p42185

Now I just need to get mine updated :smiley:.

Kurt

The new RoboClaw firmware brings out some new commands that will allow you to write your own PID control if you want as well as including a built in PID controller for each motor with adjustable settings so hopefully no one will have to roll their own.

The speed command in the old system did not allow you to write your own PID because it was the average speed(over one second) which is too slow for a good PID. The new firmware has an additional “instant” speed which is updated 125 times a second. This along with the new PWM commands will allow anyone to write their own PID if they like. I even prototyped our builtin PID controllers using these new commands before it was implemented internally.

The new Roboclaw arrived. It may be a week or so before I have time to do much with it, but:

Sounds Great! If there are others who do not know what Nathan meant by PID,

Again there is information about the new commands up on the thread I mentioned a few posts ago… (forums.basicmicro.net/electronic … tml#p42199)

A side note: on my Tri-track it appears like my max Qpps is somewhere near 37000. I will double check again. But it does not surprise me that the added friction of moving the track would slow the motor down.

Kurt

Kurt

37000 is what I get on my battery after a minute or so of running. I’m using a Lynxmotion 12v battery(one of the green ones, though they all may be green). Yes, you are probably getting a lower top speed because you have tracks. You definitely want to set the maxqpps to your value because it gives the PID controllers a better feedforward value(eg the PID has to do less work to keep the motor at the requested speeds).

Which RoboClaw? the 2X5? Is there a manual for it yet?

Hi Nathan,

Yep I have a lynxmotion 12v battery (the older smaller 1600mah ones lynxmotion.com/Product.aspx? … egoryID=48)

As for which one? I don’t know for sure but I think I have the 10. Pretty sure from the pictures that it is not a 5. There is a manual up on their product page: basicmicro.com/Robo-Claw-2x10A_p_45.html. I don’t think it has been updated yet to the new stuff, but from the manual and the information from Nathan on their forum, you should get a pretty good idea of what it supposed to do.

Kurt

The larger(size of the ssc for easy stacking) roboclaws are 10 and 25. The 2x5 is significantly smaller. The 2x5 has all the saame functions as the 2x10 and 2x25 just doesn’t support as high a current load on the motors. We are currently updating the RoboClaw datasheet with the new commands.

On My Claw, I don’t see any marking that shows if it is a 10 or 25, but I will guess a 10…

I don’t have much time right now, but did a little hacking to see how the new version is working. It appears to behave much better now!
Still just playing, but for example if I run the following code:

; L1 button, try driving both motors for a certain distance. IF (DualShock(2).bit2 = 0) and LastButton(1).bit2 THEN ;L1 Button test ; lets try to go forward about a feet, under the control of the encoder. REncoderCnt = 1900 * 12 ; lets see how close this is RencoderSpeed = 20000 ; It appeared like maybe 4700+ was max so lets try this. ; cmd 43 Speed1, Distance 1, speed2, Distance 2, Clearbuf CRC = (RCLAW_ADDRESS + 43 + RencoderSpeed.Byte3 + RencoderSpeed.Byte2 + RencoderSpeed.Byte1 + RencoderSpeed.Byte0 + | REncoderCnt.Byte3 + REncoderCnt.Byte2 + REncoderCnt.Byte1 + REncoderCnt.Byte0 + | RencoderSpeed.Byte3 + RencoderSpeed.Byte2 + RencoderSpeed.Byte1 + RencoderSpeed.Byte0 + | REncoderCnt.Byte3 + REncoderCnt.Byte2 + REncoderCnt.Byte1 + REncoderCnt.Byte0 + | 0) & 0x7f serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 43, | RencoderSpeed.Byte3, RencoderSpeed.Byte2, RencoderSpeed.Byte1, RencoderSpeed.Byte0, | REncoderCnt.Byte3, REncoderCnt.Byte2, REncoderCnt.Byte1, REncoderCnt.Byte0, | RencoderSpeed.Byte3, RencoderSpeed.Byte2, RencoderSpeed.Byte1, RencoderSpeed.Byte0, | REncoderCnt.Byte3, REncoderCnt.Byte2, REncoderCnt.Byte1, REncoderCnt.Byte0, | 0, CRC]; sound p9, [50\4000] pause (REncoderCnt/REncoderSpeed)*1000 + 500 ; pause until we think the command should be done. sound p9, [50\5000] ENDIF
The Tri-track now runs in pretty much a straight line which is much better than before!. Still trying to figure out how to do distances. The Distance I asked for was: 1900*12 or 22800.
After the rover stopped, I hit another butotn on the PS2 that printed asked the claw for the encoder counts and speeds and printed them out. After this run I had the results:

Left Encoder: 34973 80 Speed: 528 0 Right Encoder: 34964 82 Speed: 478 1

I also modified my other attempt, to simply start the tracks running and when it got to a certain distance stop: The code looks like:

[code] IF (DualShock(2).bit0 = 0) and LastButton(1).bit0 THEN ;L2 Button test
; lets try starting both motors foreward and then go into a query loop and try to read in the encoders and see if we can stop automatically
; after maybe two feet…
; Reset the encoder counts
serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 20, (RCLAW_ADDRESS + 20) & 0x7f] ;Reset both encoders

	; Start both wheels going foreword...
	RencoderSpeed = 25000	;	It appeared like maybe 37000 was max so lets try this.

	; cmd 37 Speed1, speed2, 
	CRC = (RCLAW_ADDRESS + 37 + RencoderSpeed.Byte3 + RencoderSpeed.Byte2 + RencoderSpeed.Byte1 + RencoderSpeed.Byte0 + |
			RencoderSpeed.Byte3 + RencoderSpeed.Byte2 + RencoderSpeed.Byte1 + RencoderSpeed.Byte0) & 0x7f

	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 37, 	|
			RencoderSpeed.Byte3, RencoderSpeed.Byte2, RencoderSpeed.Byte1, RencoderSpeed.Byte0, |
			RencoderSpeed.Byte3, RencoderSpeed.Byte2, RencoderSpeed.Byte1, RencoderSpeed.Byte0, |
			CRC];

	
	; now lets loop reading in the current distance and stop when we think we are there.
	do
		serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 16] ;read command for M1 encoder
		serin RCLAWSerinPin, RCLAW_BAUD, [REncoderCnt.Byte3, REncoderCnt.Byte2, REncoderCnt.Byte1, REncoderCnt.Byte0, REncoderStat, CRC]
	while (RencoderCnt < 34000)	 ; roughly 24 inches ???

	; and then stop...
	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 0, 0, ((0 + RCLAW_ADDRESS) & 0x7f)]	; Stop
	serout RCLAWSeroutPin, RCLAW_BAUD, [RCLAW_ADDRESS, 4, 0, ((4 + RCLAW_ADDRESS) & 0x7f)]	; Stop
	sound p9, [50\5000]		
		
ENDIF[/code]

Again it appeared to run much smoother and it stopped in a reasonable time, When I printed out the distances like the first test I saw:

Left Encoder: 35223 80 Speed: 0 0 Right Encoder: 35126 82 Speed: 0 1

I won’t have much time to do anything with this for several days, so I uploaded the code so you could play with it if you want!
Kurt

I wish the 2x5A was the same size as a 10. Well, at least I can stack two of them, even if not on top of BotBoard II size boards.

I will definitely be playing with this once I get my first RoboClaw, which may be delayed because I spent some money on Ham Radio stuff yesterday. No money available for Robotics right now if I keep the Ham stuff.

Great work, as always, Kurte!

8-Dale

Any idea when the docs will be ready? Can I order the 2x5 now? If the functionality and basic connections are the same, then possibly I can get buy with the 2x10 docs? Do you have the hole pattern and dims? (hot project).

Thanks!

Alan KM6VV

The connections are all the same the only difference is where they are on the board. Smaller board required the board layout to be different. The 2x5 has all the same connectors as the 2x10 and 2x25 except the screw terminals for power and motors are smaller. We do have them in stock right now as well as the 2x10s. I believe we’ve already shipped all the 2x25s we had so it will be a little longer before those are back in stock.

The updated docs should be availabel sometime this week. I still have to proof read them but I think most of the writing is done.

Hi Nathan,

That would be great, Thanks!

Alan KM6VV

Kurt,

Just received my 2x5 RoboClaw. I have the Lynxmotion motors and encoders as well. Looking forward to spinning some tires!

Alan KM6VV

I thought I would get back to playing with this again and have some fun. Recently I saw that Nathan (AcidTech) posted up on the Basic Micro forum a set of functions for each of the Roboclaw functions in the thread: forums.basicmicro.net/electronic … tml#p42279

I have been meaning to do something like that: So I copied down his functions and then modified the names of them. For me it was easier to read the code that looks like:
gosub RClaw_DriveForwardM1[RDrive]
Than:
gosub CMD0[RDrive]

I than removed the code for the other ways to talk to the Roboclaw (PWM, simple serial) and then converted all of code to use these functions. There are still some things I need to figure out the best way of handling, but I thought I would at least post the changes up till now, in case anyone else with the roboclaw wishes to look at it.

Some things I still need to figure out include:

a) The functions like: gosub RCLAW_ReadEncoderM1], REncoderCnt
Work great, but, it also returns a status word with some important information like direction and overflows. How best to get these values. Since Nathan’s stuff is defined at the end, I can not reference his variable. Could add a function like: RCLAW_ReturnEncoderStatus], …

b) When I want to go a specific distance, I need to calculate how long/far it will take to stop and factor that in. There is information on how to do this up on the BM thread.

c) Convert the code to know when commands complete. Can use the RCLAW_ReadBufferDepth function. The buffer count only decrements when the command is completed, so if both counts are zero, we should be done with the last command.

d) Need to play now - with stringing command together. That is I want to go foreword N units, turn 90 degrees, go … Will try to make a square and get back to the starting point.

Kurt
b)

Kurt,

Nice! I did manage to get my motors to spin, then I realized that I hadn’t really finished the mechanicals on my Micromouse. I have geared the GHM16 motors to conserve space, and for initial alignment I had used a solid 1/4" shaft between the two wheels for the initial alignment of the motor brackets.

The intent is to have a split shaft, supported at the center by a pair of bearings. So, the two wheels can’t turn independently until I make up a bearing block, and get fitted to the chassis.

As soon as I get the mechanicals fixed, I think I can try running the 'Mouse with something similar to your code.

I do like the “readability” changes you made. I had seen Nathans code, but didn’t have time to see why he created the functions. I thought perhaps he was making a replacement set of functions to mimic the Sabertooth or some other motor driver?

Anyway, thanks for posting your code. If I ever get caught up…

Alan KM6VV

Another quick update before I decide how I want to fix a few things…

Alan, it sounds like you are also having some fun. It will be fun to see your micromouse!. I believe Nathan created all of the functions to make it easier to try out the features of the roboclaw. It is a lot easier to understand the code when you see something like:

[code]IF (DualShock(2).bit2 = 0) and LastButton(1).bit2 THEN ;L1 Button test
; lets try to go forward about a feet, under the control of the encoder.
;REncoderCnt = 1900 * 12 ; lets see how close this is
;RencoderSpeed = 20000 ; It appeared like maybe 4700+ was max so lets try this.
; cmd 43 Speed1, Distance 1, speed2, Distance 2, Clearbuf
gosub RCLAW_DriveSpeedDistance[20000, 1900 * 12, 20000, 1900 * 12, 0]

; now lets try to turn...
gosub RCLAW_DriveSpeedDistance[20000, 14500, -20000, -14500, 0]
	
; and go forward for a little ways
gosub RCLAW_DriveSpeedDistance[20000, 1900 * 6, 20000, 1900 * 6, 0]
	
; and Stop
gosub RCLAW_DriveSpeedDistance[0, 0, 0, 0, 0]	' should bring us to a stop...
	
' now lets see if we can figure out when the stop actually happens.
' Note the ReadBufferDepth returns two counts, one for each wheel we are done
' when both go to zero so simply checking the word for zero should be sufficient.
sound p9, [50\4000]
do 
	gosub RCLAW_ReadBufferDepth], EncoderBuffCnts
while EncoderBuffCnts
			
'pause (REncoderCnt/REncoderSpeed)*1000*2 + 500	; pause until we think the command should be done.
sound p9, [50\5000]		

ENDIF
[/code]
Then it is to see the equivalent code with a bunch of serin/serout calls and computing checksums.

For the fun of it I had a Base Rotate kit, some servos and brackets and added this to the Tri-track. Will later add sensors and/or tank gun… I added some of the code that I was playing with last week for Linuxguy for pan/tilt under ifdefs. I played a little with this code. I need to tweak the limits and the like, but when the tri-track is running in one stick mode, I can use the left stick to do pan/tilt. Clicking the L3 button will bring them back to the zero location…

BUT: then I hit the right joystick to move the tri-track and nothing happened :frowning:. I thought maybe I dislodged a wire when I was hooking up the pan/tilt, but decided to first disable the pan/tilt code by commenting out the defines for which servo they are on and it worked again. The problem, that I should have realized right away is that once I enabled HSERVO, the bit/bang serout/serin functions at 38400 did not work properly and the roboclaw did not get any valid packets. Now trying to decide what to do. I have several possible solutions:
a) Punt: This is the easiest way and what I am currently doing. That is don’t do it…
b) Try communicating at a lower speed like 2400. Will probably get some packets through.
c) Bring in my own serial input/output functions: Could do this pretty easy, but is a lot of complicated assembly language code that could confuse people who may wish to play with a simple rover program like this.
d) Use HSERIAL to talk to the roboclaw. This will require me to move the PS2 from the default IO pins. Can move to P0-P3 using built-in pull-up resistor and change all of the serial functions to use the hserin/hserout functions. This is probably the way I will go. I will try to put this all under #ifdefs as I may wish to use these functions in other programs…

Suggestions?

Kurt

P.S - I wish the basic would allow me to abstract away which physical way the IO is happening without having to change APIS for each call! That is, I wish for example serout might allow me to specify a hardware port/mode and it would automatically redirect to the underlying API. For example if a pin of -1 implies Hardware serial port and -2 implies Hardware serial port 2. Then one could simply have some quick defines at the start of the program and the rest of the code goes unchanged. You could in this case either ignore the baudmode or compares it to the last one and if it changes does a call to sethserial, probably defaulting to 8 bit, no parity, 1 stop bit… But that is another subject.

Hi Kurt,

Your tracked robot is really getting some where! I’m not going to do tracks any time soon, but it’s still similar control. Differential steering vs. slip-slide. I did a project for a photographer, 4-wheel drive, tilt/pan for a camera. Kinda curious how it basically slip-slided around. The MicroMouse, of course, is differential steering. But I am considering putting on a tilt/pan for the BlackFin camera. Overkill for a MicroMouse? Maybe. But a good exercise in vision, I think. And I’m thinking I can port the camera, compass and GPS to a Magellan robot. compass and GPS probably not needed on MircoMouse!

Yeah, a little fun! A lot of time is spent with new 2010 SS2/RS Camaro!

I agree with your improved “formatting” of the functions. All that low-level stuff should be hidden, and only used a few places.

I have a base rotate kit somewhere. Initial thought was to put it on the mentioned photo recon robot, but it wasn’t big enough to handle a serious SLR digital camera. I’ll kick around a few ideas for the MicroMouse.

Yeah, that’s a real problem with BASIC. Really need to code proper buffers, and run interrupts. One of the trade-offs in running built-in LIB functions, I guess.

If the ASM code could be made modular enough (why we like include files), then it could be a drop-in. I think I’ve moved the pins before when confronted with a similar problem.

How about a WiFi connection? The Lantronix is interesting, and it can handle the Blackfin video!

Part of HAL (Hardware Abstraction Layer) approach is defining hardware pins and ports. From Phoenix, we have:

;[PIN NUMBERS]
#IF SSC_LM_SETUP ;Connector to the front
RRCoxaPin con P0 ;Rear Right leg Hip Horizontal
RRFemurPin con P1 ;Rear Right leg Hip Vertical
.
.
.
#ELSE ;Connector to the back
RFCoxaPin con P2 ;Front Right leg Hip Horizontal
RFFemurPin con P1 ;Front Right leg Hip Vertical
#ENDIF

As you know; this is a start. With enough ifdefs for defines, and conditional compiles, we can get the job done.

Alan KM6VV