Introducing the STALKER! (project ended)

I wish to share my code with everyone to see if i have made any mistakes.
the problem i am facing is that i havent managed to buy all the servos for this robot (due to cost) yet so i cannon test it.

from a visual assessment does the code look correct?

I hope anyone can help.

TO DO LIST:
'-------------------------
'1. Add Servo CONSTANTS/VARIABLES for: TurretsPan/Tilt (T-p/t for right and left) or Cannon ©

'T or C _PulseMin con ?
'T or C _PulseMax con ?

'T or C Pin con P#?

'T or C _Pulse var word


’ TC= (((TC_PulseMax - TC_PulseMin) * ((TravelLengthZ + 64 ) & $7F) |
’ / 127 + TC_PulseMax) min TC_PulseMin) max TC_PulseMax
'===================================================

'2. Update the positions of the servos [SERVO DRIVER]
’ ServoDriver:
’ leg
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretRTiltPin,“P”,dec TOINT(TOFLOAT(-?TurretRTiltAngle +45)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretRPanPin,“P”,dec TOINT(TOFLOAT(-?TurretRPanAngle+90)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretLTiltPin,“P”,dec TOINT(TOFLOAT(-?TurretLTiltAngle +45)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretLPanPin,“P”,dec TOINT(TOFLOAT(-?TurretLPanAngle+90)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?CannonPin,“P”,dec TOINT(TOFLOAT(-?CannonAngle+45)/0.10588238)+650]
'===================================================

'3 Add the Mechanical limits of the servos
;-----------------------------[MIN/MAX ANGLES]
'TurretRTiltAngle_Min con #?
'TurretRTiltAngle_Max con #?
'TurretRPanAngle_Min con #?
'TurretRPanAngle_Max con #?
'TurretLTiltAngle_Min con #?
'TurretLTiltAngle_Max con #?
'TurretLTiltAngle_Min con #?
'TurretLTiltAngle_Max con #?
'CannonAngle_Min con #?
'CannonAngle_Max con #?
'===================================================

[code] ;*************************************************
;===BotBoard with Basic ATOM 28 Pro, SSC32 V2===
;================& PS2 DualShock================
;====================STALKER===================**
;============================Quadruped Robot=============================
;**************************************************************************
;Description: Stalker robot with symmetrical Design
;Software version: V1.0
;Date: 15/01/09
;
;Programmer: Jonny Poole (aka Innerbreed)
;
;With Credit & Thanks to…
;Jeroen Janssen (aka Xan) for programming structure phoen1.3.bas (Black Widow)
;KÃ¥re Halvorsen (aka Zenta) for Balance Calculation phorip01.bas (Phoenix)
;
'==========================================================================
’ Quadruped Stalker Overview (Fig:1)
'--------------------
’ ±± <--------------------Gun Cannon} (rotates to follow Rotate direction, with Left Stick)
’ /^^
’ /-\ /-\
’ (-]_ / /]-) <---------------Gun Turrets} (up & down with Body, with D-pad)
’ |
|
’ /
]
\ <------------------Upper Body
’ ]_
/] } (rotates to follow Walk/Strafe direction, with Right Stick)
’ / // \ \ <-------Lower Body
’ /]=====] ]=====]
’ // \
’ | // \ | <-----Legs (see Fig:3)
’ // \/
’ \ /
’ \ /

'====================================================
’ Layout Diagram & X/Y/Z plane (Fig:2)
'----------------------
’ Back
’ 02 18
’ 01 17 Y+ Z+
’ 00_____16 | /
’ R | | L | /
’ i | | e |/
’ g | | f 0—X
’ h |
___| t |
’ t 08 24 |
’ 09 25 |
’ 10 26 Y- Z-
’ Front
'====================================================
’ 3DOF Leg Diagram (Fig:3)
'----------------------
’ [0]
’ / //
’ /[2]=====[1] 0= Coxa servo Length 70 [mm]
’ //
’ | // 1= Femur servo Length 130 [mm]
’ //
’ \ 2= Tibia servo Length 140 [mm]
’ \

'====================================================

;--------------------------------------------------------------------
;
;PS2 DualShock CONTROLS:
; - Start Turn on/off the bot
; - select Switch gaits
; - Left Stick Walk/Strafe
; - Right Stick Rotate
; - D-Pad up Body up 10 mm
; - D-Pad down Body down 10 mm
; - Triangle Move body to 35 mm from the ground (walk pos)
; - Circle Move body to the ground
; - Square Balance mode on or off
; - L1 & L. Stick Shift body X/Z
; - L1 & R. Stick Shift body Y and rotate body Y
; - L2 & Sticks Rotate body X/Y/Z
; - R2 & L. Stick X2 gait travel length
;
;KNOWN BUGS:
; - None at the moment :wink:
;
;====================================================================
;-----------------------------[CONSTANTS]
TRUE con 1
FALSE con 0

BUTTON_DOWN con 0
BUTTON_UP con 1
;--------------------------------------------------------------------
;-----------------------------[SERIAL CONNECTIONS]
SSC_OUT con P11 ;Output pin for (SSC32 RX) on BotBoard (Yellow)
SSC_IN con P10 ;Input pin for (SSC32 TX) on BotBoard (Red)
SSC_BAUTE con i38400 ;SSC32 Baute rate
;--------------------------------------------------------------------
;-----------------------------[PS2 DualShock Controller]
PS2DAT con P4 ;PS2 Controller DAT (Brown)
PS2CMD con P5 ;PS2 controller CMD (Orange)
PS2SEL con P6 ;PS2 Controller SEL (Blue)
PS2CLK con P7 ;PS2 Controller CLK (Black or White)
PadMode con $79
;--------------------------------------------------------------------
;-----------------------------[PIN NUMBERS]
RRCoxaPin con P0 ;Rear Right leg Hip Horizontal
RRFemurPin con P1 ;Rear Right leg Hip Vertical
RRTibiaPin con P2 ;Rear Right leg Knee

RFCoxaPin con P8 ;Front Right leg Hip Horizontal
RFFemurPin con P9 ;Front Right leg Hip Vertical
RFTibiaPin con P10 ;Front Right leg Knee

LRCoxaPin con P16 ;Rear Left leg Hip Horizontal
LRFemurPin con P17 ;Rear Left leg Hip Vertical
LRTibiaPin con P18 ;Rear Left leg Knee

LFCoxaPin con P24 ;Front Left leg Hip Horizontal
LFFemurPin con P25 ;Front Left leg Hip Vertical
LFTibiaPin con P26 ;Front Left leg Knee

BodyPin con P3 ;Body rotate con

;--------------------------------------------------------------------
;-----------------------------[MIN/MAX ANGLES]
RRCoxa_MIN con -26 ;Mechanical limits of the Right Rear Leg
RRCoxa_MAX con 74
RRFemur_MIN con -101
RRFemur_MAX con 95
RRTibia_MIN con -106
RRTibia_MAX con 77

RFCoxa_MIN con -58 ;Mechanical limits of the Right Front Leg
RFCoxa_MAX con 74
RFFemur_MIN con -101
RFFemur_MAX con 95
RFTibia_MIN con -106
RFTibia_MAX con 77

LRCoxa_MIN con -74 ;Mechanical limits of the Left Rear Leg
LRCoxa_MAX con 26
LRFemur_MIN con -95
LRFemur_MAX con 101
LRTibia_MIN con -77
LRTibia_MAX con 106

LFCoxa_MIN con -74 ;Mechanical limits of the Left Front Leg
LFCoxa_MAX con 58
LFFemur_MIN con -95
LFFemur_MAX con 101
LFTibia_MIN con -77
LFTibia_MAX con 106

Body_Min con 95 ;Mechanical limits of the Body rotate
Body_Max con -95
;--------------------------------------------------------------------
;-----------------------------[BODY/LEG DIMENSIONS]
CoxaLength con 70 ;Length of the Coxa [mm]
FemurLength con 130 ;Length of the Femur [mm]
TibiaLength con 140 ;Lenght of the Tibia [mm]

CoxaAngle con 90 ;Default Coxa setup angle
;pin08
RFOffsetX con -60 ;Distance X from center of the body to the Right Front coxa
RFOffsetZ con -75 ;Distance Z from center of the body to the Right Front coxa
;pin00
RROffsetX con -60 ;Distance X from center of the body to the Right Rear coxa
RROffsetZ con 75 ;Distance Z from center of the body to the Right Rear coxa
;pin24
LFOffsetX con 60 ;Distance X from center of the body to the Left Front coxa
LFOffsetZ con -75 ;Distance Z from center of the body to the Left Front coxa
;pin16
LROffsetX con 60 ;Distance X from center of the body to the Left Rear coxa
LROffsetZ con 75 ;Distance Z from center of the body to the Left Rear coxa
;--------------------------------------------------------------------
;-----------------------------[REMOTE]
TravelDeadZone con 4 ;The deadzone for the analog input from the remote
;====================================================================
;-----------------------------[ANGLES]
RFCoxaAngle var sword ;Actual Angle of the Right Front Leg
RFFemurAngle var sword
RFTibiaAngle var sword

RRCoxaAngle var sword ;Actual Angle of the Right Rear Leg
RRFemurAngle var sword
RRTibiaAngle var sword

LFCoxaAngle var sword ;Actual Angle of the Left Front Leg
LFFemurAngle var sword
LFTibiaAngle var sword

LRCoxaAngle var sword ;Actual Angle of the Left Rear Leg
LRFemurAngle var sword
LRTibiaAngle var sword

BodyAngle var sword ;Actual Angle of the Body rotate
;--------------------------------------------------------------------
;-----------------------------[POSITIONS]
RFPosX var sword ;Actual Position of the Right Front Leg
RFPosY var sword
RFPosZ var sword

RRPosX var sword ;Actual Position of the Right Rear Leg
RRPosY var sword
RRPosZ var sword

LFPosX var sword ;Actual Position of the Left Front Leg
LFPosY var sword
LFPosZ var sword

LRPosX var sword ;Actual Position of the Left Rear Leg
LRPosY var sword
LRPosZ var sword
;--------------------------------------------------------------------
;-----------------------------[INPUTS]
butA var bit
butB var bit
butC var bit

prev_butA var bit
prev_butB var bit
prev_butC var bit
;--------------------------------------------------------------------
;-----------------------------[OUTPUTS]
LedA var bit ;Red
LedB var bit ;Green
LedC var bit ;Orange
;--------------------------------------------------------------------
;-----------------------------[VARIABLES]
Index var byte ;Index used for freeing the servos
SSCDone var byte ;Char to check if SSC is done

;GetSinCos
AngleDeg var float ;Input Angle in degrees
ABSAngleDeg var float ;Absolute value of the Angle in Degrees
AngleRad var float ;Angle in Radian
sinA var float ;Output Sinus of the given Angle
cosA var float ;Output Cosinus of the given Angle

;GetBoogTan
BoogTanX var sword ;Input X
BoogTanY var sword ;Input Y
BoogTan var float ;Output BOOGTAN2(X/Y)

;Body position
BodyPosX var sbyte ;Global Input for the position of the body
BodyPosY var sword
BodyPosZ var sbyte

;Body Inverse Kinematics
BodyRotX var sbyte ;Global Input pitch of the body
BodyRotY var sbyte ;Global Input rotation of the body
BodyRotZ var sbyte ;Global Input roll of the body
PosX var sword ;Input position of the feet X
PosZ var sword ;Input position of the feet Z
PosY var sword ;Input position of the feet Y
RotationY var sbyte ;Input for rotation of a single feet for the gait
BodyOffsetX var sbyte ;Input Offset betweeen the body and Coxa X
BodyOffsetZ var sbyte ;Input Offset betweeen the body and Coxa Z
sinB var float ;Sin buffer for BodyRotX calculations
cosB var float ;Cos buffer for BodyRotX calculations
sinG var float ;Sin buffer for BodyRotZ calculations
cosG var float ;Cos buffer for BodyRotZ calculations
TotalX var sword ;Total X distance between the center of the body and the feet
TotalZ var sword ;Total Z distance between the center of the body and the feet
DistCenterBodyFeet var float ;Total distance between the center of the body and the feet
AngleCenterBodyFeetX var float ;Angle between the center of the body and the feet
BodyIKPosX var sword ;Output Position X of feet with Rotation
BodyIKPosY var sword ;Output Position Y of feet with Rotation
BodyIKPosZ var sword ;Output Position Z of feet with Rotation

;Leg Inverse Kinematics
IKFeetPosX var sword ;Input position of the Feet X
IKFeetPosY var sword ;Input position of the Feet Y
IKFeetPosZ var sword ;Input Position of the Feet Z
IKFeetPosXZ var sword ;Length between the coxa and feet
IKSW var float ;Length between shoulder and wrist
IKA1 var float ;Angle between SW line and the ground in rad
IKA2 var float ;?
IKSolution var bit ;Output true if the solution is possible
IKSolutionWarning var bit ;Output true if the solution is NEARLY possible
IKSolutionError var bit ;Output true if the solution is NOT possible
IKFemurAngle var sword ;Output Angle of Femur in degrees
IKTibiaAngle var sword ;Output Angle of Tibia in degrees
IKCoxaAngle var sword ;Output Angle of Coxa in degrees
;--------------------------------------------------------------------
;[PS2 DualShock Controller]
DualShock var Byte(7)
LastButton var Byte(2)
DS2Mode var Byte
PS2Index var byte
BodyYShift var sbyte
;--------------------------------------------------------------------
;-----------------------------[TIMING]
lTimerWOverflowCnt var long ;used in WTimer overflow. Will keep a 16 bit overflow so we have a 32 bit timer
lCurrentTime var long
lTimerStart var long ;Start time of the calculation cycles
lTimerEnd var long ;End time of the calculation cycles
CycleTime var byte ;Total Cycle time

SSCTime var word ;Time for servo updates
PrevSSCTime var word ;Previous time for the servo updates

InputTimeDelay var byte ;Delay that depends on the input to get the “sneaking” effect
;--------------------------------------------------------------------
;-----------------------------[GLOABAL]
QuadOn var bit ;Switch to turn on Stalker
;--------------------------------------------------------------------
;[Balance]
BalanceMode var bit
TravelHeightY var sword
TotalTransX var sword
TotalTransZ var sword
TotalTransY var sword
TotalYbal var sword
TotalXBal var sword
TotalZBal var sword
TotalY var sword ;Total Y distance between the center of the body and the feet

;[gait]
GaitType var byte ;Gait type
NomGaitSpeed var byte ;Nominal speed of the gait

LegLiftHeight var byte ;Current Travel height
TravelLengthX var sword ;Current Travel length X
TravelLengthZ var sword ;Current Travel length Z
TravelRotationY var sword ;Current Travel Rotation Y

TLDivFactor var byte ;Number of steps that a leg is on the floor while walking
NrLiftedPos var nib ;Number of positions that a single leg is lifted (1-3)
HalfLiftHeigth var bit ;If TRUE the outer positions of the ligted legs will be half height

GaitInMotion var bit ;Temp to check if the gait is in motion
StepsInGait var byte ;Number of steps in gait
LastLeg var bit ;TRUE when the current leg is the last leg of the sequence
GaitStep var byte ;Actual Gait step

RFGaitLegNr var byte ;Init position of the leg
RRGaitLegNr var byte ;Init position of the leg
LFGaitLegNr var byte ;Init position of the leg
LRGaitLegNr var byte ;Init position of the leg

GaitLegNr var byte ;Input Number of the leg
TravelMulti var sbyte ;Multiplier for the length of the step

RFGaitPosX var sbyte ;Relative position corresponding to the Gait
RFGaitPosY var sbyte
RFGaitPosZ var sbyte
RFGaitRotY var sbyte ;Relative rotation corresponding to the Gait

RRGaitPosX var sbyte
RRGaitPosY var sbyte
RRGaitPosZ var sbyte
RRGaitRotY var sbyte

LFGaitPosX var sbyte
LFGaitPosY var sbyte
LFGaitPosZ var sbyte
LFGaitRotY var sbyte

LRGaitPosX var sbyte
LRGaitPosY var sbyte
LRGaitPosZ var sbyte
LRGaitRotY var sbyte

GaitPosX var sbyte ;In-/Output Pos X of feet
GaitPosY var sword ;In-/Output Pos Y of feet
GaitPosZ var sbyte ;In-/Output Pos Z of feet
GaitRotY var sbyte ;In-/Output Rotation Y of feet
;====================================================================
;-----------------------------[TIMER INTERRUPT INIT]
ONASMINTERRUPT TIMERWINT, Handle_TIMERW
;====================================================================
;-----------------------------[INIT]
;Turning off all the leds
LedA = 0
LedB = 0
LedC = 0

'Feet Positions
RFPosX = 53 ;Start positions of the Right Front leg
RFPosY = 25
RFPosZ = -91

RRPosX = 53 ;Start positions of the Right Rear leg
RRPosY = 25
RRPosZ = 91

LFPosX = 53 ;Start positions of the Left Front leg
LFPosY = 25
LFPosZ = -91

LRPosX = 53 ;Start positions of the Left Rear leg
LRPosY = 25
LRPosZ = 91

;Body Positions
BodyPosX = 0
BodyPosY = 0
BodyPosZ = 0

;Body Rotations
BodyRotX = 0
BodyRotY = 0
BodyRotZ = 0

;Gait
GaitType = 0
BalanceMode = 0
LegLiftHeight = 50
GaitStep = 1
GOSUB GaitSelect

;Timer
WTIMERTICSPERMS con 2000; we have 16 clocks per ms and we are incrementing every 8 so divide again by 2
TCRW = 0x30 ;clears TCNT and sets the timer to inc clock cycle / 8
TMRW = 0x80 ;starts the timer counting
lTimerWOverflowCnt = 0
enable TIMERWINT_OVF

;PS2 DualShock controller
high PS2CLK
LastButton(0) = 255
LastButton(1) = 255
BodyYShift = 0

;SSC
SSCTime = 150
QuadOn = False
;====================================================================
;-----------------------------[MAIN]
main:
'Start time
GOSUB GetCurrentTime], lTimerStart

'Reset IKsolution indicators
IKSolution = False
IKSolutionWarning = False
IKSolutionError = False

;Gait
GOSUB GaitSeq

;Balance calculations
TotalTransX = 0 'reset values used for calculation of balance
TotalTransZ = 0
TotalTransY = 0
TotalXBal = 0
TotalYBal = 0
TotalZBal = 0
IF (BalanceMode>0) THEN
gosub BalCalcOneLeg -RFPosX+BodyPosX+RFGaitPosX, RFPosZ+BodyPosZ+RFGaitPosZ,RFGaitPosY, RFOffsetX, RFOffsetZ]
gosub BalCalcOneLeg -RRPosX+BodyPosX+RRGaitPosX, RRPosZ+BodyPosZ+RRGaitPosZ,RRGaitPosY, RROffsetX, RROffsetZ]
gosub BalCalcOneLeg [LFPosX-BodyPosX+LFGaitPosX, LFPosZ+BodyPosZ+LFGaitPosZ,LFGaitPosY, LFOffsetX, LFOffsetZ]
gosub BalCalcOneLeg [LRPosX-BodyPosX+LRGaitPosX, LRPosZ+BodyPosZ+LRGaitPosZ,LRGaitPosY, LROffsetX, LROffsetZ]
gosub BalanceBody
ENDIF

'Reset IKsolution indicators
IKSolution = False
IKSolutionWarning = False
IKSolutionError = False

;Right Front leg
GOSUB BodyIK -RFPosX+BodyPosX+RFGaitPosX, RFPosZ+BodyPosZ+RFGaitPosZ,RFPosY+BodyPosY+BodyYShift+RFGaitPosY, RFOffsetX, RFOffsetZ, RFGaitRotY]
GOSUB LegIK [RFPosX-BodyPosX+BodyIKPosX-RFGaitPosX, RFPosY+BodyPosY+BodyYShift-BodyIKPosY+RFGaitPosY, RFPosZ+BodyPosZ-BodyIKPosZ+RFGaitPosZ]
RFCoxaAngle = IKCoxaAngle + CoxaAngle ;Angle for the basic setup for the front leg
RFFemurAngle = IKFemurAngle
RFTibiaAngle = IKTibiaAngle

;Right Rear leg
GOSUB BodyIK -RRPosX+BodyPosX+RRGaitPosX, RRPosZ+BodyPosZ+RRGaitPosZ,RRPosY+BodyPosY+BodyYShift+RRGaitPosY, RROffsetX, RROffsetZ, RRGaitRotY]
GOSUB LegIK [RRPosX-BodyPosX+BodyIKPosX-RRGaitPosX, RRPosY+BodyPosY+BodyYShift-BodyIKPosY+RRGaitPosY, RRPosZ+BodyPosZ-BodyIKPosZ+RRGaitPosZ]
RRCoxaAngle = IKCoxaAngle - CoxaAngle ;Angle for the basic setup for the front leg
RRFemurAngle = IKFemurAngle
RRTibiaAngle = IKTibiaAngle

;Left Front leg
GOSUB BodyIK [LFPosX-BodyPosX+LFGaitPosX, LFPosZ+BodyPosZ+LFGaitPosZ,LFPosY+BodyPosY+BodyYShift+LFGaitPosY, LFOffsetX, LFOffsetZ, LFGaitRotY]
GOSUB LegIK [LFPosX+BodyPosX-BodyIKPosX+LFGaitPosX, LFPosY+BodyPosY+BodyYShift-BodyIKPosY+LFGaitPosY, LFPosZ+BodyPosZ-BodyIKPosZ+LFGaitPosZ]
LFCoxaAngle = IKCoxaAngle + CoxaAngle ;Angle for the basic setup for the front leg
LFFemurAngle = IKFemurAngle
LFTibiaAngle = IKTibiaAngle

;Left Rear leg
GOSUB BodyIK [LRPosX-BodyPosX+LRGaitPosX, LRPosZ+BodyPosZ+LRGaitPosZ,LRPosY+BodyPosY+BodyYShift+LRGaitPosY, LROffsetX, LROffsetZ, LRGaitRotY]
GOSUB LegIK [LRPosX+BodyPosX-BodyIKPosX+LRGaitPosX, LRPosY+BodyPosY+BodyYShift-BodyIKPosY+LRGaitPosY, LRPosZ+BodyPosZ-BodyIKPosZ+LRGaitPosZ]
LRCoxaAngle = IKCoxaAngle - CoxaAngle ;Angle for the basic setup for the front leg
LRFemurAngle = IKFemurAngle
LRTibiaAngle = IKTibiaAngle

GOSUB CheckAngles

LedC = IKSolutionWarning
LedA = IKSolutionError

;Read input
GOSUB Ps2Input
;GOSUB ReadButtons ;I/O used by the PS2 remote
;GOSUB WriteLeds ;I/O used by the PS2 remote

;Get endtime and calculate wait time
GOSUB GetCurrentTime], lTimerEnd
CycleTime = (lTimerEnd-lTimerStart)/WTIMERTICSPERMS

IF(QuadOn)THEN
;Wait for previous commands to be completed while walking
IF(ABS(TravelLengthX)>TravelDeadZone | ABS(TravelLengthZ)>TravelDeadZone | ABS(TravelRotationY*2)>TravelDeadZone) THEN

  pause (PrevSSCTime - CycleTime -50) MIN 1 ;	Min 1 ensures that there alway is a value in the pause command
  
  IF(BalanceMode=0)THEN
  	SSCTime = NomGaitSpeed + (InputTimeDelay*2)
  ELSE
  	SSCTime = NomGaitSpeed + (InputTimeDelay*2) + 100
  ENDIF
  
ELSE
  SSCTime = 200 ;NomGaitSpeed
ENDIF
	
GOSUB ServoDriver

ELSE
;Turn the bot off
GOSUB FreeServos
ENDIF
goto main
;====================================================================
;[ReadButtons] Reading input buttons from the ABB
ReadButtons:
input P4
input P5
input P6

prev_butA = butA
prev_butB = butB
prev_butC = butC

butA = IN4
butB = IN5
butC = IN6
return
;--------------------------------------------------------------------
;[WriteLEDs] Updates the state of the leds
WriteLEDs:
if ledA = 1 THEN
low p4
ENDIF
if ledB = 1 THEN
low p5
ENDIF
if ledC = 1 THEN
low p6
ENDIF
return
;-------------------------------------------------------------------------------------------------------------------
;-----------------------------[PS2 INPUT]

Ps2Input:

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8]
shiftin PS2DAT,PS2CLK,FASTLSBPOST,[DS2Mode\8]
high PS2SEL
pause 1

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8,$42\8]
shiftin PS2DAT,PS2CLK,FASTLSBPOST,[DualShock(0)\8, DualShock(1)\8, DualShock(2)\8, DualShock(3)\8, |
DualShock(4)\8, DualShock(5)\8, DualShock(6)\8]
high PS2SEL
pause 1

if DS2Mode <> PadMode THEN
low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
high PS2SEL
pause 1

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
high PS2SEL
pause 1

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
high PS2SEL
pause 1

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
high PS2SEL
pause 1

low PS2SEL
shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
high PS2SEL
pause 100
	
sound P9,[100\4000, 100\4500, 100\5000]
return

ENDIF
;------------------
IF (DualShock(1).bit3 = 0) and LastButton(0).bit3 THEN ;Start Button test
IF(QuadOn) THEN
'Turn off
Sound P9,[100\500,80\4500,60\4000]
BodyPosX = 0
BodyPosY = 0
BodyPosZ = 0
BodyRotX = 0
BodyRotY = 0
BodyRotZ = 0
TravelLengthX = 0
TravelLengthZ = 0
TravelRotationY = 0

  SSCTime = 600
  GOSUB ServoDriver
  QuadOn = False
ELSE
  'Turn on
  Sound P9,[60\400,80\4500,100\5000]
  SSCTime = 200
  QuadOn = True	
ENDIF

ENDIF
;------------------
IF QuadOn THEN
IF (DualShock(1).bit0 = 0) and LastButton(0).bit0 THEN ;Select Button test
IF TravelLengthX=0 & TravelLengthZ=0 & TravelRotationY=0 THEN

  ;Switch to next Gait type
	IF GaitType<7 THEN
	  Sound P9,[50\4000]
	  GaitType = GaitType+1
  	ELSE
	  Sound P9,[50\4000, 50\4500]
	  GaitType = 0
  	ENDIF

  	GOSUB GaitSelect
  ENDIF
ENDIF

;------------------
IF (DualShock(1).bit4 = 0) and LastButton(0).bit4 THEN ;Up Button test
BodyPosY = BodyPosY+10
ENDIF
;------------------
IF (DualShock(1).bit6 = 0) and LastButton(0).bit6 THEN ;Down Button test
BodyPosY = BodyPosY-10
ENDIF
;------------------
IF (DualShock(2).bit4 = 0) and LastButton(1).bit4 THEN ;Triangle Button test
BodyPosY = 35
ENDIF
;------------------
IF (DualShock(2).bit5 = 0) and LastButton(1).bit5 THEN ;Circle Button test
BodyPosY = 0
ENDIF
;------------------
’ IF (DualShock(2).bit6 = 0) and LastButton(1).bit6 THEN ;Cross Button test
’ ENDIF
;------------------
IF (DualShock(2).bit7 = 0) and LastButton(1).bit7 THEN ;Square Button test
IF BalanceMode = 0 THEN
BalanceMode = 1
sound P9,[100\4000, 50\8000]
ELSE
BalanceMode = 0
sound P9,[250\3000]
ENDIF
ENDIF
;------------------
IF (DualShock(2).bit3 = 0) THEN ;R1 Button test
LegLiftHeight = 80
ELSE
LegLiftHeight = 50
ENDIF
;------------------
BodyYShift = 0
IF (DualShock(2).bit2 = 0) THEN ;L1 Button test
BodyPosX = (Dualshock(5) - 128)/2
BodyPosZ = -(Dualshock(6) - 128)/3
BodyRotY = (Dualshock(3) - 128)/6
BodyYShift = (-(Dualshock(4) - 128)/2)MIN-(BodyPosY-10)

ELSEIF (DualShock(2).bit0 = 0) 	;L2 Button test
  BodyRotX = (Dualshock(6) - 128)/8
  BodyRotY = (Dualshock(3) - 128)/6
  BodyRotZ = (Dualshock(5) - 128)/8
  BodyYShift = (-(Dualshock(4) - 128)/2)MIN-(BodyPosY-10)
			
ELSE ;Walk
  'BodyPosX = 0
  'BodyPosZ = 0

  'BodyRotX = 0
  'BodyRotY = 0
  'BodyRotZ = 0

;------------------
IF (DualShock(2).bit1 = 0) THEN ;R2 Button test
TravelLengthX = -(Dualshock(5) - 128)
TravelLengthZ = (Dualshock(6) - 128)
ELSE
TravelLengthX = -(Dualshock(5) - 128)/2
TravelLengthZ = (Dualshock(6) - 128)/2
ENDIF

  TravelRotationY = -(Dualshock(3) - 128)/4
ENDIF

		 BodyPin=  (((Body_Max - Body_Min) * ((TravelLengthZ + 64 ) & $7F) |
	/ 127 + Body_Max) min Body_Min) max Body_Max

;------------------
;Calculate walking time delay
InputTimeDelay = 128 - (ABS((Dualshock(5) - 128)) MIN ABS((Dualshock(6) - 128))) MIN ABS((Dualshock(3) - 128))

ENDIF
;------------------
LastButton(0) = DualShock(1)
LastButton(1) = DualShock(2)
return
;-------------------------------------------------------------------------------------------------------------------
;-----------------------------[GAIT Select]
GaitSelect
;Gait selector
IF (GaitType = 0) THEN ;Ripple Gait 6 steps
LRGaitLegNr = 1
RFGaitLegNr = 2
RRGaitLegNr = 4
LFGaitLegNr = 5

NrLiftedPos = 1	  
TLDivFactor = 4	  
StepsInGait = 6
NomGaitSpeed = 150

ENDIF
;------------------
IF (GaitType = 1) THEN ;Ripple Gait 12 steps
LRGaitLegNr = 1
RFGaitLegNr = 3
RRGaitLegNr = 7
LFGaitLegNr = 9

NrLiftedPos = 3
HalfLiftHeigth = TRUE
TLDivFactor = 8	  
StepsInGait = 12	
NomGaitSpeed = 100

ENDIF
;------------------
IF (GaitType = 2) THEN ;Quadripple 9 steps
LRGaitLegNr = 1
RFGaitLegNr = 2
RRGaitLegNr = 5
LFGaitLegNr = 7

NrLiftedPos = 2
HalfLiftHeigth = FALSE	
TLDivFactor = 6	  
StepsInGait = 9	    
NomGaitSpeed = 150

ENDIF
;------------------
IF (GaitType = 3) THEN ;Tripod 4 steps
LRGaitLegNr = 3
RFGaitLegNr = 1
RRGaitLegNr = 1
LFGaitLegNr = 3

NrLiftedPos = 1	
TLDivFactor = 2	  
StepsInGait = 4	    
NomGaitSpeed = 150

ENDIF
;------------------
IF (GaitType = 4) THEN ;Tripod 6 steps
LRGaitLegNr = 4
RFGaitLegNr = 1
RRGaitLegNr = 1
LFGaitLegNr = 4

NrLiftedPos = 2
HalfLiftHeigth = FALSE	
TLDivFactor = 4	  
StepsInGait = 6	    
NomGaitSpeed = 150

ENDIF
;------------------
IF (GaitType = 5) THEN ;Tripod 8 steps
LRGaitLegNr = 5
RFGaitLegNr = 1
RRGaitLegNr = 1
LFGaitLegNr = 5

NrLiftedPos = 3
HalfLiftHeigth = TRUE	
TLDivFactor = 4	  
StepsInGait = 8	    
NomGaitSpeed = 110

ENDIF
;------------------
IF (GaitType = 6) THEN ;Wave 12 steps
LRGaitLegNr = 7
RFGaitLegNr = 1
RRGaitLegNr = 5
LFGaitLegNr = 11

NrLiftedPos = 1
HalfLiftHeigth = FALSE	
TLDivFactor = 10	  
StepsInGait = 12	    
NomGaitSpeed = 120

ENDIF
;------------------
IF (GaitType = 7) THEN ;Wave 18 steps
LRGaitLegNr = 10
RFGaitLegNr = 1
RRGaitLegNr = 7
LFGaitLegNr = 16

NrLiftedPos = 2
HalfLiftHeigth = FALSE	
TLDivFactor = 16	  
StepsInGait = 18	    
NomGaitSpeed = 100

ENDIF
return
;--------------------------------------------------------------------
;-----------------------------[GAIT Sequence]
GaitSeq
;Calculate Gait sequence
LastLeg = FALSE
GOSUB Gait [LRGaitLegNr, LRGaitPosX, LRGaitPosY, LRGaitPosZ, LRGaitRotY]
LRGaitPosX = GaitPosX
LRGaitPosY = GaitPosY
LRGaitPosZ = GaitPosZ
LRGaitRotY = GaitRotY

GOSUB Gait [RFGaitLegNr, RFGaitPosX, RFGaitPosY, RFGaitPosZ, RFGaitRotY]
RFGaitPosX = GaitPosX
RFGaitPosY = GaitPosY
RFGaitPosZ = GaitPosZ
RFGaitRotY = GaitRotY

GOSUB Gait [RRGaitLegNr, RRGaitPosX, RRGaitPosY, RRGaitPosZ, RRGaitRotY]
RRGaitPosX = GaitPosX
RRGaitPosY = GaitPosY
RRGaitPosZ = GaitPosZ
RRGaitRotY = GaitRotY

LastLeg = TRUE
GOSUB Gait [LFGaitLegNr, LFGaitPosX, LFGaitPosY, LFGaitPosZ, LFGaitRotY]
LFGaitPosX = GaitPosX
LFGaitPosY = GaitPosY
LFGaitPosZ = GaitPosZ
LFGaitRotY = GaitRotY

return
;--------------------------------------------------------------------
;-----------------------------[GAIT]
Gait [GaitLegNr, GaitPosX, GaitPosY, GaitPosZ, GaitRotY]

;Check IF the Gait is in motion
GaitInMotion = ((ABS(TravelLengthX)>TravelDeadZone) | (ABS(TravelLengthZ)>TravelDeadZone) | (ABS(TravelRotationY)>TravelDeadZone) )

;Leg middle up position
;Gait in motion Gait NOT in motion, return to home position
IF (GaitInMotion & (NrLiftedPos=1 | NrLiftedPos=3) & GaitStep=GaitLegNr) | (GaitInMotion=FALSE & GaitStep=GaitLegNr & ((ABS(GaitPosX)>2) | (ABS(GaitPosZ)>2) | (ABS(GaitRotY)>2))) THEN ;Up
GaitPosX = 0
GaitPosY = -LegLiftHeight
GaitPosZ = 0
GaitRotY = 0
ELSE

;Optional Half heigth Rear
IF ((NrLiftedPos=2 & GaitStep=GaitLegNr) | (NrLiftedPos=3 & (GaitStep=GaitLegNr-1 | GaitStep=GaitLegNr+(StepsInGait-1)))) & GaitInMotion THEN
  GaitPosX = -TravelLengthX/2
  GaitPosY = -LegLiftHeight/(HalfLiftHeigth+1)
  GaitPosZ = -TravelLengthZ/2
  GaitRotY = -TravelRotationY/2
ELSE
  
  ;Optional half heigth front
  IF (NrLiftedPos>=2) & (GaitStep=GaitLegNr+1 | GaitStep=GaitLegNr-(StepsInGait-1)) & GaitInMotion THEN
    GaitPosX = TravelLengthX/2
    GaitPosY = -LegLiftHeight/(HalfLiftHeigth+1)
    GaitPosZ = TravelLengthZ/2
    GaitRotY = TravelRotationY/2
  ELSE  	  

  	;Leg front down position
  	IF (GaitStep=GaitLegNr+NrLiftedPos | GaitStep=GaitLegNr-(StepsInGait-NrLiftedPos)) & GaitPosY<0 THEN
      GaitPosX = TravelLengthX/2
      GaitPosY = 0
      GaitPosZ = TravelLengthZ/2
      GaitRotY = TravelRotationY/2

  	;Move body forward      
  	ELSE
      GaitPosX = GaitPosX - (TravelLengthX/TLDivFactor)     
      GaitPosY = 0
      GaitPosZ = GaitPosZ - (TravelLengthZ/TLDivFactor)
      GaitRotY = GaitRotY - (TravelRotationY/TLDivFactor)
    ENDIF
  ENDIF
ENDIF

ENDIF

;Advance to the next step
IF LastLeg THEN ;The last leg in this step
GaitStep = GaitStep+1
IF GaitStep>StepsInGait THEN
GaitStep = 1
ENDIF
ENDIF

return
;--------------------------------------------------------------------
;-----------------------------[BalCalcOneLeg]
BalCalcOneLeg [PosX, PosZ, PosY, BodyOffsetX, BodyOffsetZ]
;Calculating totals from center of the body to the feet
TotalZ = BodyOffsetZ+PosZ
TotalX = BodyOffsetX+PosX
TotalY = 150 + PosY’ using the value 150 to lower the centerpoint of rotation 'BodyPosY +
TotalTransY = TotalTransY + PosY
TotalTransZ = TotalTransZ + TotalZ
TotalTransX = TotalTransX + TotalX
gosub GetBoogTan [TotalX, TotalZ]
TotalYbal = TotalYbal + TOINT((BoogTan180.0) / 3.141592)
gosub GetBoogTan [TotalX, TotalY]
TotalZbal = TotalZbal + TOINT((BoogTan
180.0) / 3.141592)
gosub GetBoogTan [TotalZ, TotalY]
TotalXbal = TotalXbal + TOINT((BoogTan*180.0) / 3.141592)
'serout S_OUT, i9600, “BalOneLeg PosX=”, sdec PosX," PosZ=", sdec PosZ," TotalXTransZ=", sdec TotalTransZ, 13]
return
;--------------------------------------------------------------------
;-----------------------------[BalanceBody]
BalanceBody:
TotalTransZ = TotalTransZ/6
TotalTransX = TotalTransX/6
TotalTransY = TotalTransY/6
if TotalYbal < -180 then 'Tangens fix caused by +/- 180 deg
TotalYbal = TotalYbal + 360
endif
if TotalZbal < -180 then 'Tangens fix caused by +/- 180 deg
TotalZbal = TotalZbal + 360
endif
if TotalXbal < -180 then 'Tangens fix caused by +/- 180 deg
TotalXbal = TotalXbal + 360
endif

;Balance rotation
TotalYBal = TotalYbal/6
TotalXBal = TotalXbal/6
TotalZBal = -TotalZbal/6
	
;Balance translation
LFGaitPosZ = LFGaitPosZ - TotalTransZ
LRGaitPosZ = LRGaitPosZ - TotalTransZ
RFGaitPosZ = RFGaitPosZ - TotalTransZ
RRGaitPosZ = RRGaitPosZ - TotalTransZ

LFGaitPosX = LFGaitPosX - TotalTransX
LRGaitPosX = LRGaitPosX - TotalTransX
RFGaitPosX = RFGaitPosX - TotalTransX
RRGaitPosX = RRGaitPosX - TotalTransX 

LFGaitPosY = LFGaitPosY - TotalTransY
LRGaitPosY = LRGaitPosY - TotalTransY
RFGaitPosY = RFGaitPosY - TotalTransY
RRGaitPosY = RRGaitPosY - TotalTransY

return
;--------------------------------------------------------------------
;[GETSINCOS] Get the sinus and cosinus from the angle +/- multiple circles
;AngleDeg - Input Angle in degrees
;SinA - Output Sinus of AngleDeg
;CosA - Output Cosinus of AngleDeg
GetSinCos [AngleDeg]

;Get the absolute value of AngleDeg
IF AngleDeg < 0.0 THEN
  ABSAngleDeg = AngleDeg *-1.0
ELSE
  ABSAngleDeg = AngleDeg
ENDIF

;Shift rotation to a full circle of 360 deg -> AngleDeg // 360
IF AngleDeg < 0.0 THEN	;Negative values
	AngleDeg = 360.0-(ABSAngleDeg-TOFLOAT(360*(TOINT(ABSAngleDeg/360.0))))
ELSE				;Positive values
	AngleDeg = ABSAngleDeg-TOFLOAT(360*(TOINT(ABSAngleDeg/360.0)))
ENDIF

IF AngleDeg < 180.0 THEN	;Angle between 0 and 180
	;Subtract 90 to shift range
	AngleDeg = AngleDeg -90.0
	;Convert degree to radials
	AngleRad = (AngleDeg*3.141592)/180.0
	
	SinA = FCOS(AngleRad)		;Sin o to 180 deg = cos(Angle Rad - 90deg)
	CosA = -FSIN(AngleRad)	;Cos 0 to 180 deg = -sin(Angle Rad - 90deg)
	
ELSE	;Angle between 180 and 360
	;Subtract 270 to shift range
	AngleDeg = AngleDeg -270.0
	;Convert degree to radials
	AngleRad = (AngleDeg*3.141592)/180.0
	
	SinA = -FCOS(AngleRad)		;Sin 180 to 360 deg = -cos(Angle Rad - 270deg)
	CosA = FSIN(AngleRad)	;Cos 180 to 360 deg = sin(Angle Rad - 270deg)
ENDIF

return
;--------------------------------------------------------------------
;[BOOGTAN2] Gets the Inverse Tangus from X/Y with the where Y can be zero or negative
;BoogTanX - Input X
;BoogTanY - Input Y
;BoogTan - Output BOOGTAN2(X/Y)
GetBoogTan [BoogTanX, BoogTanY]
IF(BoogTanX = 0) THEN ; X=0 -> 0 or PI
IF(BoogTanY >= 0) THEN
BoogTan = 0.0
ELSE
BoogTan = 3.141592
ENDIF
ELSE

	IF(BoogTanY = 0) THEN	; Y=0 -> +/- Pi/2
		IF(BoogTanX > 0) THEN
			BoogTan = 3.141592 / 2.0
		ELSE
			BoogTan = -3.141592 / 2.0
		ENDIF
	ELSE
		
		IF(BoogTanY > 0) THEN	;BOOGTAN(X/Y)
			BoogTan = FATAN(TOFLOAT(BoogTanX) / TOFLOAT(BoogTanY))
		ELSE	
			IF(BoogTanX > 0) THEN	;BOOGTAN(X/Y) + PI	
				BoogTan = FATAN(TOFLOAT(BoogTanX) / TOFLOAT(BoogTanY)) + 3.141592
			ELSE					;BOOGTAN(X/Y) - PI	
				BoogTan = FATAN(TOFLOAT(BoogTanX) / TOFLOAT(BoogTanY)) - 3.141592
			ENDIF
		ENDIF
	ENDIF
ENDIF

return
;--------------------------------------------------------------------
;-----------------------------[BODY INVERSE KINEMATICS]
;BodyRotX - Global Input pitch of the body
;BodyRotY - Global Input rotation of the body
;BodyRotZ - Global Input roll of the body
;RotationY - Input Rotation for the gait
;PosX - Input position of the feet X
;PosZ - Input position of the feet Z
;BodyOffsetX - Input Offset betweeen the body and Coxa X
;BodyOffsetZ - Input Offset betweeen the body and Coxa Z
;SinB - Sin buffer for BodyRotX
;CosB - Cos buffer for BodyRotX
;SinG - Sin buffer for BodyRotZ
;CosG - Cos buffer for BodyRotZ
;BodyIKPosX - Output Position X of feet with Rotation
;BodyIKPosY - Output Position Y of feet with Rotation
;BodyIKPosZ - Output Position Z of feet with Rotation
BodyIK [PosX, PosZ, PosY, BodyOffsetX, BodyOffsetZ, RotationY]

;Calculating totals from center of the body to the feet
TotalZ = BodyOffsetZ+PosZ
TotalX = BodyOffsetX+PosX
;PosY are equal to a “TotalY”

;Successive global rotation matrix:
;Math shorts for rotation: Alfa (A) = Xrotate, Beta (B) = Zrotate, Gamma (G) = Yrotate
;Sinus Alfa = sinA, cosinus Alfa = cosA. and so on…

;First calculate sinus and cosinus for each rotation:
GOSUB GetSinCos [TOFLOAT(BodyRotX+TotalXBal)]
SinG = SinA
CosG = CosA
GOSUB GetSinCos [TOFLOAT(BodyRotZ+TotalZBal)]
SinB = SinA
CosB = CosA
GOSUB GetSinCos [TOFLOAT(BodyRotY+RotationY+TotalYBal)]

;Calcualtion of rotation matrix:
BodyIKPosX = TotalX-TOINT(TOFLOAT(TotalX)CosACosB - TOFLOAT(TotalZ)CosBSinA + TOFLOAT(PosY)SinB)
BodyIKPosZ = TotalZ-TOINT(TOFLOAT(TotalX)CosGSinA + TOFLOAT(TotalX)CosASinB
SinG +TOFLOAT(TotalZ)CosACosG-TOFLOAT(TotalZ)SinASinBSinG-TOFLOAT(PosY)CosBSinG)
BodyIKPosY = PosY - TOINT(TOFLOAT(TotalX)SinASinG - TOFLOAT(TotalX)CosACosG
SinB + TOFLOAT(TotalZ)CosASinG + TOFLOAT(TotalZ)CosGSinA*SinB + TOFLOAT(PosY)CosBCosG)

return
;--------------------------------------------------------------------
;-----------------------------[LEG INVERSE KINEMATICS] Calculates the angles of the tibia and femur for the given position of the feet
;IKFeetPosX - Input position of the Feet X
;IKFeetPosY - Input position of the Feet Y
;IKFeetPosZ - Input Position of the Feet Z
;IKSolution - Output true IF the solution is possible
;IKSolutionWarning - Output true IF the solution is NEARLY possible
;IKSolutionError - Output true IF the solution is NOT possible
;IKFemurAngle - Output Angle of Femur in degrees
;IKTibiaAngle - Output Angle of Tibia in degrees
;IKCoxaAngle - Output Angle of Coxa in degrees
LegIK [IKFeetPosX, IKFeetPosY, IKFeetPosZ]

;Length between the Coxa and Feet
IKFeetPosXZ = TOINT(FSQRT(TOFLOAT((IKFeetPosX*IKFeetPosX)+(IKFeetPosZ*IKFeetPosZ))))

;IKSW - Length between shoulder and wrist
IKSW = FSQRT(TOFLOAT(((IKFeetPosXZ-CoxaLength)*(IKFeetPosXZ-CoxaLength))+(IKFeetPosY*IKFeetPosY)))
	
;IKA1 - Angle between SW line and the ground in rad
GOSUB GetBoogTan [IKFeetPosXZ-CoxaLength, IKFeetPosY]
IKA1 = BoogTan

;IKA2 - ?
IKA2 = FACOS((TOFLOAT((FemurLength*FemurLength) - (TibiaLength*TibiaLength)) + (IKSW*IKSW)) / (TOFLOAT(2*Femurlength) * IKSW))

;IKFemurAngle
IKFemurAngle = (TOINT(((IKA1 + IKA2) * 180.0) / 3.141592)*-1)+90

;IKTibiaAngle
IKTibiaAngle = (90-TOINT(((FACOS((TOFLOAT((FemurLength*FemurLength) + (TibiaLength*TibiaLength)) - (IKSW*IKSW)) / TOFLOAT(2*Femurlength*TibiaLength)))*180.0) / 3.141592)) * -1

;IKCoxaAngle
GOSUB GetBoogTan [IKFeetPosZ, IKFeetPosX]
IKCoxaAngle = TOINT((BoogTan*180.0) / 3.141592)
	
;Set the Solution quality	
IF(IKSW < TOFLOAT(FemurLength+TibiaLength-30)) THEN
	IKSolution = TRUE
ELSE
	IF(IKSW < TOFLOAT(FemurLength+TibiaLength)) THEN
		IKSolutionWarning = TRUE
	ELSE
		IKSolutionError = TRUE	
	ENDIF
ENDIF		

return
;--------------------------------------------------------------------
;[CHECK ANGLES] Checks the mechanical limits of the servos
CheckAngles:
RFCoxaAngle = (RFCoxaAngle min RFCoxa_MIN) max RFCoxa_MAX
RFFemurAngle = (RFFemurAngle min RFFemur_MIN) max RFFemur_MAX
RFTibiaAngle = (RFTibiaAngle min RFTibia_MIN) max RFTibia_MAX

RRCoxaAngle = (RRCoxaAngle min RRCoxa_MIN) max RRCoxa_MAX
RRFemurAngle = (RRFemurAngle min RRFemur_MIN) max RRFemur_MAX
RRTibiaAngle = (RRTibiaAngle min RRTibia_MIN) max RRTibia_MAX

LFCoxaAngle = (LFCoxaAngle min LFCoxa_MIN) max LFCoxa_MAX
LFFemurAngle = (LFFemurAngle min LFFemur_MIN) max LFFemur_MAX
LFTibiaAngle = (LFTibiaAngle min LFTibia_MIN) max LFTibia_MAX

LRCoxaAngle = (LRCoxaAngle min LRCoxa_MIN) max LRCoxa_MAX
LRFemurAngle = (LRFemurAngle min LRFemur_MIN) max LRFemur_MAX
LRTibiaAngle = (LRTibiaAngle min LRTibia_MIN) max LRTibia_MAX

BodyAngle = (BodyAngle min Body_MIN) max Body_MAX
return
;--------------------------------------------------------------------
;[SERVO DRIVER] Updates the positions of the servos
ServoDriver:
;Front Right leg
serout SSC_OUT,SSC_BAUTE,"#",dec RFCoxaPin,“P”,dec TOINT(TOFLOAT(-RFCoxaAngle +90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec RFFemurPin,“P”,dec TOINT(TOFLOAT(-RFFemurAngle+90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec RFTibiaPin,“P”,dec TOINT(TOFLOAT(-RFTibiaAngle+90)/0.10588238)+650]

;Rear Right leg
serout SSC_OUT,SSC_BAUTE,"#",dec RRCoxaPin,“P”,dec TOINT(TOFLOAT(-RRCoxaAngle +90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec RRFemurPin,“P”,dec TOINT(TOFLOAT(-RRFemurAngle+90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec RRTibiaPin,“P”,dec TOINT(TOFLOAT(-RRTibiaAngle+90)/0.10588238)+650]

;Front Left leg
serout SSC_OUT,SSC_BAUTE,"#",dec LFCoxaPin,“P”,dec TOINT(TOFLOAT(LFCoxaAngle +90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec LFFemurPin,“P”,dec TOINT(TOFLOAT(LFFemurAngle+90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec LFTibiaPin ,“P”,dec TOINT(TOFLOAT(LFTibiaAngle+90)/0.10588238)+650]

;Rear Left leg
serout SSC_OUT,SSC_BAUTE,"#",dec LRCoxaPin,“P”,dec TOINT(TOFLOAT(LRCoxaAngle +90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec LRFemurPin,“P”,dec TOINT(TOFLOAT(LRFemurAngle+90)/0.10588238)+650]
serout SSC_OUT,SSC_BAUTE,"#",dec LRTibiaPin,“P”,dec TOINT(TOFLOAT(LRTibiaAngle+90)/0.10588238)+650]

serout SSC_OUT,SSC_BAUTE,"#",dec BodyPin,“P”,dec TOINT(TOFLOAT(BodyAngle +90)/0.10588238)+650]

;Send
serout SSC_OUT,SSC_BAUTE,“T”,dec SSCTime,13]

PrevSSCTime = SSCTime
return
;--------------------------------------------------------------------
;[FREE SERVOS] Frees all the servos
FreeServos
for Index = 0 to 31
serout SSC_OUT,SSC_BAUTE,"#",DEC Index,“P0”]
next
serout SSC_OUT,SSC_BAUTE,“T200”,13]
return
;-----------------------------------------------------------------------------------
;[Handle TimerW interrupt]
BEGINASMSUB
HANDLE_TIMERW
push.w r1 ; save away register we will use
bclr #7,@TSRW:8 ; clear the overflow bit in the Timer status word
mov.w @LTIMERWOVERFLOWCNT+1:16,r1 ; We will increment the word that is the highword for a clock timer
inc.w #1,r1
mov.w r1, @LTIMERWOVERFLOWCNT+1:16
pop.w r1 ; restore our registers
rte ; and return
return
;-------------------------------------------------------------------------------------
;[Simple function to get the current time and verify that no overflow happened]
GetCurrentTime
lCurrentTime = lTimerWoverflowCnt + TCNT ; calculate the timer
IF lCurrentTime.highword <> lTimerWOverflowcnt.highword THEN
lCurrentTime = lTimerWoverflowCnt + TCNT ; calculate the timer
ENDIF
return lCurrentTIme
;--------------------------------------------------------------------END-----------------------------------

;TO DO LIST:
'-------------------------
'1. Add Servo CONSTANTS/VARIABLES for: TurretsPan/Tilt (T-p/t for right and left) or Cannon ©

'T or C _PulseMin con 600
'T or C _PulseMax con 2400

'T or C Pin con P#?

'T or C _Pulse var word


’ TC= (((TC_PulseMax - TC_PulseMin) * ((TravelLengthZ + 64 ) & $7F) |
’ / 127 + TC_PulseMax) min TC_PulseMin) max TC_PulseMax
'===================================================

'2. Update the positions of the servos [SERVO DRIVER]
’ ServoDriver:
’ leg
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretRTiltPin,“P”,dec TOINT(TOFLOAT(-?TurretRTiltAngle +45)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretRPanPin,“P”,dec TOINT(TOFLOAT(-?TurretRPanAngle+90)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretLTiltPin,“P”,dec TOINT(TOFLOAT(-?TurretLTiltAngle +45)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?TurretLPanPin,“P”,dec TOINT(TOFLOAT(-?TurretLPanAngle+90)/0.10588238)+650]
’ serout SSC_OUT,SSC_BAUTE,"#",dec ?CannonPin,“P”,dec TOINT(TOFLOAT(-?CannonAngle+45)/0.10588238)+650]
'===================================================

'3 Add the Mechanical limits of the servos
;-----------------------------[MIN/MAX ANGLES]
'TurretRTiltAngle_Min con #?
'TurretRTiltAngle_Max con #?
'TurretRPanAngle_Min con #?
'TurretRPanAngle_Max con #?
'TurretLTiltAngle_Min con #?
'TurretLTiltAngle_Max con #?
'TurretLTiltAngle_Min con #?
'TurretLTiltAngle_Max con #?
'CannonAngle_Min con #?
'CannonAngle_Max con #?
'=================================================== [/code]

I’ve got no idea…

but this code looks kinda familiar…

:unamused: :wink:

i have mentioned that the code has been writen with the skills of yourself and zenta,

;With Credit & Thanks to... ;Jeroen Janssen (aka Xan) for programming structure *phoen1.3.bas* (Black Widow) ;KÃ¥re Halvorsen (aka Zenta) for Balance Calculation *phorip01.bas* (Phoenix)

hope you dont mind.?

guess i will need to wait till i can compile the code… :unamused: :unamused:

Thanks XAN!

No No! Don’t get me wrong. I was just joking!

share, use, improve + innovate!
thank you.

You’ve got it! :wink:

**Here i have re-made the chassis using 1050 aluminium.
Also i have managed to utilize the cube “that i wanted to get rid of” to hold an electronic (SSC-32) carrier made from Lexan.

Also i have gained room by lifting up the top body!

The idea for having the SSC on the lower body is that there are many more servo wires connecting to it from the lower half than there is from the top.
I have come up with a nice little idea to house the wires from the top half to the bottom without snagging! but i wont post that yet.

To save more space and to neaten it up, i will be shortening the servo wires from the legs so that there will only be enough wire to allow for movement!

The BotBoard will remain at the top and the power/data/etc wires will follow the servo wires up inside the body.**
http://i531.photobucket.com/albums/dd355/innerbreed/100_0819.jpg

now all i have to do is figure out were to put the battery’s!!
:confused:

Hi,

Looking good!
What are the dimensions of the battery pack? Placing the package as low as possible would be a good idea I think :wink:

yeah i have had it in mind to put it on the underside of the chassis.

not yet looked at batterys yet…
think ill be using a Lipo! :laughing:

LiPo’s are often rather long shaped. Maybe the new A123-system cells or a custom NiMh pack are easier to make fit. I don’t know, you probably have to search around to see what might fit. Or maybe using two smaller LiPo packs?

yeah been looking at something like these:


i will research this more when i come to it.
thanks.

i do still have my 6.0 Volt Ni-MH 2800mAh Battery Pack from my hex project so i may use that. its a bit over sized (1.875" x 4.375" x 0.9375) but why buy another!

I think if you mount the SSC-32 inverted, it would be better. The servo wires I think might get snagged by the turret rotating. Just some feedback. Since most of the servos are the legs, it would allow for better routing.

wierd! i was just thiking the same thing just that second. thats one of the reason for the carrier having the sides cut out like the LM one.

also when i start programming, i wont have the top half connected. ill be working on the gait programming and IK first. once i have the right control i will add the rest of the robot top and vacuum parts…

thanks.

these batteries are also pretty inexpensive I used them for my 5 cell pack in my Phoenix , honestly it seems that 4700Mah is the cutoff for capacity for NiMh batteries without going to LiPo.
batteryjunction.com/tenergy-sub-c-4700.html

The batteries come with tab’s too so you can make whatever size shape you want.

It’s funny yesterday I looked at the amount of brackets and tidbits lynxmotion sells and I was kinda surprised I had no idea they sold that many bracket’s!

I think it would be quite funny to put some “robster craws” on the phoenix , the Johnny 5 grippers look pretty mean.

Loookin cool Innerbreed.

Pretty creative taking a fictional object and trying to make it in real life, I believe this might give some people some interesting ideas

youtube.com/watch?v=dUsbIBzy87g

The thing is 38 bucks at o-like.com from china… I ordered one why… NO IDEA but its a flipping beam of light that burns! how cool. I think you should attach this to Johnny 5 :stuck_out_tongue:

Anyway very cool very cool, be interesting to see how your plastic armor like pieces turn out, I think I’ve seen a couple guides on youtube about how to make your own vacuum formed pieces

i did consider lasers that burn! i looked up on modding/hacking normal laser diodes to higher powered ones. youtube has vids of this.

thanks for your kind comments, the vacuum parts for the femur are finished its just they are still with the guy who’s done them for me… and… he’s gone on holiday! :angry:

just a progress update:

This close up also shows the hacked PS2 cable, and the shortend servo wires:
http://i531.photobucket.com/albums/dd355/innerbreed/100_0845.jpg
http://i531.photobucket.com/albums/dd355/innerbreed/100_0844.jpg

http://i531.photobucket.com/albums/dd355/innerbreed/100_0847.jpg

Still a long way to go, mainly lacking servos.
The code is written but untested,
The main structure is nearly built but still under development,
The Tibia ends still need to be designed and made,

lots more to do…
:cry:

What servos do you plan on using for this? Those are pretty long segments in between servos, which will require a ton of torque. I would think 5990s at minimum.

at th price of the HSR-5990TG (417 oz. in.) Digital Standard Servo i think not… would be nice.

i only plan on using 645’s! would this be enough?

i have been thinking about making the segments shorter ill only know once i have got it working.

Hi,

Great to see an overview of the complete construction, looking good. But as Tyberius mention the long “femur” part demands much torque.

Are you able to estimate the complete weight of the robot and how long is the longest segment (femur part)? With that in mind it should be easy to calculate if the 645MG have enough torque.