perm filename ARMSOL.PAL[2,VDS] blob
sn#252098 filedate 1976-12-02 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00023 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00004 00002 ARMSOL - SUITE OF PROGRAMS INVOLVING ARM KINEMATICS
C00005 00003 SOLVE - COMPUTES JOINT ANGLES GIVEN A TRANSFORM
C00007 00004 ["SOLVE" - JOINT 3]
C00010 00005 ["SOLVE" - JOINTS 1 & 2]
C00013 00006 ["SOLVE" - JOINT 3 REFERENCE VECTOR]
C00016 00007 ["SOLVE" - JOINT 4]
C00019 00008 ["SOLVE" - JOINTS 5 & 6]
C00022 00009 ["SOLVE" - CLEAN UP AND DEGENERATE CASE]
C00023 00010 ["SOLVE" - LOCAL STORAGE AREA]
C00025 00011 UPDATE - COMPUTES THE ARM TRANSFORM GIVEN THE JOINT ANGLES
C00027 00012 [CONTINUATION OF "UPDATE"]
C00030 00013 ["UPDATE" LOCAL STORAGE AREA]
C00031 00014 SUBROUTINE "CROSS" - COMPUTES THE CROSS PRODUCT OF TWO VECTORS
C00034 00015 SUBROUTINE "SECOND" - COMPUTES THE MAGNITUDE SQUARED OF A VECTOR
C00036 00016 SUBROUTINE "ANGLE" - COMPUTES THE ANGLE BETWEEN TWO VECTORS ABOUT A THIRD VECTOR
C00039 00017 [CONTINUATION OF "ANGLE"]
C00040 00018 SUBROUTINE "MULTA" - MULTIPLIES AN "A" MATRIX BY A "T" MATRIX
C00043 00019 [CONTINUATION OF "MULTA"]
C00045 00020 SUBROUTINE "ARAY" - GENERATES THE A MATRIX FOR A GIVEN ARM LINK
C00048 00021 [CONTINUATION OF "ARAY"]
C00050 00022 ["ARAY" - LOCAL STORAGE AREA]
C00052 00023 PHYSICAL CONSTANTS FOR MODEL STANFORD ARM (WESTERN ELECTRIC VERSION)
C00054 ENDMK
C⊗;
;ARMSOL - SUITE OF PROGRAMS INVOLVING ARM KINEMATICS
.TITLE ARMSOL
;THE FOLLOWING PROGRAMS ARE USED TO COMPUTE THE JOINT ANGLES FOR THE
;SCHEINMAN MANIPULATOR GIVEN A REQUIRED TRANSFORM OR VISE VERSA.
;THE THEORETICAL BASIS FOR THE KINEMATIC SOLUTIONS IMPLEMENTED IN
;THESE PROGRAMS IS PRESENTED IN "MODELLING, TRAJECTORY CALCULATION AND
;SERVOING OF A COMPUTER CONTROLLED ARM" BY RICHARD (LOU) PAUL,
;STANFORD A.I. MEMO AIM-177, NOVEMBER 1972. WHERE EVER POSSIBLE, THE
;VARIABLE NAMES USED IN THAT DOCUMENT AND IN THE FOLLOWING PROGRAMS
;ARE THE SAME.
;SOLVE - COMPUTES JOINT ANGLES GIVEN A TRANSFORM
;GIVEN A TRANSFORM "T", THE REQUIRED JOINT ANGLES ARE DETERMINED IN DEGREES.
;IF ANY JOINT ANGLE IS OUTSIDE OF THE PERMITTED RANGE OF MOVEMENT, THE ANGLE
;RETURNED IS THE AVERAGE OF THE OLD JOINT ANGLE AND THE JOINT STOP LIMIT.
;IN THE DETERMINATION OF JOINT ANGLE 4, IF THE REQUIRED CHANGE IN ANGLE IS
;GREATER THAN 90 DEGRESS AND LESS THAN 180, THE HAND IS FLIPPED OVER AND THE
;JOINT ANGLE CHANGE BECOMES THETA = THETA-90. ON COMPLETION OF EXECUTION,
;REGISTER R0 CONTAINS THE NUMBER OF NON-EXACT JOINT SOLUTIONS RETURNED. A
;SAMPLE CALLING SEQUENCE TO "SOLVE" FOLLOWS:
;
; MOV #T,R0 ;LOAD ADDRESS OF TRANSFORM "T"
; MOV #THETA,R1 ;LOAD POINTER TO JOINT ANGLES. INITIALLY
; ; THIS ARRAY SHOULD CONTAIN THE PREVIOUS ANGLES
; JSR PC,SOLVE ;CALLED USING PC
; TST R0 ;CHECK FOR NUMBER OF NON-EXACT SOLUTIONS
;
;ALL NUMBERS SHOULD BE IN SINGLE PRECISION FLOATING POINT REPRESENATATION.
;EXECUTION TIME: 4820 MICRO SECONDS
;REGISTERS USED:
;
; R0,R1 PASS ARGUMENTS AND R0 IS ALTERED BY "SOLVE"
; AC0, AC1, AC2, AC3, AC4, AND AC5 ARE GARBAGED
; ["SOLVE" - JOINT 3]
SOLVE: CLR EXACTS ;ASSUME EXACT SOLUTION FOUND
MOV R2,-(SP) ;SAVE REGISTERS
MOV R3,-(SP)
MOV R4,-(SP)
MOV #OV1,R3 ;START TRANSFERING TRANSFORM INTO OV1
ADD #20,R0
MOV #22.,R4 ;TRANSFER WORDS UNTIL PV3
SBLT1: MOV (R0)+,(R3)+ ;MOVE A WORD FROM THE TRANSFORM
SOB R4,.-2 ;REPEAT UNTIL DONE
CLRF AC0 ;CLEAR F.P. ACCUM
MOV #10,R3 ;SET COUNTER TO START WITH Z COMPONENTS
SOL1: LDF AV1(R3),AC1 ;GET COMPONENT OF THE APPROACH VECTOR A
MULF S6,AC1 ;MULT BY THE HAND LENGTH
ADDF SHOLDX(R3),AC1 ;ADD SHOULDER ORIGIN
SUBF PV1(R3),AC1 ;SUB. ARM POSITION IN TABLE COORDINATES
; NOW HAVE -LINK 3 COMPONENT OF LENGTH
STF AC1,W(R3) ;SAVE -W
MULF AC1,AC1
STF AC1,W2(R3) ;SAVE W**2
ADDF AC1,AC0 ;GET THE SUM OF THE SQUARES
SUB #4,R3 ;POINT TO NEXT COMPONENT OF ARM POSITION
BGE SOL1 ;DO Z,Y,X DIRECTIONS
;COMPUTE JOINT 3 POSITION
SUBF S22,AC0 ;SUB. JOINT 2 OFFSET**2 FROM SUM OF SQUARES
CFCC ; NOW HAVE JOINT 3**2
BGE S3REAL ;SKIP IF JOINT EXTENSION REAL
CLRF AC0 ;IF NOT, SET TO ZERO AND SKIP SQUARE ROOT
BR NSR
S3REAL: JSR PC,SQRTF ;COMPUTE SQUARE ROOT TO GET JOINT 3
NSR: CMPF STOP3+4,AC0 ;COMPARE TO MAX. JOINT EXTENSION
CFCC
BGE S3LE ;BRANCH IF LESS THAN MAX
LDF STOP3+4,AC0 ;ELSE SUBSTITUE MAX ALLOWABLE EXT.
BR M3
S3LE: CMPF STOP3,AC0 ;COMPARE TO MIN. JOINT EXTENSION
CFCC
BLE S3OK ;BRANCH IF IN RANGE
LDF STOP3,AC0 ;ELSE SUBSTITUTE MIN LENGTH
M3: INC EXACTS ;INDICATE EXACT SOLUTION NOT FOUND
ADDF 10(R1),AC0 ;ADD THE PREVIOUS JOINT ANGLE TO THE STOP LIMIT
MULF #40000,AC0 ;TAKE THE AVERAGE OF THE TWO ANGLES
S3OK: STF AC0,10(R1) ;SEND BACK JOINT 3
; ["SOLVE" - JOINTS 1 & 2]
;COMPUTE JOINT 1 ANGLE
LDF W2+4,AC0 ;LOAD W(2)**2
ADDF W2,AC0 ; + W(1)**2
JSR PC,SQRTF ;COMPUTE ( W(1)**2 + W(2)**2 ) **.5
LDF S2,AC1 ;GET THE JOINT 2 OFFSET
DIVF AC0,AC1 ;NOW HAVE SIN THETA= S2/(W(1)**2+W(2)**2)**.5
STF AC1,AC0
JSR PC,ASIN ;GET THETA
STF AC0,AC4 ;SAVE TEMP.
LDF W+4,AC0 ;LOAD -W(2)
LDF W,AC1 ;LOAD -W(1)
JSR PC,ATAN2 ;COMPUTE PHI = ATAN -W(2)/(-W(1))
ADDF AC4,AC0 ;JOINT 1 = PHI +THETA
MULF RADTOD,AC0 ;CONVERT FROM RADIANS TO DEGREES
STF AC0,AC1
SUBF STOP1+4,AC1 ;CHECK IF GREATER THAN MAX STOP LIMIT
CFCC
BMI J1N ;SKIP IF LESS
SUBF C360,AC0 ;ELSE SUBTRACT 360 DEG
J1N: CMPF STOP1+4,AC0 ;COMPARE ANGLE TO MAX STOP LIMIT
CFCC
BGE J1LE ;BRANCH IF LESS THAN MAX
LDF STOP1+4,AC0 ;ELSE REPLACE ANGLE BY STOP
BR M1
J1LE: CMPF STOP1,AC0 ;COMPARE TO MIN STOP LIMIT
CFCC
BLE J1OK ;BRANCH IF WITHIN STOP LIMITS
LDF STOP1,AC0 ;ELSE REPLACE ANGLE BY MIN STOP
M1: INC EXACTS ;INDICATE NO EXACT SOLUTION
ADDF (R1),AC0 ;ADD PREVIOUS ANGLE TO STOP LIMIT
MULF #40000,AC0 ;TAKE ANGLE HALF WAY BETWEEN THE TWO
J1OK: STF AC0,(R1) ;SEND OFF NEW JOINT 1 ANGLE
;COMPUTE JOINT 2 ANGLE
LDF W+10,AC0 ;GET -W(3)
NEGF AC0 ;NOW HAVE +W(3)
DIVF 10(R1),AC0 ;DIVID BY NEW LENGTH OF JOINT 3
STF AC0,AC4 ;SAVE THE COS JOINT 2 = W(3)/S3
JSR PC,ACOS ;GET ANGLE FOR JOINT 2
MULF NRADTD,AC0 ;CONVERT FROM RADIANS TO DEGREES AND NEGATE
STF AC0,4(R1) ;SEND NEW JOINT 2 ANGLE. NO STOP LIMIT
; CHECKING SINCE ALL SOLUTIONS WITHIN 0 TO Pi
; ["SOLVE" - JOINT 3 REFERENCE VECTOR]
;FORM THE UNIT VECTORS AT END OF LINK 3
JSR PC,SNCOSD ;COMPUTE THE SIN/COS FOR THE NEW JOINT 2
STF AC0,AC5 ;ONLY NEED THE SINE, SAVE FOR LATER
NEGF AC0 ;GET - SIN J2
STF AC0,Y3+10 ;Z-COMPONENT OF Y(3) VECTOR IN TABLE COORDINATES
LDF (R1),AC0 ;COMPUTE THE SIN/COS FOR THE NEW JOINT 1
JSR PC,SNCOSD
STF AC0,AC2 ;SAVE SINE AND COSINE J1
STF AC1,AC3
MULF AC4,AC1 ;COMPUTE COS J2*COS J1
STF AC1,Y3 ;X-COMPONENT OF Y(3) VECTOR
MULF AC4,AC0 ;COMPUTE COS J2*SIN J1
STF AC0,Y3+4 ;Y-COMPONENT OF Y(3)
MULF AC5,AC3 ;COMPUTE SIN J2*COS J1
STF AC3,Z3 ;X-COMPONENT OF Z(3) VECTOR IN TABLE COORDINATES
MULF AC5,AC2 ;COMPUTE SIN J2*SIN J1
STF AC2,Z3+4 ;Y-COMPONENT OF Z(3)
LDF AC4,AC0 ;GET COS J2
STF AC0,Z3+10 ;Z-COMPONENT OF Z(3)
;COMPUTE "RR" VECTOR, PERPENDICULAR TO PLANE OF LINK 3 AND HAND, AND
;CHECK FOR DEGENERATE CONFIGURATION, RR APPROX. 0 → HAND AND LINK 3 IN LINE
MOV #RR,R0 ;COMPUTE RR ← Z(3) CROSS Z(6)
MOV #Z3,R3
MOV #AV1,R4 ;AV1 IS THE SAME AS Z(6)
JSR PC,CROSS ;GET CROSS PRODUCT
MOV #RR,R0 ;GET THE SQUARE THE MAGNITUDE OF RR
JSR PC,SECOND
CMPF MINANG,AC0 ;CHECK IF DEGENERATE CASE → Z(3) IN LINE WITH
; Z(6) → |RR|**2 SMALL
CFCC
BLE NODEGN ;SKIP IF NOT DEGENERATE CASE
JMP DEGEN
NODEGN: JSR PC,SQRTF ;ELSE GET MAGNITUDE OF RR = |RR|
MOV #RR,R0 ;CONVERT RR TO UNIT VECTOR
MOV #3,R3 ;DIVID ALL THREE COMPONENTS BY MAGNITUDE
UNITRR: LDF (R0),AC1 ;LOAD A COMPONENT OF RR
DIVF AC0,AC1 ;DIVID BY MAGNITUDE
STF AC1,(R0)+ ;PUT BACK IN ARRAY
SOB R3,UNITRR ;REPEAT 3 TIMES
; ["SOLVE" - JOINT 4]
;COMPUTE JOINT ANGLE 4
MOV #RR,R3 ;JT 4 ANGLE IS JUST THE ANGLE BETWEEN RR AND Y(3)
MOV #Y3,R4
MOV #Z3,R0 ;JT 4 MUST BE DIRECTED ABOUTED Z(3)
JSR PC,ANGLE ;COMPUTE ANGLE
CMPF STOP4+4,AC0 ;IF GREATER THAN MAX SUBT 360 DEGREES
BGT .+6
SUBF C360,AC0
STF AC0,AC1 ;GET ANGLE INTO AC1
SUBF 14(R1),AC1 ;GET DIFFERENCE BETWEEN OLD ANGLE AND NEW
CMPF C180,AC1 ;CHECK IF DIFFERENCE GREATER THAN 180 DEGRESS
CFCC
BGE JT4LTP ;BRANCH IF LESS THAN 180
SUBF C360,AC0 ;ELSE SUBT. 360 DEG - GO THE SHORTEST DIRECTION
SUBF C360,AC1
BR TN
JT4LTP: CMPF CM180,AC1 ;CHECK IF DIFF. GREATER THAN -180 DEGREES
CFCC
BLE TN ;BRANCH IF GREATER THAN -180 DEG
ADDF C360,AC0 ;ELSE ADD 360 DEG - GO THE SHORTEST DIRECTION
ADDF C360,AC1
TN: CMPF C90,AC1 ;CHECK IF DIFF. LESS THAN 90 DEG
CFCC
BGE JT4LP2 ;SKIP IF IT IS
SUBF C180,AC0 ;ELSE GO THE OTHER DIRECTION AND FLIP HAND
BR FLIPJ4
JT4LP2: CMPF CM90,AC1 ;CHECK IF DIFF. GREATER THAN -90 DEG
CFCC
BLE NOFLIP ;SKIP IF IT IS
ADDF C180,AC0 ;ELSE GO THE OTHER DIRECTION
FLIPJ4: MOV #100000,R0 ;FLIP HAND OVER
XOR R0,RR ;COMPLEMENT THE THREE COMPONENTS OF VECTOR RR
XOR R0,RR+4
XOR R0,RR+10
NOFLIP: CMPF STOP4+4,AC0 ;COMPARE THE ANGLE TO THE MAX. STOP LIMIT FOR JT 4
CFCC
BGE JT4LE ;BRANCH IF LESS THAN MAX
LDF STOP4+4,AC0 ;ELSE REPLACE ANGLE BY STOP LIMIT
BR M4
JT4LE: CMPF STOP4,AC0 ;COMPARE THE ANGLE TO THE MIN STOP LIMIT
CFCC
BLE JT4OK ;BRANCH IF GREATER THAN MIN
LDF STOP4,AC0 ;ELSE REPLACE ANGLE BY STOP LIMIT
M4: INC EXACTS ;INDICATE NO EXACT SOLUTION
ADDF 14(R1),AC0 ;ADD THE OLD JOINT ANGLE TO THE STOP LIMIT
MULF #40000,AC0 ;TAKE THE AVERAGE OF THE TWO VALUES
JT4OK: STF AC0,14(R1) ;SEND BACK THE NEW JOINT ANGLE
; ["SOLVE" - JOINTS 5 & 6]
;COMPUTE JOINT 5 ANGLE
MOV #AV1,R3 ;JT 5 ANGLE IS JUST THE ANGLE BETWEEN Z(6) AND Z(3)
MOV #Z3,R4
MOV #RR,R0 ;JT 5 MUST BE DIRECTED ABOUTED RR
JSR PC,ANGLE ;COMPUTE ANGLE
CMPF STOP5+4,AC0 ;COMPARE ANGLE TO MAX STOP LIMIT OF JOINT 5
CFCC
BGE JT5LE ;BRANCH IF ANGLE LESS THAN STOP LIMIT
LDF STOP5+4,AC0 ;ELSE REPLACE ANGLE BY STOP LIMIT
BR M5
JT5LE: CMPF STOP5,AC0 ;COMPARE ANGLE TO MIN STOP LIMIT
CFCC
BLE JT5OK ;BRANCH IF ANGLE IN RANGE
LDF STOP5,AC0 ;ELSE REPLACE ANGLE BY MIN STOP LIMIT
M5: INC EXACTS ;INDICATE NO EXACT SOLUTION FOUND
ADDF 20(R1),AC0 ;ADD PREVIOUS ANGLE TO STOP LIMIT
MULF #40000,AC0 ;TAKE AVERAGE VALUE
JT5OK: STF AC0,20(R1) ;SEND BACK ANGLE
;COMPUTE JOINT 6 ANGLE
MOV #OV1,R3 ;JT 6 ANGLE IS THE ANGLE BETWEEN ORIENT. VECT AND RR
MOV #RR,R4
MOV #AV1,R0 ;DIRECTED ABOUT Z(6)
JSR PC,ANGLE ;COMPUTE ANGLE
TOL: STF AC0,AC1 ;GET ANGLE
SUBF 24(R1),AC1 ;GET DIFFERENCE BETWEEN NEW ANGLE AND OLD JOINT 6
CMPF C180,AC1 ;CHECK IF DIFFERENCE GREATER THAN 180 DEG
CFCC
BGE JT5LTP ;BRANCH IF LESS THAN Pi
SUBF C360,AC0 ;ELSE SUBT. 360 DEG - GO THE SHORTEST DIRECTION
BR ST6
JT5LTP: CMPF CM180,AC1 ;CHECK IF DIFFERENCE LESS THAN -180 DEG
CFCC
BLE ST6 ;BRANCH IF GREATER THAN -180
ADDF C360,AC0 ;ELSE ADD 2Pi - GO THE SHORTEST DIRECTION
ST6: CMPF STOP6+4,AC0 ;CHECK IF ANGLE LESS THAN MAX STOP LIMIT
CFCC
BGE JT6LE ;SKIP IF ANGLE LESS THAN MAX STOP
LDF STOP6+4,AC0 ;ELSE REPLACE ANGLE BY STOP LIMIT
BR M6
JT6LE: CMPF STOP6,AC0 ;CHECK IF ANGLE GREATER THAN MIN STOP LIMIT
CFCC
BLE JT6OK ;BRANCH IF IN RANGE
LDF STOP6,AC0 ;ELSE REPLACE ANGLE BY MIN STOP LIMIT
M6: INC EXACTS ;INDICATE NO EXACT SOLUTION FOUND
ADDF 24(R1),AC0 ;ADD PREVIOUS JOINT 6 ANGLE TO STOP LIMIT
MULF #40000,AC0 ;TAKE AVERAGE VALUE
JT6OK: STF AC0,24(R1) ;SEND BACK ANGLE
; ["SOLVE" - CLEAN UP AND DEGENERATE CASE]
;ALL DONE COMPUTING ANGLES, CLEAN UP
MOV EXACTS,R0 ;LEAVE EXACT SOLUTION FLAG IN R0
MOV (SP)+,R4 ;RESTORE REGISTERS
MOV (SP)+,R3
MOV (SP)+,R2
RTS PC ;RETURN
;HERES WHAT WE DO WITH DEGENERATE ANGLES FOR JOINTS 4 AND 6
DEGEN: CLR 20(R1) ;SEND BACK JOINT 5 EQUAL TO ZERO
CLR 22(R1)
MOV #OV1,R3 ;JT 6 IS THE ANGLE BETWEEN THE ORIEN. VECT AND Y(3)
MOV #Y3,R4
MOV #AV1,R0 ;DIRECTED ABOUT Z(6)
JSR PC,ANGLE ;COMPUTE ANGLE
SUBF 14(R1),AC0 ;SUBTRACT CONTRIBUTION OF JOINT 4
JMP TOL ;LEAVE JOINT 4 AS IT IS AND PROCEED TO JOINT 6 COMPU
;END OF "SOLVE"
; ["SOLVE" - LOCAL STORAGE AREA]
OV1: .BLKW 10 ;ARRAY FOR ORIENTATION VECTOR "O"
AV1: .BLKW 10 ;ARRAY FOR APPROACH VECTOR "A"
PV1: .BLKW 6 ;ARRAY FOR POSITION VECTOR "P"
W: .BLKW 6 ;THREE COMPONENTS OF "W"
W2: .BLKW 6 ;"W**2"
Y3: .BLKW 6 ;UNIT VECTOR IN Y DIR. OF JOINT 3 IN TABLE COORDIN.
Z3: .BLKW 6 ; " " " Z " " " " " " "
RR: .BLKW 6 ;VECTOR CROSS PRODUCT OF Z3 AND Z6
EXACTS: 0 ;COUNT OF NON-EXACT SOLUTION JOINTS
MINANG: .WORD 33206,33675 ;MINIMUM JOINT 5 ANGLE WITHOUT BEING DEGENERATE
; CASE = 0.000001
C360: .WORD 42264, 0 ; 360.0000
C90: .WORD 41664, 0 ; 90.00000
CM90: .WORD 141664, 0 ;-90.00000
C180: .WORD 42064, 0 ; 180.0000
CM180: .WORD 142064, 0 ;-180.0000
RADTOD: .WORD 41545,27341 ;CONVERSION FROM RADIANS TO DEGREES
NRADTD: .WORD 141545,27341 ;- RADTOD
;UPDATE - COMPUTES THE ARM TRANSFORM GIVEN THE JOINT ANGLES
;GIVEN THE JOINT ANGLES "THETA", THE RESULTING HAND POSITION AND ORIENTATION ARE
;DETERMINED AND STORED IN A GIVEN TRANSFORM "T". THE TRANSFORM IS A 4 BY 4
;MATRIX STORED BY COLUMNS WITH EACH VALUE REPRESENTED IN TABLE COORDINATES.
;A SAMPLE CALLING SEQUENCE FOLLOWS:
;
; MOV #T,R0 ;LOAD TRANSFORM ADDRESS IN R0
; MOV #THETA,R1 ;LOAD ADDRESS OF JOINT ANGLE LIST
; JSR PC,UPDATE ;CALLED USING PC
;
;THE TRANSFORM WILL BE OF THE FOLLOWING FORM:
;
; | T1 T5 T9 T13 |
; | T2 T6 T10 T14 |
; | T3 T7 T11 T15 |
; | 0 0 0 1.0 |
;
;ALL OF THE NUMBERS MUST BE IN SINGLE PRECISION FLOATING POINT REPRESENTATION.
;ALL ANGLES ARE IN DEGREES
;EXECUTION TIME: 5700 MICRO SECONDS
;REGISTERS USED:
;
; R0 - T TRANSFORM/LINK NUMBER
; R1 - THETA LIST/ARM CONSTANTS LIST POINTER
; AC0,AC1,AC2,AC3,AC4,AC5 GARBAGED
;DEFINITIONS:
LINK==%0
;START OF EXECUTABLE CODE
UPDATE: MOV R2,-(SP) ;SAVE REGISTERS
MOV R3,-(SP)
MOV R4,-(SP)
MOV R5,-(SP)
MOV R0,-(SP) ;SAVE T TRANSFORM ADDRESS
MOV #12.,R4 ;TRANSFER THE ANGLES
MOV #THET,R3 ;PUT THEM IN THET
MOV (R1)+,(R3)+ ;MOVE A HALF OF A F.P. NUMBER
SOB R4,.-2 ;DO 12 TIMES
; [CONTINUATION OF "UPDATE"]
MOV #10.,LINK ;START WORK AT LINK 6
JSR PC,ARAY ;COMPUTE "A" MATRIX
MOV #8.,LINK ;NOW AT LINK 5
MOV #30.,R3 ;TRANSFER A6 TO TN MATRIX
MOV #AM1,R4
MOV #TN1,R5
MOV (R4)+,(R5)+ ;TRANSFER ONE NUMBER
SOB R3,.-2 ;DONT STOP TILL FIRST 15 TERMS DONE
MOV #TN1,R5 ;FIRST MULT. T ← A5 x TN
MOV (SP),R4
HLLP: JSR PC,ARAY ;COMPUTE "A" MATRIX FOR NEXT LINK
MOV #3,COL4 ;SET COLUMN FOUR NOT TRUE, START AT COL 1
MUT: JSR PC,MULTA ;MULTIPLY "A" BY A COLUMN OF T1
ADD #4,R4 ;POINT TO THE NEXT COLUMN OF T2 MATRIX
ADD #4,R5 ; " " " " " " T1 "
DEC COL4 ;DO ALL FOUR COLUMNS
BPL MUT ;REPEAT IF NOT DONE
MOV #-100,R2 ;SET T1 AND T2 TO POINT TO COLUMN 1 AGAIN
ADD R2,R4
ADD R5,R2
MOV R4,R5 ;REVERSE THE DIRECTION OF MULTIPLICATION BETWEEN
MOV R2,R4 ; TN AND T
SUB #2,LINK ;POINT TO NEXT LINK
BGE HLLP ;DO ALL 6 LINKS
MOV (SP)+,R0 ;GET THE ADDRESS OF THE "T" TRANSFORM AGAIN
LDF 60(R0),AC0 ;ADJUST X,Y,Z FOR ORIGIN OF TABLE
ADDF SHOLDX,AC0 ;ADD IN X LOCATION OF JOINT 1
STF AC0,60(R0)
LDF 64(R0),AC0
ADDF SHOLDY,AC0 ;ADD IN Y LOCATION OF JOINT 1
STF AC0,64(R0)
CLR 14(R0) ;COMPLETE INITIALIZATION OF TRANSFORM
CLR 16(R0)
CLR 34(R0)
CLR 36(R0)
CLR 54(R0)
CLR 56(R0)
MOV #40200,74(R0)
CLR 76(R0)
MOV (SP)+,R5 ;RESTORE THE REGISTERS
MOV (SP)+,R4
MOV (SP)+,R3
MOV (SP)+,R2
RTS PC ;EXIT
;END OF "UPDATE"
; ["UPDATE" LOCAL STORAGE AREA]
;JOINT ANGLES
THET: .WORD 0,0,0,0
THET3: .WORD 0,0,0,0,0,0,0,0
;TEMPORARY "T" MATRICES
TN1: .WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0
TN15: .WORD 0,0
.WORD 40200,0
TM1: .WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0,0,0,0,0
.WORD 0,0,0,0,0,0
.WORD 40200,0
;SUBROUTINE "CROSS" - COMPUTES THE CROSS PRODUCT OF TWO VECTORS
;COMPUTES THE CROSS PRODUCT OF "A x B" AND RETURNS THE RESULT IN "C". A,B,
;AND C MUST BE ARRAYS CONTAINING THREE ELEMENTS. THE FOLLOWING OPERATION IS
;CARRIED OUT:
;
; C(1) ← A(2)B(3) - A(3)B(2)
; C(2) ← A(3)B(1) - A(1)B(3)
; C(3) ← A(1)B(2) - A(2)B(1)
;
;A SAMPLE CALL FOLLOWS:
;
; MOV #C,R0 ;LOAD ADDRESS OF C(1) INTO R0
; MOV #A,R3 ; " " " A(1) " R3
; MOV #B,R4 ; " " " B(1) " R4
; JSR PC,CROSS ;CALLED USING PC
;
;ALL NUMBERS SHOULD BE IN SINGLE PRECISION FLOATING POINT REPRESENTATION.
;REGISTERS USED:
;
; R0,R3,R4 PASS ARGUMENTS AND ARE ALTERED DURING EXECUTION
; AC0,AC1,AC2,AC3 GARBAGED
;START OF EXECUTABLE CODE
CROSS: LDF (R3)+,AC0 ;LOAD A(1)
LDF (R3)+,AC1 ;LOAD A(2)
LDF (R3),AC2 ;LOAD A(3)
MULF (R4),AC1 ;A(2)B(1)
MULF (R4)+,AC2 ;A(3)B(1)
LDF (R4),AC3 ;LOAD B(2)
MULF AC0,AC3 ;A(1)B(2)
SUBF AC1,AC3 ;C(3) = A(1)B(2)-A(2)B(1)
LDF (R4)+,AC1 ;LOAD B(2)
MULF (R3),AC1 ;A(3)B(2)
MULF (R4),AC0 ;A(1)B(3)
SUBF AC0,AC2 ;C(2) = A(3)B(1)-A(1)B(3)
LDF (R4),AC0 ;LOAD B(3)
MULF -(R3),AC0 ;A(2)B(3)
SUBF AC1,AC0 ;C(1) = A(2)B(3)-A(3)B(2)
STF AC0,(R0)+ ;SAVE C(1)
STF AC2,(R0)+ ;SAVE C(2)
STF AC3,(R0) ;SAVE C(3)
RTS PC ;RETURN
;END OF "CROSS"
;SUBROUTINE "SECOND" - COMPUTES THE MAGNITUDE SQUARED OF A VECTOR
;THIS PERFORMS THE FUNCTION OF TAKING THE DOT PRODUCT OF A VECTOR WITH
;ITSELF. A SAMPLE CALL FOLLOWS:
;
; MOV #A,R0 ;LOAD ADDRESS OF VECTOR INTO R0
; JSR PC,SECOND ;CALLED USING THE PC
;
;THE VECTOR IS ASSUMED TO BE THREE DIMENSIONAL WITH ALL TERMS STORED
;IN SINGLE PRECISION FLOATING POINT REPRESENTATION. THE RESULT IS
;RETURNED IN AC0.
;REGISTERS USED:
;
; R0, AC0 PASS ARGUMENTS AND ARE ALTERED DURING EXECUTION
; AC1 IS GARBAGED
;START OF EXECUTABLE CODE
SECOND: LDF (R0)+,AC0 ;GET FIRST ELEMENT
MULF AC0,AC0 ;SQUARE VALUE
LDF (R0)+,AC1 ;GET SECOND ELEMENT
MULF AC1,AC1 ;SQUARE VALUE
ADDF AC1,AC0 ;GET SUM OF SQUARES
LDF (R0),AC1 ;GET LAST ELEMENT
MULF AC1,AC1 ;SQUARE VALUE
ADDF AC1,AC0 ;NOW HAVE SUM OF SQUARES IN AC0
RTS PC ;RETURN
;END OF "SECOND"
;SUBROUTINE "ANGLE" - COMPUTES THE ANGLE BETWEEN TWO VECTORS ABOUT A THIRD VECTOR
;THIS ROUTINE FIRST USES THE DIRECTION COSINES OF TWO UNIT VECTORS (X AND Y) TO
;COMPUTE THE ANGLE BETWEEN THE VECTORS, i.e. IT TAKES THE DOT PRODUCT OF X
;AND Y. IT THEN COMPUTES THE CROSS PRODUCT OF X AND Y ABOUT Z TO DETERMINE
;THE SIGN OF THE ANGLE. THE IMPLEMENTED EQUATIONS ARE AS FOLLOWS:
;
; ABS(ANGLE) ← ACOS( X DOT Y )
; ← ACOS( X(1)Y(1) + X(2)Y(2) + X(3)Y(3) )
;
; | X(1) X(2) X(3) |
; SIGN(ANGLE)← -DET | Y(1) Y(2) Y(3) |
; | Z(1) Z(2) Z(3) |
;
;A SAMPLE CALLING SEQUENCE FOLLOWS:
;
; MOV #X,R3 ;LOAD ADDRESS OF X ARRAY INTO R3
; MOV #Y,R4 ; " " " Y " " "
; MOV #Z,R0 ; " " " Z " " "
; JSR PC,ANGLE ;CALLED USING PC
;
;EACH VECTOR IS ASSUMED TO BE THREE DIMENSIONAL WITH ALL TERMS STORED
;IN SINGLE PRECISION FLOATING POINT REPRESENTATION. THE RESULTING ANGLE
;IS RETURNED IN AC0 IN DEGREES.
;REGISTERS USED:
;
; R0, R3, R4, AC0 PASS ARGUMENTS AND ARE ALTERED DURING EXECUTION
; AC1, AC2, AC3 ARE GARBAGED
;START OF EXECUTABLE CODE
ANGLE: MOV R2,-(SP) ;SAVE REGISTER
CLRF AC0
MOV #3,R2 ;SET LOOP COUNTER TO COMPUTE DOT PRODUCT
DOTLP: LDF (R3)+,AC1 ;LOAD X COMPONENT
MULF (R4)+,AC1 ;MULT BY CORRESPONDING Y COMPONENT
ADDF AC1,AC0 ;SUM DIRECTION COSINES
SOB R2,DOTLP ;REPEAT FOR 3 DIRECTIONS
JSR PC,ACOS ;GET ANGLE IN RADIANS
MULF RADTOD,AC0 ;CONVERT ANGLE TO DEGREES
LDF (R0)+,AC1 ;LOAD Z(1)
MULF -10(R4),AC1 ;x Y(2)
LDF (R0)+,AC2 ;LOAD Z(2)
MULF -14(R4),AC2 ;x Y(1)
SUBF AC1,AC2 ;NOW HAVE Y(1)Z(2)-Y(2)Z(1)
MULF -(R3),AC2 ;x X(3)
; [CONTINUATION OF "ANGLE"]
LDF -(R4),AC1 ;LOAD Y(3)
MULF -10(R0),AC1 ;x Z(1)
LDF -10(R4),AC3 ;LOAD Y(1)
MULF (R0),AC3 ;x Z(3)
SUBF AC3,AC1 ;NOW HAVE Y(3)Z(1)-Y(1)Z(3)
MULF -(R3),AC1 ;x X(2)
ADDF AC2,AC1 ;ADD FIRST 6 TERMS
LDF -(R4),AC2 ;LOAD Y(2)
MULF (R0),AC2 ;x Z(3)
LDF -(R0),AC3 ;LOAD Z(2)
MULF 4(R4),AC3 ;x Y(3)
SUBF AC3,AC2 ;NOW HAVE Y(2)Z(3)-Y(3)Z(2)
MULF -(R3),AC2 ;x X(1)
MOV (SP)+,R2 ;RESTORE REGISTER
ADDF AC2,AC1 ;DETERMINATE NOW IN AC1
CFCC
BLT .+4 ;SKIP IF DETERMINATE NEGATIVE
NEGF AC0 ;IF POSITIVE, COMPLEMENT ANGLE
RTS PC ;RETURN
;END OF "ANGLE"
;SUBROUTINE "MULTA" - MULTIPLIES AN "A" MATRIX BY A "T" MATRIX
;THE MATRIX "A" IS MULTIPLIED BY THE COLUMN MATRIX "T1" AND THE RESULTS ARE
;STORED IN THE COLUMN MATRIX "T2". THIS IS THE FOLLOWING OPERATION:
;
; | T2(1) | | A1 A5 A9 0 | | T1(1) |
; | T2(2) | | A2 A6 A10 0 | | T1(2) |
; | T2(3) | ← | A3 A7 A11 A15 | X | T1(3) |
; | 0** | | 0 0 0 1.0 | | 0** |
;
;** THESE ARE 1.0 IF T1 IS THE FOURTH COLUMN OF A T MATRIX. A SAMPLE CALLING
;SEQUENCE FOLLOWS.
;
; MOV #1,COL4 ;ZERO IF T1 IS FOURTH COLUMN OF T MATRIX
; MOV #T1,R5 ;ADDRESS OF T1 MATRIX IN R5
; MOV #T2,R4 ;ADDRESS OF T2 MATRIX IN R4
; JSR PC,MULTA ;CALLED USING PC
;
;THE A MATRIX IS ASSUMED TO BE THE AM MATRIX. ALL NUMBERS IN SINGLE PRECISION
;FLOATING POINT REPRESENTATION.
;REGISTER ASSIGNMENTS
;
; R0 - LINK NUMBER*2 -2
; R2 - GARBAGED
; R3 - GARBAGED
; R4 - T2 MATRIX POINTER
; R5 - T1 MATRIX POINTER
COL4: 0 ;ZERO IF T1 IS THE FOURTH COLUMN IN THE T MATRIX
;START OF EXECUTABLE CODE
MULTA: MOV #AM1,R3 ;START WITH 1ST ROW OF "A" MATRIX
LDF (R5)+,AC2 ;LOAD A COLUMN OF THE "T" MATRIX
LDF (R5)+,AC3
LDF (R5)+,AC0
STF AC0,AC4
MOV AZERO(LINK),R2 ;PICK UP BITS INDICATING ZERO "A" ELEMENTS
ASL R2 ;CHECK IF FIRST "A" ELEMENT ZERO
MU0: BMI MU1 ;SKIP IF NOT
CLRF AC0 ;ELSE CLEAR ACCUM. AND SKIP MULTIPLY
BR MU2
MU1: LDF (R3),AC0 ;LOAD FIRST "A" ELEMENT
MULF AC2,AC0 ;MULT BY "T" ELEMENT
; [CONTINUATION OF "MULTA"]
MU2: ASL R2 ;CHECK IF SECOND TERM ZERO
BPL MU3 ;SKIP IF IT IS
LDF 20(R3),AC1 ;ELSE MULT SECOND ELEMENT IN A ROW BY "T1" TERM
MULF AC3,AC1
ADDF AC1,AC0 ;ADD TO PREVIOUS PRODUCT
MU3: ASL R2 ;CHECK IF THIRD TERM ZERO
BPL MU4 ;SKIP IF ZERO
LDF 40(R3),AC1 ;ELSE MULT THIRD TERM BY "T1" TERM
MULF AC4,AC1
ADDF AC1,AC0 ;ADD TO PREVIOUS SUMS
MU4: STF AC0,(R4)+ ;SAVE RESULT IN T2 MATRIX
ADD #4,R3 ;POINT TO NEXT ROW OF "A" MATRIX
ASL R2 ;CHECK IF ALL MULTIPLICATION DONE
BNE MU0 ;DO ALL THREE ROWS
TST COL4 ;IS THIS THE LAST COLUMN?
BNE MU5 ;SKIP IF NOT
ADDF AM15,AC0 ;ELSE ADD IN A ELEMENT 15 TO LAST SUM
STF AC0,-4(R4) ;SAVE NEW SUM IN T2 MATRIX
MU5: RTS PC ;RETURN
;END OF "MULTA"
;SUBROUTINE "ARAY" - GENERATES THE A MATRIX FOR A GIVEN ARM LINK
;THE A MATRIX IS GENERATED AND STORED BY COLUMNS IN THE "AM" LIST. THE
;NORMAL MATRIX REPRESENTATION AND THE AM LIST ARE RELATED IN THE FOLLOWING
;FASHION:
;
; | AM1 AM5 AM9 AM13 |
; | AM2 AM6 AM10 AM14 |
; | AM3 AM7 AM11 AM15 |
; | 0 0 0 1.0 |
;
;IN TERMS OF "THET", THE JOINT ANGLE,"AL", THE ANGLE ALPHA FOR THE LINK, AND
;"S", THE JOINT OFFSET, THE MATRIX IS WRITTEN AS FOLLOWS:
;
; | COS(TH) -COS(AL)SIN(TH) SIN(AL)SIN(TH) 0 |
; | SIN(TH) COS(AL)COS(TH) -SIN(AL)COS(TH) 0 |
; | 0 SIN(AL) COS(AL) S |
; | 0 0 0 1.0 |
;
;THE AM13 AND AM14 TERMS ARE NOT IN GENERAL ZERO, BUT THEY ARE FOR THE
;SCHEINMAN ARMS.
;REGISTER ASSIGNMENT
;
; R0 - LINK NUMBER*2 -2
; R2 - USED FOR TEMP STORAGE
; R3 - USED FOR TEMP STORAGE
;DEFINITIONS
SN==%0
CS==%1
FLINK==%3
;START OF EXECUTABLE CODE
ARAY: MOV #18.,R3 ;CLEAR THE A MATRIX
MOV #AM3,R2
CLR (R2)+
SOB R3,.-2 ;ZERO ELEMENTS 2 TO 12
MOV LINK,FLINK ;GET FLOATING POINT LINK INDEX
ASL FLINK
CMP LINK,#4 ;IS THIS THE SLIDING JOINT?
BNE REVOL ;SKIP IF REVOLUTE JOINT
LDF SI3,SN ;LOAD EQUIVALENT SINE FOR JOINT 3
MOV THET3,AM15 ;JOINT VARIBLE BECOMES LINK OFFSET
LDF CS3,CS ;LOAD EQUIVALENT COSINE FOR JOINT 3
MOV THET3+2,AM15+2 ;SECOND HALF OF JOINT VARIABLE FLOATING POINT NUMBER
BR CONA
; [CONTINUATION OF "ARAY"]
REVOL: LDF THET(FLINK),AC0 ;LOAD THE JOINT ANGLE
JSR PC,SNCOSD ;COMPUTE SIN/COS
MOV S1(FLINK),AM15 ;MOVE LINK OFFSET "S" INTO A MATRIX 15
MOV S1+2(FLINK),AM15+2
;CONSTRUCT THE A MATRIX
CONA: STF CS,AM1 ;STORE COS THETA IN ELEMENT 1
STF SN,AM2 ;STORE SIN THETA IN ELEMENT 2
TST AZERO(LINK) ;CHECK IF COS ALPHA OR SIN ALPHA IS ZERO
BGE NOCA ;SKIP IF COS ALPHA IS ZERO
LDF CA(FLINK),AC2 ;ELSE LOAD COSINE ALPHA
STF AC2,AM11 ;STORE IN ELEMENT 11
MULF AC2,CS ;COMPUTE COS ALPHA * COS THETA
STF CS,AM6 ;STORE IN ELEMENT 6
NEGF AC2 ;NEGATE COS ALPHA
MULF AC2,SN ;COMPUTE - COS ALPHA * SINE THETA
STF SN,AM5 ;STORE IN ELEMENT 5
RTS PC ;RETURN
NOCA: LDF SA(FLINK),AC2 ;LOAD THE SINE OF ALPHA
STF AC2,AM7 ;STORE IN ELEMENT 7
MULF AC2,SN ;COMPUTE SINE ALPHA * SIN THETA
STF SN,AM9 ;STORE IN ELEMENT 9
NEGF AC2 ;GET - SINE ALPHA
MULF AC2,CS ;COMPUTE -SINE ALPHA * COS THETA
STF CS,AM10 ;STORE IN ELEMENT 10
RTS PC ;RETURN
;END OF "ARAY"
; ["ARAY" - LOCAL STORAGE AREA]
;"A" MATRIX: 4 BY 4 STORED BY COLUMNS
AM1: .WORD 0,0
AM2: .WORD 0,0
AM3: .WORD 0,0
.WORD 0,0
AM5: .WORD 0,0
AM6: .WORD 0,0
AM7: .WORD 0,0
.WORD 0,0
AM9: .WORD 0,0
AM10: .WORD 0,0
AM11: .WORD 0,0
.WORD 0,0
AM13: .WORD 0,0
AM14: .WORD 0,0
AM15: .WORD 0,0
.WORD 40200,0
;SINE AND COSINE ALPHA FOR THE JOINTS
SA: .WORD 140200,0
.WORD 40200,0
.WORD 0,0
.WORD 140200,0
.WORD 40200,0
.WORD 0,0
CA: .WORD 0,0
.WORD 0,0
.WORD 40200,0
.WORD 0,0
.WORD 0,0
.WORD 40200,0
;SINE AND COSINE THETA FOR JOINT 3
SI3: .WORD 140200,0
CS3: .WORD 0,0
;BIT FLAGS INDICATING NON-ZERO ELEMENTS IN "A" MATRIX. BIT 15 INDICATES WHERE
;THE COS ALPHA IS ZERO, EACH BIT AFTER THAT CORRESPONDS TO 1 ELEMENT OF THE "A"
;MATRIX.
AZERO: .WORD 055200
.WORD 055200
.WORD 124100
.WORD 055200
.WORD 055200
.WORD 166100
;PHYSICAL CONSTANTS FOR MODEL STANFORD ARM (WESTERN ELECTRIC VERSION)
;TABLE COORDINATES OF MODEL STANFORD ARM SHOULDER AND JOINT OFFSETS
SHOLDX: .FLT2 0.0 ;SHOULDER LOCATION
SHOLDY: .FLT2 0.0
SHOLDZ:
S1: .FLT2 17.805 ;JT 1 OFFSET, SAME AS SHOLDZ
S2: .FLT2 6.535 ;JT 2 OFFSET
.FLT2 0.0 ;JOINT VARIABLE 3 IS THE JOINT 3 OFFSET
.FLT2 0.0 ; JOINT 4 OFFSET
.FLT2 0.0 ; JOINT 5 OFFSET
S6: .FLT2 7.985 ; JOINT 6 OFFSET
S22: .FLT2 42.70623 ;S2**2
;ARM JOINT STOP LIMITS
STOP1: .FLT2 -203.0 ;JOINT 1 MIN
.FLT2 90.0 ; MAX
STOP3: .FLT2 7.63 ;JOINT 3 MIN
.FLT2 35.7 ; MAX
STOP4: .FLT2 -265.0 ;JOINT 4 MIN
.FLT2 36.0 ; MAX
STOP5: .FLT2 -109.0 ;JOINT 5 MIN
.FLT2 109.0 ; MAX
STOP6: .FLT2 -84.0 ;JOINT 6 MIN
.FLT2 234.0 ; MAX
;END OF "ARMSOL"