Looks great.
It has been awhile since I played with the TA type code. Back then I had code some basic code to do some experiments. What I was curious about was which would give me better approximation of where the leg servos were when the contact happened. Asking the SSC-32 about it. This took the time to respond to the contact happening, plus the time to issue the command and then for it to respond. Or to approximate the position, by knowing when we issued the last command, where the servo was at that time, where the servo was moving to and how long the command was supposed to take and when the interrupt happened. My last set of code for this included:
[code]
;--------------------------------------------------------------------
;[ComputeFKYA] Compute FK for Y given the Femur and Tibia Angles in
; our coordinate system
#ifdef ENABLE_TA
; first try at figuring out FK for Y
FKYA var sword
FEA1 var sword
TEA1 var sword
FKY var sword
ComputeFKYA[FEA1, TEA1]:
gosub GetSinCos[900-FEA1]
FKY = (cos4 * cFemurLength)/10000 ; Sin or Cos - ???
gosub GetSinCos(900-FEA1)+(TEA1-900)]
FKY = FKY + (cos4*cTibiaLength)/10000 ; Double check these…
return FKY
FES1 var word
TES1 var word
FYKSS var sword ; do we need to invert the value
ComputeFKYS[FES1, TES1, FYKSS]
gosub ComputeFKYA(((FES1-650)*1059)/1000-900)*FYKSS, (((TES1-650)*1059)/1000-900)*FYKSS], FKY
return FKY
WKPINTTABLE bytetable WKPINT_0, WKPINT_1, WKPINT_2, WKPINT_3, WKPINT_4, WKPINT_5
#endif
'=====================================================
=======================================
’
’ Handle the WKPINT interrupt - This happens when a leg is moving down and the contract switch is
’ triggered.
#ifdef ENABLE_TA
_bWhichWKP var byte ’ Which WKP happened.
_lTimerWKP var long ’ Time when the WKP happened
_wDeltaTimeWKP var word ’ Delta time between start of command and when the WKP happened
_wWKPFemur var word ’ Guess for Femur
_wWKPTibia var word
_wFEMFromSSC var word
_wTIBFromSSC var word
_FKYFS var sword
_lSSCMask var long
_wFEMFromSSC2 var word
_wTIBFromSSC2 var word
_FKYFS2 var sword
Handle_WKP0:
_bWhichWKP = 0
disable WKPINT_0 ; only interrupt once per leg…
goto Handle_WKP
Handle_WKP1:
_bWhichWKP = 1
disable WKPINT_1 ; only interrupt once per leg…
goto Handle_WKP
Handle_WKP2:
_bWhichWKP = 2
disable WKPINT_2 ; only interrupt once per leg…
goto Handle_WKP
Handle_WKP3:
_bWhichWKP = 3
disable WKPINT_3 ; only interrupt once per leg…
goto Handle_WKP
Handle_WKP4:
_bWhichWKP = 4
disable WKPINT_4 ; only interrupt once per leg…
goto Handle_WKP
Handle_WKP5:
disable WKPINT_5 ; only interrupt once per leg…
_bWhichWKP = 5
Handle_WKP:
; Get the current time - interrupts not enabled so need to fix if a rollover happens
enable
gosub GetCurrentTime], _lTimerWKP
' Pass 1 lets see where we think the Y is by a few different methods...
_wDeltaTimeWKP = ((_lTimerWKP-lTimerStart) * WTIMERTICSPERMSMUL) / WTIMERTICSPERMSDIV
' Stop all servos...
disable ' let the serouts work
serout cSSC_OUT, cSSC_BAUD, [0xA2] ; Stop command...
' BUGBUG: using 38400 right now so can use serin/serout...
_wFEMFromSSC = 0
_wTIBFromSSC = 0
serout cSSC_OUT, cSSC_BAUD, "QP", dec cFemurPin(_bWhichWKP), "QP", dec cTibiaPin(_bWhichWKP),13]
serin cSSC_IN, cSSC_BAUD, 10000, _HWKP_TO, [_wFEMFromSSC.lowbyte, _wTIBFromSSC.lowbyte]
_HWKP_TO:
_wFEMFromSSC = _wFEMFromSSC * 10
_wTIBFromSSC = _wTIBFromSSC * 10
enable
; try bitmask way
disable
_lSSCMask = (1<<cFemurPin(_bWhichWKP))| (1 << cTibiaPin(_bWhichWKP)) ; generate the mask
serout cSSC_Out, cSSC_BAUD, [0xB0|(_lSSCMask & 0xf),(_lSSCMask>>4) & 0x7f, (_lSSCMask>>11) & 0x7f,(_lSSCMask>>18) & 0x7f,(_lSSCMask>>25) & 0x7f]
serin cSSC_In, cSSC_BAUD, 10000, _HWKP_TO2,[_wFEMFromSSC2.highbyte, _wFEMFromSSC2.lowbyte,_wTIBFromSSC2.highbyte, _wTIBFromSSC2.lowbyte];
_HWKP_TO2:
if prevssctime then
_wWKPFemur = awSSCFemurAnglePrev(_bWhichWKP) + |
((awSSCFemurAngle(_bWhichWKP)-awSSCFemurAnglePrev(_bWhichWKP)) * _wDeltaTimeWKP) / PrevSSCTime
_wWKPTibia = awSSCTibiaAnglePrev(_bWhichWKP) + |
((awSSCTibiaAnglePrev(_bWhichWKP)-awSSCTibiaAngle(_bWhichWKP)) * _wDeltaTimeWKP) / PrevSSCTime
if _bWhichWKP < 3 then
gosub ComputeFKYS[_wFEMFromSSC, _wTIBFromSSC, -1], _FKYFS
gosub ComputeFKYS[_wFEMFromSSC2, _wTIBFromSSC2, -1], _FKYFS2
gosub ComputeFKYS[_wWKPFemur, _wWKPTibia, -1]
else
gosub ComputeFKYS[_wTIBFromSSC, _wTIBFromSSC, 1], _FKYFS
gosub ComputeFKYS[_wTIBFromSSC2, _wTIBFromSSC2, 1], _FKYFS2
gosub ComputeFKYS[_wWKPFemur, _wWKPTibia, 1]
endif
#ifdef HSP_DEBUG
hserout HSP_DEBUG, [13, “WC: “, dec _bWhichWKP, " “, dec awSSCFemurAnglePrev(_bWhichWKP) ,”-”,dec awSSCFemurAngle(_bWhichWKP),|
" “, dec awSSCTibiaAnglePrev(_bWhichWKP), “-”, dec awSSCTibiaAngle(_bWhichWKP), |
" T:”, dec _wDeltaTimeWKP, “:”, dec prevssctime, |
“(”, dec _wWKPFemur,”,",dec _wWKPTibia,"=",sdec FKY,")"]
hserout HSP_DEBUG, “{”, dec _wFEMFromSSC, “,”,dec _wTIBFromSSC, “=”, sdec _FKYFS,"}","<", dec _wFEMFromSSC2, “,”,dec _wTIBFromSSC2, “=”, sdec _FKYFS2,">",13];
#else
disable
serout s_out, i9600, “WC: “, dec _bWhichWKP, “(”, dec _wWKPFemur,”,”,dec _wWKPTibia,"=",sdec FKY,")",13];
enable
#endif
endif
resume
#endif [/code]
This code is where I found the offset issue with the SSC-32. Should try it again, now that the bug was fixed. Also need to try on a hard surface to see if I can get better triggering with the SSC-32. If the approximation code looks at all promising, I may change the actual interrupt code to be in ASM, where it captures which leg and the time, and then probably does the rest in basic. Could be another triggered interrupt or could have the code check a state variable at several key points in the program…
I am also glad that you are getting some time to work on this again and can not wait to see how you process the leg information when contact is made.
Great work!
Kurt