Xans phoenix code SSC-32 speed up/Binary mode

There are a few different threads talking about this in a few of the different forums (SSC, remote control, …) so I am not sure where the best place is to talk about this. I thought about the thread talking about Xans phoenix code, but I did not want to hijack that thread, so I decided maybe it deserves it’s own thread…

First I would again like to say that Xan did a great job with version 2 of the phoenix code, which works great :exclamation: Among other things he has done a lot of work to improve the performance from version 1.

But there is always a need for speed :laughing: One of the bottle necks has been the communications between the BAP and the SSC-32. Currently in my versions of the code that was adapted to use XBEE input from the DIY remote, I have made some changes to the version 2.0 code to speed up these communications, which include:

a) If you are about to tell a servo to go to same place it is, don’t output the data. Should be a big win for example if you are doing one leg movements and the like…

b) Used my own serial output function that allowed me to drive the SSC-32 at full speed (115200). This has been working well for me and I think it works OK for Zenta as well.

Now this week, there is an Alpha version of new firmware for the SSC-32 that introduces a binary command set that reduces the number of characters that are transmitted, by maybe half which should again give us a speed up. Last night I made a version of my phoenix code that used this binary mode, which I think is working. I will do some more optimizing of this code later today (or tomorrow…)

I am also looking at maybe rearranging some of the code and would appreciate input. Example: The code below is the main code that drives the legs. It waits a sufficient amount of time for the previous command to complete before it issues the next command. It however has to do some fudging with the -45 on the sleep time to guess how long it will take to output the new command and subtract that from the time we wait.

[code] ;Drive Servos
IF HexOn THEN
IF HexOn AND Prev_HexOn=0 THEN
Sound P9,[60\4000,80\4500,100\5000]
Eyes = 1
ENDIF

;Set SSC time
IF(ABS(TravelLengthX)>cTravelDeadZone | ABS(TravelLengthZ)>cTravelDeadZone | ABS(TravelRotationY*2)>cTravelDeadZone) THEN
  SSCTime = NomGaitSpeed + (InputTimeDelay*2) + SpeedControl
  
  ;Add additional delay when Balance mode is on
  IF BalanceMode THEN
    SSCTime = SSCTime + 100
  ENDIF
  
ELSE ;Movement speed excl. Walking
  SSCTime = 200 + SpeedControl
ENDIF

;Sync BAP with SSC while walking to ensure the prev is completed before sending the next one
IF (GaitPosX(cRF) OR GaitPosX(cRM) OR GaitPosX(cRR) OR GaitPosX(cLF) OR GaitPosX(cLM) OR GaitPosX(cLR)  OR  |
	GaitPosY(cRF) OR GaitPosY(cRM) OR GaitPosY(cRR) OR GaitPosY(cLF) OR GaitPosY(cLM) OR GaitPosY(cLR)  OR  |
	GaitPosZ(cRF) OR GaitPosZ(cRM) OR GaitPosZ(cRR) OR GaitPosZ(cLF) OR GaitPosZ(cLM) OR GaitPosZ(cLR)  OR  |
	GaitRotY(cRF) OR GaitRotY(cRM) OR GaitRotY(cRR) OR GaitRotY(cLF) OR GaitRotY(cLM) OR GaitRotY(cLR)) THEN
	
  ;Get endtime and calculate wait time
  GOSUB GetCurrentTime], lTimerEnd	
  CycleTime = ((lTimerEnd-lTimerStart) * WTIMERTICSPERMSMUL) / WTIMERTICSPERMSDIV 

#ifdef DEBUG_MAIN
lsumCycleTime = lsumCycleTime + CycleTime ; BUGBUG::: debug
cCycleTime = cCycleTime + 1 ;
#endif
;Wait for previous commands to be completed while walking
pause (PrevSSCTime - CycleTime - 45) MIN 1 ; Min 1 ensures that there alway is a value in the pause command
ENDIF

GOSUB ServoDriver  	

[/code]

What I am thinking of doing differently is to try to take advantage that the SSC-32 does not do anything until the end of the command is received. In ASCII mode that is the CR and in binary mode when it receives the 3 byte move time: 0xe1 <Time Low).
That is to change the code such that before we do the pause we output all of the new command except the termination stuff and that way we only have the fudge of time for 0 (nothing changed) 1(normal mode) or 3 (binary mode) characters at the right time. Thoughts?

Also are there others who are interested in playing with stuff? That is should I try to build a version with most of these changes that would run on a phoenix/chr3 that does not rely on our xbee stuff (ie PS2 or serial…). If I do this I will probably not include the stuff for b) above as most of you probably don’t want to see a lot of assembly language stuff…

Kurt

That would be an awesome project and would probably have the most interested parties. T-Hex builders would also stand to benefit from this code. (coming soon) :smiley: Thanks Kurt!

I would like to see more development of the Phoenix code in the PS2 mode , the xbee’s are great but after playing with them I think a whole new code just using xbee’s would a new path for many of us where as the current PS2 is well developed and used by many, also on a sales point of view it would be very easy to adapt Xan’s code as it stands to the T-HEX and I for one would buy a T-Hex just to try Xan’s PS2 code on it.

My reasons for this are because while i’m able to understand the code i’m not 100% comfortable with it and it takes me more time than I have to keep altering the way we control the bot’s.

Be it wired, blue-tooth, PS2 , XBee etc. they all do the same thing with variations…they control the bot.

I would like to see more AI work with sensors, and work towards an autonomous bot with PS2 or whatever override controller.

but this is just my thought for today and thank’s for the already overwhelming info already on this forum.

Dave

Hi Putt Putt,

I hear you. Of course I am just doing this for the fun of it! Yes it adds to the fun that more people can use it, which is why I will port some of this back some of the changes into the current code base and to make sure that they are usable from the PS2. Also I am glad if it also helps Lynxmotion sell more products as I like the company a lot :smiley: Yes I hope we will simply be able to generate a new config file for the T-Hex and have it off and running. The only thing may depend on if the T-Hex has 3 servos per leg or 4. If 4 there will need to be additional changes made. I believe that Zenta had some of this working earlier.

I just downloaded a virgin copy of the code to start merging in changes. Currently the only types of changes I am merging in is to improve the performance. In particular on how fast we can do updates between the processor and the SSC-32.

a)Things like only output new values.
b) Faster outputs.
c) Maybe change from TimerW to TimerA which has lower resolution, but can reduce the number of interrupts.
d) Change to less guessing on delay.
e) Change the PS2, to try to speed up gaits and see how they work.

Ones these things are in place I will upload my private version for people to try out and then hopefully Xan will have a chance to review the changes and integrate it with the next release.

Then we can all start off on adding the other things we want, like checking sensors (like leg contact) or the like.

I agree that many of the things are just ways to control the bot, however I got sort-of spoiled with my XBEE-DIY remote as I added bi-directional communication and it is nice to hit a key on the remote and see which gait I selected.

Got to run.
Kurt

Hi kurt,

I’m happy to hear that the binary commands are available in a alpha release. I was very happy that I had the change to try them out some time ago. Mike did some great work with the SSC firmware and it really makes a huge difference in transfer speed. I did some smal scale tests with his new firmware especially for the query command used in the TA part. I got stuck in the TA math right after that so I didn’t had the time to rebuild the SSC communication part in my program. It would be great if you could fill me in there.

I also tought about only sending the changed values to the SSC. But with this code, all servos will change in every move. So it will only help when not moving or having aditional servos that are on the same position for a longer time.

I’m doing some work in our new house at the moment. I hope to participate when we’ve fully moved in to our new home.

Thanks,

Xan

Hey Xan,

Glad to here you are finally moving in! I wish I could have waited for you to finish your work with TA experiments, but too much time had gone by. I had to release it so Mike could finish the firmware. Enjoy your new house. Don’t get too many honey-do’s! Hope you will have more robot time in the future. Thanks! Jim

Hi Kurt,

It sounds like a good idea starting a new thread for this topic.
I’ve not had time to test out this binary mode yet, but I’m looking forward to it. Thanks for sharing your work though!

This sounds like an brilliant idea! I’m just wondering why this hasn’t been done before. Was there any chance that the “get current time” interrupt function messed up the communication part to the SSC32 at first?

If this is possible to do the cycle time would be much more accurate. I believe the Servodriver command must be done before the IF (GaitPosX(cRF) OR GaitPosX(cRM) OR ... command, since the pause command isn’t active when doing body movement. Actually, this part has puzzled me. Because when doing body rotation combined with walking the body rotation get very “choppy”. But thats another story…

Congratz with your new house Xan!

Btw, I hope you got some space for a little workshop too :wink:

The house should be built AROUND the workshop!

Alan KM6VV

I totally understand that! Mike did some awesome work with the new firmware and everybody should have the opportunity to use it!

Thanks for all the wishes on our new home. As for a workshop, I’ve claimed the whole 3rd floor which I’m gonna turn in to my “office” with a big desk and most of my tools. We’ve got plans to expand our house with a garage within a year or so. This should give me more room to do some mechanical adjustments without messing up the wooden floor. :wink:

Thanks, Xan

Hi Xan, Zenta and others.

I am glad to hear you are moving in! Congrats! You get a whole floor for your stuff! I am jealous :laughing:

I will play some more with this and let everyone who is interested try it out…

I can’t wait until you have a chance to work on your TA stuff!

Now back to questions and comments.

I did this earlier when I had times when the communication would get corrupted. I agree that for normal moves it did not help, but I found that when I was moving just one leg it helped. Also depending on how we try TA stuff I thought it might help there as well. This won’t be my highest priority to merge into the virgin copy as I think the biggest bang fix will be to convert the serouts to the binary. Also probably converting the 3 serouts per leg to 1 will also speed some stuff up as you don’t have the overhead time of reentering the serout function. May check later with logic analyzer.

Actually possible the biggest win is if we could run the SSC-32 at 115200 instead of 38400 as it is 3 times faster. I wish serout would work as i115200 is defined but when I tried it the SSC-32 did not like it and when I looked at it with the logic analyzer it was sufficiently off. I wonder if Nathan could fix it??? I Could integrate my TASerout function which is what I am currently using, but the coding interface is not fancy (ie a buffer and how many bytes to output).

You are right that the interrupt may have caused problems, especially with higher speeds like we are trying to achieve. But I think I have ways around it.

Convert from TimerW (16 bit) to timerA (8 bit). Why? The slowest you can increment TimerW is Clock/8 so you have 16000000/(8 * 65536)= 30+ interrupts per second. If you TimerA with clock/8192 you get only 16000000/(8192 * 256) or abouty 7.6 interrupts per second. I think the resolution of about 1950 ticks per second is sufficient.

Now my assumption is that it won’t take 1/8th of a second to output the serial outputs so we should be able to temporarily disable the timer interrupt while we are doing the serouts and reneanble it after we finish the serout, but before we get the timer, which should allow any pending timer interrupt to be processed and since we will not be disabled long enough to miss one. In fact could probably continue with timerW for now as I don’t think our serouts will take 1/30th of a second.

I hope that makes some sense?

Yes I would need to rearrange those ifs as well.

That is all for now, I suppose I should get to working on it!

Kurt

OK, I’m not up on this processor, but do you really want to disable the timer IRQ just to service a serial XMIT (or RCVR for that matter)? They should have sufficient buffering, such that it shouldn’t matter.

Lowering the rate of IRQ’s to the lowest possible will certainly cut down on the overhead (time spent servicing interrupts).

Just some thoughts.

I’m really fighting a C code translation from CCS to HighTech. All the data types in CCS are funny! Reminds me why I never ordered an update to my 16F CCS compiler. A CCS “short” is 1 bit? A CCS “long” is 16 bits? And they all default to unsigned. ugh!

Alan KM6VV

Remember when you do a serout command it is a bit bang function. So for each bit it has a timing loop that counts the number of cycles before it goes on to the next bit. So if my quick calculations are correct one bit at 38400 will cycle for about 416 clocks. If I understand correctly to be reasonably reliable you need to be within 3-5% of the actual baud rate, which maybe gives us ±20 cycles. I believe my assembly language interrupt handler takes something in the order of (60-70) clocks, which is why we sometimes with serouts even at lower speeds like 9600 baud.

It would be even worse with a basic implementation of the interrupt, which saves and restores 6-7 32 bit registers among other things which for the save/restore is something like 120-140 cycles.

I have not done any C programing on the pic, I have done some on the BAP(H8) and am also currently doing some on the AVR Mega 640 but that is a different thread.

Kurt

OK, you’re talking about still using bit-bang serial. Then it all makes sense. I thought you were using full interrupt driven serial.

I got a real surprise doing simple com on a PIC. This time I just used the USART routines furnished with the compiler. And LynxTerm 1.1. I’ve used it before for talking to the R/C PID motor control code I’m working on. Just simple putch() and hetch() routines. There are switches in LynxTerm for auto LF both ways. Even with these turned off, the PIC is getting extra CRs from LynxTerm, and dropping some printf() messages. I was short on time last night, but I did get proper action from another terminal emulator. I’ve never experienced THAT before! Really made debugging the routine that expected a CR between blocks of code! I’ll check out the 1.8 version, maybe it’s been fixed.

Alan KM6VV

The BAP28 has one UART (HSERIAL), but at 16mhz, you can not configure it to output at 115200. So the fastest you can configure it on the BAP to talk to the SSC-32 is again 38400.

Yep I wish I had the 4 UARTS I have on the ATMega640, but the BAP has many other nice features so…

Yeah, I’m tired of bit-bang.

And I just found out that I **DO ** have the latest LynxTerm. I should probably re-verify and start a new thread to document what I’m seeing. I can’t imagine anything else that could cause it. I have another terminal program that does work, so all is not lost (my ability to work on my code).

Perhaps Basic Micro should (if they haven’t) provide a CPU XTAL parameter, and allow a “proper” clock frequency that divides down to an exact com port osc frequency to be used. we **ALWAYS **used a specialized XTAL frequency to guarantee good com clock freq.

Alan KM6VV

Ok, I think I have finished pass 1 of merging some code in for binary mode using PS2 at i38400.

Had to dig up a PS2 controller module, as my others receivers are on Brats with the simple wiring on them… Grabbed my old sector 7, hopefully still works. Also I am trying plugging it into P0-3 with the built-in pull-up, as to not have to unplug xbee stuff. Waiting for battery to recharge. Probably good enough as I am to blinking green on the charger… So hopefully will have something up and running again soon!

All changes are under #ifdef, to make it easier for Xan to merge into his “Official” version…

Once I have this up and running I may try to also ifdef in a version of the TASerial for the faint of heart. They way you can run real turbo mode I115200 plus binary mode.

Also wondering if I should merge in a few other changes I have in my code, like: I found that if I tried to start a GP sequence that was not defined I might hang the SSC-32, so my code checks to see if that sequence is defined. Likewise I think I added an abort for a sequence when it started…

Kurt

Yah :smiley:

First pass is now walking again with PS2 and in binary at 38400. I think only the main phoenix file has the only real changes. So far my PS2 support file has changes to make it work with PS2 on P0-3. Also I ifdefed out a few of the PS2 init strings as I was having some problems, ended up plulling one of the PS2 receivers off my BRAT :frowning:

But in case any one wants to try it on a phoenix or the like here is the first pass. I included everything just in case.

Ok, I have hacked on this some more and merged in my own Serin/Serout functions that work well enough at 115200 to communicate with the SSC-32. So this version is configured for what I called “Turbo” mode. ie it outputs at 115200 with binary output/input so it should run pretty quick!. This is using the same functions I use in the XBee project, I just merged the code into the main file…

Some main Notes:

  1. I edited the both CFG files to turn on turbo mode but did not try the phoenix one as I don’t have one…
  2. You need to update the SSC-32 baud rate jumpers to 115200 (both on)
  3. Still need to test more, especially to run sequences
  4. I used notepad in the PS2 file in the zip file to try to make sure it was configured for PS2 on normal pins. May want to verify.
  5. Probably want to play some with the UI to see how fast we can make it!.

Let me know if any one tries this out and how it works. I will probably try to merge some of these changes back into the XBEE stuff for Zenta!

Kurt
SSC32 Binary mode check point.zip (26.1 KB)

On a side note: It would be great if we could simply use serout at i115200 instead of having to convert to my assembly language versions. When I mentioned this to Nathan, he knew that HSERIAL would not work at that baud rate but thought for sure it would work with serout. My assumption is that it has never worked at that baud rate as all of the programs/tutorials all change to 38400. So I wrote up a simple program that simply output “#0P1500T0”, 13 and had it output on P1 and then output on P2 using my function. I hooked up the logic analyzer on my test board and captured the outputs. I sent Nathan the program and outputs. Hopefully if we keep our fingers crossed he will be able to fix this!

Here is a sample output


When I had the logic analyzer try to understand the serial outputs, it worked fine with TASerout (second line), but not with Serout. I then told it to use AutoBaud rate, which it then properly identified the characters, but it thinks the output is at 125000.

The program minus my support functions was simply:

[code]BT bytetable “#0P1500T0”, 13

sound P9, [40\5000,40\5000] ; let we know we started…

Main:
serout p1, i115200, [str BT\10];
gosub TASerout[p2,i115200, @BT, 10]
pause 10
goto main[/code]
Kurt