Supervisory Control Algorithms For Telerobotic Space ... - CORE
-
Upload
khangminh22 -
Category
Documents
-
view
0 -
download
0
Transcript of Supervisory Control Algorithms For Telerobotic Space ... - CORE
\
Supervisory Control AlgorithmsFor Telerobotic Space Structure Assembly
by
DAVID ELLIOTT ANDERSON
B.S., Massachusetts Institute of Technology(1986)
Submitted in partial fulfillment ofthe requirements for the degree of
MASTER OF SCIENCEIN AERONAUTICS AND ASTRONAUTICS
at the
MASSACHUSETTS INSTITUTE OF TECHNOLOGYMay 6, 1988
© Massachusetts Institute of Technology 1988
Signature of Author
Certified by
Accepted by
Departmt of Aeronautics and AstronauticsMay 6, 1988
Professor David L. AkinThesis Sunervisor
Professor Harold Y. WachmanChairman, Departmental Graduate Committee
MAY 4 lubd
L J S R M I E S. ;
"!9 - ._
"' ; ' . i ·- ? ltsF, 1 a I:
. ; - - - -- -4.,~~~~~~~~~~~
-
SUPERVISORY CONTROL ALGORITHMSFOR TELEROBOTIC SPACE STRUCTURE ASSEMBLY
by
DAVID ELLIOTT ANDERSON
Submitted to the Department of Aeronautics and Astronauticson May 6, 1988 in partial fulfillment of the requirements for
the degree of Master of Science
ABSTRACT
A method for applying a task primitive supervisory control capability to a structuralassembly teleoperator is presented and compared with manual control modes. The task ofstructural assembly is often repetitive. Several of the basic steps in an assembly can becompleted by the computer faster with more accuracy and repeatability, lowering theworkload on operator and increasing productivity. These results are demonstrated byexample using the Beam Assembly Teleoperator.
The primary application of the Beam Assembly Teleoperator is the assembly oftetrahedral structures constructed of six beams and four nodes. The beam manipulation andjoint assembly portions of the assembly are augmented by the task primitive supervisorycontrol algorithm, Triad. Manual and supervisory modes are compared by repeated jointassembly and by full structure assembly.
Use of Triad proved to be significantly faster in repeated joint assembly, yielding timesfor a n'ive subject using Traid equal or better than an experienced operator under manualcontrol.
For full EASE structural assembly, Triad produced an estimated full assembly time20% faster than the previously established manual time, despite increased times for theportions of assembly not under Triad control. The times for the portions assembly underTriad control were decreased 43% from the corresponding manual times.
Thesis Supervisor: Prof. David L. AkinTitle: Rockwell Assistant Professor of Aeronautics and Astronautics
ACKNOWLEDGEMENTS
For the correct combination of guidance and freedom, and for a unique research
environment, I sincerely thank Professor Dave Akin.
Thanks also to Herb Viggh and John Spofford for bringing BAT into functionality
and tolerating my questions about circuitry and 'Spofford Assembly Language'. Thanks to
the BAT UROP'ers, Lisa, Jud, and Beth, for their skill with vacuum grease and devotion
to WIF tests. Courage, Jud. BAT can function. When in doubt, read chapter 4.
For keeping me going through Multivariable, thanks to Sue and Rob. I am sure that
if I put as much time into a marriage as we did into that class, it has got to work out.
For a truly eventful working environment, thanks to office mates Janice, Craig,
Mary, Vicky, Wendy, Tony, and to Russ, even if he did make me sit in the corner for the
last four months.
Thanks to my roommates, Chris, Win, Dana, and Jean+l, for good times, good
food, a comfortable home and lots of cran-raspberry juice.
Thanks especially to my family out west in Oregon for never letting me forget that
there is a world outside of Boston with good people, moderate weather, and decent
pavement.
This research made possible by NASA's Office of Aeronautics and Space
Technology under NASA Grant NAGW-21.
Table of Contents1. INTRODUCTION .............................................................................. 6
1.1 Teleoperation .................. ......... ..................... 61.2 The addition of supervisory control ................................................ 71.3 EASE and the SSL loop group . ....................................................1.4 The vehicle, BAT ................................................. 101.5 The control station, ICS ................................................ 131.6 Triad . ..... ........ ............................................................151.7 Scope of thesis ....................................................................... 16
2. UPGRADED CONTROL ALGORITHMS 5DOF ARM .................................. 172.1 Previous control system ............................................................. 17
2.1.1 Chain of command to move the arm .................................... 172.1.2 The role of BATSOFT ................................................... 182.1.3 The role of the joint cards ................................................ 182.1.4 Problems with the previous control system ........................... 19
2.2 Digital PID control ................................................. 202.2.1 Digital approximations of PID control .......... .................. 202.2.2 Tuning ............................................ .21
2.3 Application to BAT ............. ......... .. ......... ............ 222.3.1 Direct application ......................................................... 222.3.2 Addition of a separate integrator ........................................ 23
3. TRIAD, TASK PRIMATIVE SUPERVISORY CONTROL .............................. 243.1 Theory ............... ................................. 24
3.1.1 Supervisory Control .................................................... 243.1.2 Trajectory control and path planning ................................... 24
3.2 Method ................................................ 253.2.1 BAT's Limitations ................................................ 253.2.2 Application to BAT . ............................................... 263.2.3 Triad trajectory development ................... 2......... .........28
3.3 Application to the EASE structure assembly ...................................... 293.3.1 Breakdown of EASE joint assembly . .................................. 293.3.2 Assembling a joint manually ............................................ 303.3.3 Assembling a joint with Triad ........................................... 30
4. MANUAL vs. TRIAD ASSEMBLY of the EASE JOINT . ...............................314.1 Manual assembly using P-type control law ....................................... 314.2 Manual assembly using PD-type control law . .................................... 314.3 Manual assembly using PID-type control law ....................................344.4 Triad assembly ................................................ 35
4.4.1 The procedure ............................................................. 354.4.2 Results ..................................................................... 36
4.5 Comparing manual and Triad assemblies . .................................... 374.5.1 Overall time ................................................................ 374.5.2 Joint completion time . ....................................................384.5.3 Tasks covered by Triad .................................................. 39
4
5. FULL EASE STRUCTURE ASSEMBLY ............... .................................. 405.1 Results of NB-67 .................................................................... 40
5.1.1 Test setup and procedure ................................................ 405.1.2 Times for assembly and proportions . ...................... .......415.1.3 Comments on Fatigue . . ..................................................42
5.2 Results of NB-67C ...................................................... 425.2.1 Test setup and procedure ................................................ 425.2.2 Mechanical setbacks ..................................................... 445.2.3 Estimation of Triad assembly times and proportions ................. 44
5.3 Comparison of NB-67 and NB-67C data ......................................... 455.3.1 Direct comparison of assembly times .................................. 455.3.2 Weighted comparison . ................................................... 46
5.4 Limitations of the present configuration ........................................... 476. CONCLUSIONS AND RECOMMENDATIONS .......................................... 48
6.1 Conclusions ........ .. ......... ......... .......................486.2 The future of BAT ............................................................... 49REFERENCES . ..................................................... 52
APPENDIX I. BAT mobility using RMS ..................................................... 53APPENDIX II. BATSOFT ...................................................... 55APPENDIX III. JCS code ...................................................... 119APPENDIX IV. Triad trajectories .............................................................. 132APPENDIX V. EASE structure assembly schedule ......................................... 150
5
1. INTRODUCTION
1.1 Teleoperation
In hazardous environments such as the containment vessel of a nuclear reactor, the high
pressure depths of the ocean, or radiation-intense regions of space, it is dangerous or
impossible to have a human on site. In these situations, the human must be kept remote
from the site while a machine completes the task. One way to do this, with existing
technology, is teleoperation, which involves an on-site machine controlled by a human in
some safe remote location. A teleoperator enacts the human's commands, scaling them and
enhancing them. From a safe distance, the human can use the enhancements of the system
to move an object larger than he can move or make fine movements on a smaller scale.
In the case of the Beam Assembly Teleoperator (BAT) developed by the M.I.T. Space
Systems Lab (SSL), the mobile machine has propellers to give the teleoperative base 6
degrees of freedom (DOF), a dextrous, anthropomorphic arm for manipulation, a claw for
grappling and a claw for carrying. BAT operates in the neutrally buoyant environment of a
swimming pool, controlled by an operator in the Integrated Control Station (ICS) on the
surface.
The ultimate in teleoperation is called telepresence: "at the work site, the manipulators
have the dexterity to allow the operator to perform normal human functions" and "at the
control station, the operator receives sufficient quantity and quality of sensory feedback to
provide a feeling of actual presence at the work site."[1] Telepresence allows the operator
to use all the control strategies ingrained in the neural network of his brain from the long
years of childhood and adulthood that allow him to use his body to interact with the
environment and apply them to the remote work site. The control station and the
teleoperator are "transparent" in the control scheme. This would be a tremendous savings
in training time. Instead of the operator training to associate this joystick with that
manipulator joint and this toggle with that thruster, he simply uses the training he has on
6
the use of his own body to associate closing his fingers with grasping an object.
Unfortunately, no truly telepresent system has yet been developed.
1.2 The addition of supervisory control
If a teleoperator that could transmit all the agility of a human could be built, it would
equal human on-site productivity. But such a teleoperator must still be controlled manually
through each step of the task at hand, limited by that same agility, and by the motivation
and fatigue of the operator. One way to increase productivity is to hand off some portions
of the task to a computer control system on the vehicle. The computer receives commands
from the operator, and, by means of sensors and actuators, implements them. The operator
monitors the system, intermittently adjusting or supplying new commands. This is called
supervisory control.
Supervisory control is the middle ground between completely manual teleoperation and
completely autonomous robotics. Depending on the sophistication of the system, the
operator hands off some level of control, such as the major task level, task component
level, or task primitive level. A major task is one requiring the orchestration of all of the
system components. The computer must have the ability to plan, diagnose, and react to its
environment. Operator commands to a major task level supervisory controller would be on
the order of "diagnose and repair satellite telemetry module." Similarly, at the task
component level, a controller may also require the use of all system components, but does
not require planning or diagnoses. The computer implements a series of preplanned
manipulations. An example of an operator command to a task component level supervisory
controller is "detach and remove satellite telemetry module." At a more basic level, a task
primitive involves a single system component. The computer implements a single
manipulation such as "move freed module from point A to point B."
7
Supervisory control allows for quicker task completion, quicker automatic reflexes to
disturbances and other unanticipated events, greater accuracy and repeatability, and,
perhaps most importantly, increased duration [2]. Another opportunity afforded by
supervisory control is multi-tasking. While the human operator may only be able to operate
one remote machine manually, he may be able to supervise several, stepping in as required
to solve problems the lower level computer had trouble with. The practicality of multi-
tasking is discussed in [7].
1.3 EASE and the SSL loop group
The Experimental Assembly of Structures in EVA, or EASE, was a NASA sponsored
Shuttle flight experiment to study the capabilities and limitations of humans in EVA (Extra-
Vehicular Activity). Productivity of humans in space was considered key in determining
the economic viability of any space system requiring assembly. Suited subjects assembled
the EASE structure in neutral buoyancy at the NASA Marshall Space Flight Center Neutral
Buoyancy Simulator (MSFC-NBS) and in EVA on STS flight 61-B in November and
December 1985. Data returned from this experiment has already had some impact on space
station design. Detailed results are found in [3].
A secondary objective of the EASE experiment was to verify neutral buoyancy as a
simulation of sustained zero gravity. Preliminary studies concluded that neutral buoyancy
was an accurate simulation for task involving manipulation of masses sufficiently large that
inertia dominated water drag. Damping due to water drag was expected to facilitate
alignment and body positioning in neutral buoyancy but not expected to affect task
completion time. Times for full assembly in EVA were found to be 18% faster than those
in neutral buoyancy. EVA and neutral buoyancy assembly repetitions showed similar
learning and fatigue curves, though the onset of fatigue appeared earlier in neutral
buoyancy. The overall conclusion was that, for the construction of the EASE structure,
8
there is a good correlation between working in space and simulating it under water in
neutrally buoyant conditions.
The EASE structure is a tetrahedron with six beams and three nodes assembled in the
space shuttle payload bay (see figure 1.1). One of the nodes, or clusters, is fixed to the
payload bay. The clusters and beams are connected by the EASE joint (see figure 1.2).
The cluster has a mushroom end which fits into a receptacle on the end of the beam. A
sleeve on the beam end is then slid over the joint to hold it in place. The sleeve is held in
place by a spring loaded button. The capture rocker shown in figure 1.2 was not used in
the human assembly version of the EASE joint.
Figure 1.1 The EASE tetrahedron
The EASE tetrahedron was designed to be generic in nature rather than an operational
prototype. The structure was designed to be challenging to assemble in order to assess
learning, productivity and fatigue. As such, the allowable misalignment of the two ends to
be joined is less than ± 2-3 degrees for a successful joint completion.
The first teleoperator developed by the Space Systems Laboratory, the Beam Assembly
Teleoperator or BAT, was designed to assemble the EASE structure to compare
teleoperated assembly with human assembly. Developmental testing for BAT is performed
at M.I.T.'s Alumni Swimming Pool. Full scale testing has been conducted at MSFC-
9
NBS, which is a cylindrical tank of water 23m across and 12m deep. Across the bottom of
the tank is a mock-up of the space shuttle payload bay.
Mushroom
capture rocker End
Cluster
Figure 1.2 The EASE joint, unassembled and assembled
The EASE structure used by BAT is much the same as that used by human subjects in
pressure suits with the addition of a capture latch, or rocker, to hold the mushroom in place
while the sleeve is slid. BAT does not use a pair of "harpoons" used by the suited subjects
to tether beams and clusters during assembly.
1.4 The vehicle, BAT
BAT is a neutral buoyancy simulation of a space based teleoperator. BAT's base is maneuverable in 6D
use of 8 ducted propellers (see figure 1.3). Unlike vehicles designed specifically for underwater use, ca
attention is paid in neutral buoyancy to placing the center of mass of the vehicle coincident with the cente
buoyancy, so that BAT has no preferred attitude. This attitude freedom provides a
10
Bean
Stereo Cameras
Ducted Propeller-'TJ T ilt and Pan Unit
BellyCameras
Beam Carrier Claw
Handle
Side View Front View
Figure 1.3 BAT
11
simulation of the rotational dynamics of a space vehicle, allowing BAT to 'fly'
underwater.
BAT has one dextrous 5DOF arm which is proportionally similar to a human arm (see
figure 1.4). The arm consists of a 2DOF differential wrist, a 1DOF elbow and a 2DOF
shoulder. The motors for the upper three joints are held close to the upper frame origin to
keep down inertia. Since the EASE joint has an axis of symmetry, the wrist did not need to
have a degree of freedom in pitch. Each joint is also equipped with an angular position
encoder.
[) Shoulder Pitch) Elbow
rict,) Shoulder Yaw Side View Roll
I p V IVV
Figure 1.4 BAT's right arm
BAT has two other arms. The left arm is used for grappling, and includes a stowage
handle for the right arm claw. The stowage handle is used to hold the right arm in place by
its claw when the arm joint motors are not powered. The beam carrier arm is used to
remove a beam from the beam rack, hold it back while BAT is flying, and then present it
for assembly. The claws for all three arms as well as the extension and retraction of the
beam carrier are controlled with pneumatic air cylinders.
There are two sets of stereo cameras on BAT for operator feedback. The cameras are
mounted in pairs to allow the operator to have depth perception. One stereo pair is
mounted on BAT's belly in the center of the vehicle. This pair has wide angle lenses and is
12
4-
used for flying. The other pair has a more narrow field of view and is mounted on a tilt
and pan base. The tilt and pan allows the camera to be commanded in 2DOF. The motion
of the tilt and pan is normally slaved to the motion of the operator's head to allow him to
look around. The magnification and aiming ability makes the tilt and pan cameras
applicable to assembly tasks.
The motors, encoders, batteries and circuitry on BAT are enclosed either in water tight
boxes or in waterproof potting. Most boxes are pressurized so that any leaks that occur will
leak air out rather than water in. The battery boxes are not pressurized. Since batteries vent
hydrogen as they are discharged, pressurization of the battery boxes would create a danger
of ignition if hydrogen from the battery box were allowed to mix with air. The main battery
box is purged with nitrogen before and after use.
1.5 The control station, ICS
ICS, the Integrated Control System, is the operator station for controlling BAT. (see figure
1.5) The operator interface consists of a master arm used to control BAT's dextrous right
arm, a head controller used to control the tilt and pan cameras, two 3DOF joysticks, one
translation and one rotation, used to control BAT's propulsion system, six monitors
showing computer graphics and whatever external video might be available, four switches
mounted on the master arm, four switches mounted on the rotational joystick, four foot
switches, four panel switches, six pneumatic enable switches, one large switch to change
between stereo camera pairs, and a keyboard, used mainly in system initialization.
13
tors showing BAT video
AT vid
Figure 1.5 The Integrated Control Station
14
5
Figure 1.6 Photograph of the Integrated Control Station
The interface is monitored by an IBM PC running the program BATSOFT. BATSOFT
reads the switches and the potentiometers on the arm and head controller, creates the
graphic display, beeps the appropriate beeps, and gives commands to the Joint Control
System (JCS), which controls the dextrous right arm, the pneumatics, the tilt and pan, and
the propulsion system thrusters. The JCS contains four cards each driven by a Z80
microcomputer that calculates joint duty cycles, one Z80-based card that calculates thruster
duty cycles, and a transceiver card which multiplexes all of the motor command signals
together along with signals to control the state of the pneumatics, and sends it down the
communications down link to BAT. The transceiver card also reads the up link from BAT
containing mainly joint encoder positions for the joint cards and for BATSOFT.
Since the operator has primarily visual feedback with little oral and no tactile feedback,
BAT and ICS are certainly not an example of telepresence. The operator interface,
however, has been shown to be functional with the construction of the EASE structure
detailed in [5] and chapter 5.
1.6 Triad
Triad is a set of task primitive supervisory control algorithms which use learned or
established trajectories to move the dexterous arm through the motions of joint assembly.
Triad reads in a command line from a file composed of angular positions for each joint plus
commands to control the gains in the arm control system, the accuracy at which the
trajectories are to be followed, and the state of the various pneumatics.
Triad temporarily replaces the master arm manual control. Triad works entirely in joint
space, as the master arm does, providing the JCS with command set points for each joint of
the arm.
15
Since the tilt and pan cameras are only for operator feedback and have no use to Triad,
they remain in the control of the operator while Triad is running. In this way, the operator
can monitor Triad.
1.7 Scope of thesis
Using TRIAD in addition to the already functional manual control system, the
advantages of the addition of supervisory control are analyzed. Chapter 2 details upgrades
made to the arm control system that allowed Triad to function. In chapter 3, the
specifications for Triad and its application to BAT are listed. In chapter 4, the EASE joint is
assembled repeatedly under manual and supervisory control situations for both experienced
and naive operators to discover the differences in productivity and its components in
training and fatigue. In chapter 5, assembly of the full EASE tetrahedron is demonstrated
and compared with a previous manual assembly.
16
Figure 1.7 BAT assembles the mini-EASE tetrahedron in the M.I.T. Alumni Pool
16A
Figure 1.8 The Integrated Control Station
2. UPGRADED CONTROL ALGORITHMS 5DOF ARM
2.1 Previous control system
The prime objective for BAT was to
assemble the EASE tetrahedron. This
objective was accomplished in January 1987
at NASA Marshall Space Flight Center's
Neutral Buoyancy Simulator during test
series NB-67. The control of the 5DOF right
arm was accomplished with a simple
proportional or P-type control algorithm.
2.1.1 Chain of command to move the arn
The actuation of the right arm is
accomplished by permanent magnet DC
motors fed with a pulse width modulation
(PWM) duty cycle. Gains for the P-type
control system are input into BATSOFT
which transmits them to the joint cards in the
JCS via a dual port ram (DPR). Using these
gains, a duty cycle is calculated for each joint
by the joint cards and then multiplexed into a
serial line for communication to BAT. On
BAT, the serial data is demultiplexed and
transmitted to power modules. The power
modules contain H-bridge darlington
transistors which reproduce the signal duty Figure 2.1 ICS-BAT Chain of Command
17
cycle at a current level capable of running the motors.
Each joint is also equipped with an optical incremental shaft angle encoder. Circuitry
on BAT integrates the encoder quadratures and transmits the angular position of each joint
back up the communications link to the JCS. In the JCS, the encoder positions are made
available to the joint cards and to BATSOFT. Conversion of encoder value to joint angle in
degrees is detailed in [4].
2.1.2 The role of BATSOFT
As mentioned above, the man-machine interface is monitored by an IBM PC running
the C program, BATSOFT. BATSOFT reads the various potentiometers, switches and
keys on ICS, and relays commands to the JCS. Code for BATSOFT can be found in
Appendix II.
In the running of the right arm, BATSOFT sets the gains and provides command set
points. The gains are set by the operator by loading prepared gain files or by adjusting
each joint separately. The gains are then transmitted to the joint cards, via the DPR. When
the operator turns on the master arm, BATSOFT reads the potentiometers at each joint of
the master, adjusts them to produce a command set point for each joint, and transmits each
set point to the appropriate joint card.
The tilt and pan is controlled in much the same way, with either the potentiometers on
the head controller or those on a separate joystick being read for command set points.
As long as the master arm is connected, BATSOFT transmits a new position set point
for each joint once per main loop. The frequency of the BATSOFT main loop is 8Hz.
2.1.3 The role of the joint cards
The frequency of the joint card main loop is 98Hz, an order of magnitude faster than
the BATSOFT main loop. There are four joint cards resident in the JCS. Each calculates
the duty cycle for two of BAT's motors. There are eight motors total, five in the right arm,
two in the tilt and pan, and one for the cooling pump. The code for the joint cards is listed
in Appendix III.
18
For the P-type control system, the joint cards read in the encoder position of a joint,
subtract it from the command set point, and multiply by the constant gain supplied by
BATSOFT. The result is then clipped to maximum duty cycle, if necessary, and sent to
BAT in PWM form.
2.1.4 Problems with the previous control system
The P-type control law does not provide good tracking. Overcoming friction in the
joints requires error integration. The P-type control law allows the arm to become stuck
short of the mark, since its duty cycle diminishes as the actual joint position approaches the
command set point. The operator is forced to account for this by overshooting a desired
end point with the master arm and then coming back to stop the arm at the desired location.
This is especially difficult for fine movements, in which the operator must use a large
starting error to get the arm moving and come back just far enough to stop it again at the
desired end point. The amount of leading required is variable with load and desired arm
speed.
This problem is addressed here with the addition of integrated error and differentiated
error to the control algorithm. The resulting controller is PID-type or proportional-integral-
derivative type. The derivative term excites response in the applied torque due to quick
changes in commanded speed. The integral term builds up applied torque in the presence
of an error to get rid of steady state error and to overcome friction.
Another problem with the control system which is not addressed here is the frequency
of the duty cycle used in the pulse width modulation. PWM is a method to approximate a
DC voltage using a digital two-state signal. The premise of PWM theory is that the load
has an electrical time constant sufficiently longer than the period of the PWM so that it sees
the current it would otherwise receive from the corresponding DC voltage. Here, the PWM
modulation has a frequency of 1KHz, but the motor response also about 1KHz. So,
instead of the steady current draw expected by PWM, the motors on BAT draw current in
19
spikes in phase with the PWM duty cycle. The primary result of this problem is that there
is no linear relationship between duty cycle and resultant motor torque.
A third problem with the existing control system is noise in the encoder signals. The
wiring from the encoders in the present construction is laid along side the motor power
cables for some distance. The highly oscillatory nature of the power current tends to
induce noise in the adjacent, unshielded encoder cable. This is especially prevalent in the
wrist, where an occasional twitch can be seen. The noise, together with nonlinearities
produced by water currents, water drag, friction, stiction, and backlash makes a rather
fuzzy picture of arm dynamics.
2.2 Digital PID control
2.2.1 Digital approximations of PID control
An advantage of a PID controller is that, when correctly tuned, it can give good system
response without a resident model of the system dynamics. A standard continuous time
PID-controller looks like:
1 TSU(s) = K( 1 + T + /N )E(s)TI S 1+ Ts/N
where U(s) and E(s) are Laplace transforms of control and error, K is the proportional
gain, TI is the integral time constant, TD is the derivative time constant, and N is the
number of sampling periods per rise time to a step input.
In order to implement a PID algorithm in the digital domain, the analog control law
must be approximated. An extended discussion of digital approximations is found in [8].
There are three basic methods of approximation:
20
s _ Z 1 (Euler Method)h
s = z- 1 (Backwards Difference)zh
s = h(z - 1) (Tustin Approximation)h(z+1)
where s is the Laplace operator, z is the forward shift operator such that Z=esh,
and z x X = X , where Xn is the value of X at t = h x n, and h is the sampling period
of the digital system.
According to [8], the most common way to approximate a PID controller is to make an
Euler approximation of the integral part and a backwards difference approximation of the
derivative part:
u(kh) + h TD_ z-1u(lh) = K(1+Ti(z-) + h+TD/N x z- TD/(Nh+T ) )e(kh)
where k is the sample number. For the purposes of tuning, the equation was streamlined to:
u(kh) = KD(+ h 1 1 T z-i )e(kh) T z- 1 + z +where TD = TI, TDD = TxN, and = eTNfrd.
2.2.2 Tuning
With a short sampling period, a digital PID controller behaves much like an analog
PID. Several tuning methods have been developed for the analog PID. Assuming a
sufficiently short sampling period, theses methods can be directly applied to the digital
PID. The method used here is the transient-response method developed in [9].
The transient-response method models the system as a first order system with
transportation lag. The step response to such a system is shown in figure 2.1.
21
-1
:3{oL
o0rZ
L *LI rIU
Figure 2.1 Open Loop Step Response of a System [8]
The lag and slope of the response can be used as a first approximation of PID parameters,
using the following equations:
1.2KD= RL TID= 2L TDD=0.5L
Using these parameters, the controller can be tuned by trial and error for best response.
2.3 Application to BAT
2.3.1 Direct application
The first problem encountered is that listed in section 2.1.4, that of the failure of PWM
for BAT. Instead of the smooth step response curve needed for the tuning, BAT's actual
response is a series of spikes. The way chosen around this is to examine each of the spikes
as a separate step response. The resulting values of N,the number of sampling periods per
rise time, R, the torque response slope, and L, the torque response lag, are not guaranteed
to provide the best starting point but were reasonably close.
Measuring the current output of each motor, which is proportional to output torque,
values were found for R and L to construct a first iteration PID system for BAT's right
arm. This was then implemented into the code running the joint cards. This code is listed
in Appendix III.
The control law is arrived at as follows. Beginning with the equation above, solve for
Uk, the control value for the present sampling period:
22
U(kh) a b(z- l)E(kh) =S( z-1)+ (z+c) )
where a = h/TID, b = TDD/h , c = y, and S is the number of encoder pulses per joint angle
degree. U here is the actual duty cycle sent to the arm, and E is the error between
commanded and actual encoder positions.
UE ( l+(c- 1)z'l-cz 2)=KS (l+b)+KS(c+a- 1-2b)zl+KS(ac-c+b)z 2
Uk= ( 1-c)Uk cUk _+KS( l+b)Ek+ KS(a+c- 1-2b)Ek_ tKS(ac-c+b)Ek_ 2
The coefficients of each of the control and error terms is calculated in BATSOFT and input
to the JCS as a separate set of constants for each joint:
U.= (M1 U,_M TJ -, xE PE +GEk-i l~ 2 k-2 k-1 k-2) k
where the portion in the brackets can be precalculated at each step and added to the multiple
of encoder error as soon as it is read.
Tuning of this algorithm failed to produce adequate tracking. Essentially, the integrator
did not function correctly due to the slow sampling period. The use of a Tustin
approximation instead of an Euler did not improve the response.
2.3.2 Addition of a separate integrator
A simple integrator was then added to the control law to force an integration of error to
help zero out residual errors. The integrator simply sums a multiple of the error. The sum
is then clipped, if necessary. The multiplier for each joint was determined by tuning for
fastest response. The clipping level was determined from the duty cycle necessary to
overcome starting friction. The integrator sum for each joint is reset every time the error
passes through zero to avoid integrator windup.
This addition improved the tracking sufficiently to allow the use of Triad. Sets of
parameters for each joint were then established for manual and Triad use.
23
3. TRIAD, TASK PRIMATIVE SUPERVISORY CONTROL
3.1 Theory
3.1.1 Supervisory Control
In the process of supervisory control, the operator issues commands to a computer
which in turn closes its own loop with the vehicle being controlled. The computer
produces a integrated status display to the operator to show response to these commands
and the operator steps in when necessary to change commands or make adjustments.
Sheridan, in [2], goes into great detail concerning the roles of the computer and
operator under supervisory control. He lists five major functions of the operator. The first
is to plan the task to be done, decide a strategy for its completion including the appropriate
roles of the operator and computer, and consider the initial conditions. The second is to
teach the computer how to do the task, decide how the computer is to deal with unexpected
occurrences, decide how far the computer is to go between commands, and give the
command to begin. The third function is to monitor the computer, make minor adjustments
when necessary, and diagnose failures. Fourth, the operator intervenes and takes manual
control when the computer fails, in order to reconsider the plan and how it was taught to
the computer. Last, the operator is to learn about the system in order to understand it and
make best use of its characteristics.
3.1.2 Trajectory control and path planning
The object of planning trajectories is to move between points in an optimal way,
primarily with regard to time. The path is constrained by its end points and obstacles that
must be avoided. The trajectory, the time versus position sequence required to follow the
path, is limited by joint torque maximums and allowable joint angles.
The output of a trajectory planning algorithm is a set of joint positions to be fed into the
arm control system. The set points are typically required at a rate of 60Hz to 200Hz,
depending on the control system, in order to provide a smooth arm motion as shown in [6].
24
The calculation of the set points may be accomplished by several methods. A set of
intermediary or 'via' points can be added along the desired path to insure that the arm
misses the obstacles in its path. The required arm velocities and accelerations at each point
then become constraints to the path. The path can be calculated as an Nth order polynomial
accounting for each of the constraints. But for even slightly complicated trajectories, the
polynomial is of high enough order that checking for torque limit satisfaction becomes quite
difficult. This type of trajectory is not optimal; due to the number of roots in the
polynomial, it is likely to overshoot and wander.
A way around this problem is the use of knot points. Knot points are placed at the via
points and where mathematically convenient. Given the arm state at each of the knot points,
separate cubics are calculated to govern the motion from each knot point to the next.
A point of contention among the robotic community is whether these calculations
should be conducted in cartesian space or joint space. A cartesian space trajectory is more
easily visualized by the user of a system. As noted in Appendix I, it is difficult for a
human operator to make a mental Jacobian transformation to move joints to go straight in a
cartesian direction. But cartesian position and orientation are not enough for a trajectory
planner. The inverse kinematics also require answers to questions such as whether the
elbow should be up or down. The trajectory planner working in cartesian space has
knowledge of end effector position but does not know the joint angle required to place the
end effector. For this reason, it can assure obstacle avoidance for the end effector, but not
necessarily for the upper portions of the arm.
3.2 Method
3.2.1 BAT's Limitations
Without major hardware changes, the application of supervisory control to BAT is
limited. The propulsion system for the base is operated on a loop closed only through the
visual system of the cameras and the human operator. Without any position sensing, BAT
25
has no way of knowing where it is inertially at any given time. BAT does know the state
of its pneumatics and the encoder position of the right arm. With this information,
BATSOFT could close a loop with the JCS to control the position of the right arm and the
state of the pneumatics.
As noted in chapter 2, BAT has no exact control of torque. Joint velocity and
acceleration are also not available. These limitations make a generalized trajectory planner
impractical. But since the task primitives of the EASE joint assembly were repetitive,
specialized trajectories could be developed for each portion.
3.2.2 Application to BAT
As stated in the introduction, Triad temporarily replaces the master arm control. Triad
works entirely in joint space, as the master arm does, providing the JCS with command set
points for the arm.
BATSOFT, with all its analog to digital conversions reading the potentiometers of the
master arm, head controller and joysticks, has a main loop period of 8Hz. Triad, without
the burden of the full human interface, can run much faster, approximately 1KHz. The
JCS runs at 98Hz. This allows Triad to monitor each sampling period of the JCS.
Triad operates using a file of saved joint positions and commands. A command file can
be generated during main loop manual control in Triad's learn mode. Triad saves the actual
arm position to file once every main loop. The file can then be "played back" using triad's
point-to-point mode, or modified off-line to smooth out the motion and get rid of errors.
Files can be played back singly or concatenated together for one long trajectory. A stack of
files can be set up for playback via a menu or a button software configured to load in a set
of trajectories.
Triad's learn mode saves the actual arm position, as opposed to the command position,
for two reasons. As will be shown in section 4.1, the operator often provides a higher
order control system to pick up where the JCS leaves off. The commanded position may
contain lead and dither not meant to appear in the actual arm position. The second reason is
26
that the Triad arm gains are higher than manual gains, and response to a command given
using manual gains is different than that using Triad gains. Triad gains are tuned to
provide the fastest possible tracking.
Manual gains are limited to allow for smooth arm motion under the control of the main
loop of BATSOFT. The manual gains are sufficient to provide tracking of a single
command set point in approximately one main loop of BATSOFT. If the tracking were
significantly faster, the arm would arrive at the set point before a new set point could be
supplied by BATSOFT, and the arm would slow toward a stop. The result would be
discontinuous slave arm velocity in response to a constant master arm velocity.
After Triad has issued a set point to the JCS, it monitors joint positions and waits for
the actual joint space position of the arm to come within a target region of the commanded
position. The size of the target region is set by the command file being read, but is usually
kept small near a target and large during a free move through open space. Triad also has
control over the JCS control laws for each joint. If the arm takes too long to track to a new
set point, Traid loads in higher control gains for each joint to get the arm going again.
Friction is a large factor for BAT's right arm due to the fact that the arm is operated
immersed in water, and is therefore difficult to lubricate. Once the actual position reaches
inside the target region, Triad reads in a new command from the file, passes on any
pneumatic changes in the command line, and gives the JCS a new set point.
Once the file or set of files is complete, Triad loads manual control gains to the arm if it
is still in action, or loads zero gains to the arm if it was stowed, and returns control to the
human interface. If the operator wishes to bail out of Triad in the event of an error or a
change in plans, he can pull a finger switch. Triad responds immediately by loading in
manual control gains, changing the master arm offsets so that the present master arm
position is aligned with the arm position, and returning to main loop manual control.
27
Since the tilt and pan cameras are only for operator feedback and have no use to Triad,
they remain in the control of the operator while Triad is running. In this way, the operator
can monitor Triad's progress.
3.2.3 Triad trajectory development
Each trajectory developed for Triad started with points in joint space. Starting and
ending points were taken as well as via points clear on approach to grappling positions, and
clear of any obstacles. A path was then plotted between these points using linear joint
interpolation, or a straight lines in joint space. Spacing between set points was determined
by the tuning detailed in chapter 2. Commands were then added to the Triad file to change
pneumatic states at the appropriate set points.
Commands to change arm gains were added. Three sets of gains are available: Triad 1,
2 and 3. Triad 1, the default, was used in guarded situations on approach to a grappling
point. Triad 2, with slightly higher gains, was used in free portions of the trajectory when
the arm was swinging across free space. Triad 3, with high gains, was used for arm
movements with a load in the right claw.
In situations where a particularly large torque was required, such as getting a load
started moving, a single set point was modified and moved beyond the desired position.
The actual desired position remained within the target region of the modified set point.
This would supply the large error to the joint cards to provide the torque required for the
job without waiting for the integrator to build up. The load would then respond to the jolt,
allowing the arm to move toward the desired set point. Once the actual position was within
the target region of the modified set point, by design quite close to the desired set point,
Triad would go on to the next set point. The next set point could then be back on the
nominal path.
28
3.3 Application to the EASE structure assembly
3.3.1 Breakdown of EASE joint assembly
The assembly of the EASE joint used in the comparison of manual and supervisory
control assembly is the configuration with BAT docked with its left claw to a cluster. A
beam in the beam carrier is attached to the cluster. The assembly, called a beam joint
assembly, consists of five steps:
1. Grab the beam. With a beam already in the retracted beam carrier claw, the beam is
swung forward. The right arm is powered up and the right claw open. The right arm
moves clear of the stow handle mounted on the side of the left arm, and moves clear of the
left arm. The right arm waits for the beam carrier to extend and settle the beam to a stop
and then moves up to close the right claw on the beam end. The beam carrier claw is then
opened and the beam carrier swung back.
2. Make the joint. With the beam held in the right claw, the arm maneuvers the beam to
place the cluster mushroom end into the receptacle on the beam end. The wrist must then
be twisted to apply sufficient force to set the rocker in the beam end so that it holds the
mushroom end in place.
3. Grab the sleeve. With the joint just completed, the right claw opens on the beam
end, the arm backs off of the beam end, approaches the sleeve, and grabs the sleeve with
the right claw.
4. Slide the sleeve. With the right claw closed on the sleeve, the right arm applies
sufficient force to slide the sleeve over the cluster, holding the mushroom end in place.
The sleeve is slid until the spring loaded button pops up to hold the sleeve in place.
5. Stow the right arm. With the right claw on the slid sleeve, the claw opens. The
right arm backs the claw off of the sleeve and clear of the left arm. The arm approaches the
stow handle so that the right claw can be closed on the stow handle. The gains to the right
arm are then zeroed.
29
3.3.2 Assembling a joint manually
Manual assembly of the joint involves actuating switches to change pneumatic states.
The arm movements are commanded with the master arm. Each time the master arm is
brought into use, the operator hits a software switch to set the present master arm position
equal to the present slave arm position. This process is called 'connecting' the master arm.
When the master arm position becomes uncomfortable for the operator, he may disconnect
the master arm and reconnect it in a more comfortable position. The arm is powered up and
down with a button push. The operator uses the tilt and pan cameras slaved to the head
controller to view the scene.
3.3.3 Assembling a joint with Triad
For each of the basic parts of the EASE joint assembly there is a Triad file. All five
steps are reduced to button pushes with the exception of setting the rocker on the
mushroom end. In the manual assembly, getting the rocker to set on the mushroom end
requires wiggling the beam end until the rocker receives enough force to set. Due to
problems in commanding torques, as discussed in section 3.2.1, together with inexact
positioning of the cluster in the left claw, Triad only goes so far in making the joint as to
place the beam end close to the mushroom end for easier manual completion.
For the purposes of assembling the EASE joint with Triad, the Triad trajectories are
grouped. The operator hits a switch actuating GRABBEAM and JOINT trajectories, and
watches the right arm grab the beam and move it close to the cluster. The operator
manually gets the rocker to set, and hits the switch again. Triad runs GRABSLV and
SLIDESLV. Once the operator sees the button pop on the sleeve, he hits the switch a third
time. Triad runs STOW. During the process, if a Triad trajectory fails, the operator
completes the failed task primitive manually, and restarts Triad at the beginning of the next
task primitive.
30
4. MANUAL vs. TRIAD ASSEMBLY of the EASE JOINT
4.1 Manual assembly using P-type control law
In January of 1987 during test NB-67, BAT successfully completed the EASE structure
at MSFC-NBS using manual control and a proportional (P-type) control law on the arm.
The P-type control law forced the operator to use such tricks as supplying command set
points beyond the desired location in order to overcome friction. Since assembly of the
EASE joint is repetitive, the operator could learn the necessary master arm motions to
assemble the joint.
During the testing, full size beams approximately 4m long were used. In the swimming
pool facilities available at M.I.T., full size beams are difficult to accommodate, so mini-
beams, approximately 1.5m long, are used instead. The mini-beams have the same beam
ends as the full beams. The difference in joint assembly is contained in the setting of the
rocker, where BAT must move the full beam. In this instance, the inertia of the full beams
made them more difficult to maneuver.
4.2 Manual assembly using PD-type control law
For the purposes of comparing manual and Triad joint assembly, each operator
completed several joints in succession. BAT was mounted to a frame at the bottom of the
pool. Before each run, a diver would place a beam in the retracted beam carrier. The
operator would then power up the arm, extend the beam carrier, and run through the five
steps of assembly detailed in chapter three.
Data taking consisted of video of the operator's eye view through the BAT cameras,
and a record of commanded and actual arm position and duty cycle. As soon as the data
from one run was stored, the operator would start the next assembly. Data storage took
approximately one minute per run.
There were three operators used in the testing. The experienced operator already had
more than 25 hours on the arm as the primary operator during development and the NB-67
31
testing. His experience was exclusively with the P-type manual control system. The less
experienced operator had only two hours of arm time at the start of the testing, but had
more knowledge of the new control system and of Triad. The third operator was naive,
having no operational experience with the arm, and only basic training in its use.
The first testing was performed using a PD control system before the integrator detailed
in chapter 2 was implemented. Assembly times are listed in table 4.1.
Subject:Experienced PD-Control ManualRun #:Grab BeamJointGrab SleeveSlide SleeveStowTotal Time
seconds1 2 3 4 5 6 Average:
15.0 10.0 15.0 13.0 11.0 9.0 12.249.07.08.0
17.096.0
29.09.05.0
28.081.0
30.05.05.0
17.072.0
19.07.03.0
10.052.0
25.09.04.0
16.065.0
Subject: Less Experienced PD-Control Manual
Run #: 1 2 3 4 5Grab Beam 19.0 84.0 39.0 23.0 30.0Joint 37.0 96.0 50.0 7.0 30.0Grab Sleeve 10.0 6.0 11.0 7.0 5.0Slide Sleeve 10.0 26.0 46.0 5.0 5.0Stow 20.0 26.0 10.0 15.0 13.0TotalTime 96.0 238.0 156.0 57.0 83.0
Subject: Niive PD-Control ManualRun #: 1 2 3 4 Average:Grab Beam 215.0 150.0 133.0 116.0 153.5Joint 568.0 90.0 107.0 57.0 205.5Grab Sleeve 18.0 40.0 32.0 24.0 28.5Slide Sleeve 29.0 27.0 40.0 25.0 30.3Stow 48.0 54.0 16.0 21.0 34.8Total Time 878.0 361.0328.0243.0 452.5
28.07.04.09.0
57.0
30.07.34.8
16.270.5
seconds
6 Average:14.0 34.813.0 38.817.0 9.38.0 16.7
14.0 16.366.0 116.0
Table 4.1 Manual PD assembly times
The experienced operator had the shortest times, exhibiting learning through the first
four runs. Run four for the experienced operator was the fastest manual assembly time
encountered in the entire test. Since the addition of a differentiator to the control law does
not significantly decrease steady state error, the experienced operator should continue to
benefit from his experience with the P-type controller. This is quite evident in the graph of
32
command versus arm position. Figure 4.1 shows the shoulder pitch trace as an example.
All the way through the trajectory, the operator's command leads position, overshoots to
keep the arm moving, then comes back to stop the arm motion. The actual arm position is
quite smooth, and as was already noted, quite fast. The commanded position is much more
oscillatory, especially near the end as the arm approaches the stow handle. In this way, the
operator has added his own lead to the system to compensate for the inherent lag in the PD
controller.Experienced, PD Manual, Run 4Shoulder Pitch Trajectory
UUU
-10000
0
4 -15000
-20000
sh position
slp ommadA
0 10 20 30 40
Time (seconds)
Figure 4.1 Example of Operator Addition of Higher Order Control
Traces from the less experienced and naive operators do not show this kind of
oscillation. The commanded position contains the same sort of oscillation, the larger
command to move the arm, followed by a pull back. But in these cases, the pull back is not
as well timed. The pull back is apparently actuated by the operator's view of the arm
overshooting the desired position. This leads to actual arm motion that is much more
oscillatory, and thereby slower.
33
The less experienced operator shows a much more erratic series of assembly times.
This is caused by a series of operator errors such as missing the mushroom with the beam
end and trouble aligning the claw with the sleeve while sliding it. Here the largest variation
is in the completion of the joint. This task requires the application of the correct force to set
the rocker, and the arm is not set up for force control. The result is that the operator must
know the correct master arm motions to apply forces in the correct directions. Without any
force feedback, this can be difficult.
The naive operator has times much higher than the other two operators. His times do
show a learning curve in overall time, though not consistently in each component of the
assembly. Due to operator fatigue, the naive operator only completed four runs before
having to stop.
4.3 Manual assembly using PID-type control law
During a separate test, the experienced and the less experienced operators repeated the
testing using PID arm control. The integrator added the feature of zero steady state error,
balancing out the lag in the system. Assembly times are listed in table 4.2.
Subject:Experienced PID-Control ManualRun #: 1 2 3 4Grab Beam 24.0 20.0 22.0 19.0Joint 60.0 37.0 44.0 104.0Grab Sleeve 12.0 11.0 13.0 18.0Slide Sleeve 19.0 24.0 8.0 10.0Stow 21.0 29.0 19.0 32.0TotalTime 136.0121.0 106.0 183.0 1
Subject: Less Experienced PID-Control
Run #: 1 2 3 4Grab Beam 22.0 18.0 19.0 22.0Joint 86.0 24.0 53.0 24.0Grab Sleeve 12.0 9.0 7.0 11.0Slide Sleeve 15.0 30.0 5.0 4.0Stow 20.0 16.0 17.0 12.0TotalTime 155.0 97.0101.0 73.0
seconds5 6 Average:
17.0 16.0 19.746.0 66.0 59.59.0 8.0 11.8
16.0 6.0 13.819.0 18.0 23.007.0 114.0 127.8
Manual so
536.014.011.04.0
16.081.0
627.08.0
10.03.0
19.067.0
Average:24.034.810.010.216.795.7
Table 4.2 Manual PD assembly times
34
econds
The experienced operator shows an 80% increase in average assembly time. There is
no clear learning curve. It is possible that the experienced operator had to unlearn the
portion of the control law he was used to providing to the P-type controller.
The less experienced operator shows a 20% improvement in average assembly time.
This is the expected result, considering that the arm response is faster and more accurate
here than under PD control.
4.4 Triad assembly
4.4.1 The procedure
The testing was repeated using Triad to replace most of the manual portions of the
assembly. The function of the operator through the Triad portions of the assembly was as
an observer. On one occasion when Triad failed to grab the beam, the operator stepped in
to complete the task manually.
With a beam ready in the beam carrier and the right arm on the stow handle, the
operator began by pushing a button. Triad would extend the beam carrier, grab the beam
with the right arm, release the beam from the beam carrier and move it close to the
mushroom end on the cluster. The operator then moved the beam manually to insert the
connector and set the rocker on the mushroom end. The operator next pushed the same
button to get Triad to grab and slide the sleeve over the mushroom end. Verifying the
sleeve to be slid, the operator would push the button a third time to get Triad to stow the
arm.
The assembly was completed six times in succession. Operator's eye view was video
taped and a trace of the arm command and positions was recorded. This led to the same
one minute delay between runs for data storage.
35
4.4.2 Results
The same less experienced and naive subjects were used for testing. The experienced
operator was not available for this portion. The times for the Triad runs are listed in table
4.3.
Subject:Run #:Grab BeamJointGrab SleeveSlide SleeveStowTotal Time
Subject:Run #:Grab BeamJointGrab SleeveSlide SleeveStowTotal Time
Less Experienced1 27.4 7.6
31.1 27.96.6 5.51.7 5.56.1 7.7
52.8 54.1
Niive Triad1 28.4 7.6
97.6 88.88.3 7.61.6 1.46.5 7.9
Triad37.7
27.95.11.58.3
50.4
326.1
120.56.12.07.8
122.4 113.3 162.5
47.5
47.93.07.69.3
75.4
48.3
31.83.83.56.2
58.2
17.15.9
11.27.6
49.9
58.6
50.45.61.76.6
seconds6 Average:8.0 7.7
82.6 39.15.4 5.21.4 4.87.3 7.7
104.7 64.6
seconds6 Average:8.1 11.2
28.4 69.66.9 6.41.6 2.06.5 6.9
53.7 72.8 51.5 96.0
Table 4.3 Triad assembly times
The less experienced operator was one third faster than his manual PID average; half of
the runs equal or exceed the experienced operator's record manual assembly time of 52
seconds. The times for the portions of the assembly competed by Triad are consistent.
During runs 4 and 5, Triad failed to slide the sleeve all the way. The operator completed
the task with little loss in time. The only real variation comes from the manual portion of
the assembly, the completion of the joint with the operator showing fatigue in the final run.
The naive operator shows an 80% decrease in average assembly time, including one
time faster than the record manual assembly. Again the variability is contained mainly in
the manual joint portion. Grabbeam failed in run 3. The operator recovered without a great
loss in time.
36
Overall Average Assembly Times
452
11b 1 I 128
65
' Less Exp Less Exp. Niw 'PID-Type PID-Type PID-Type
:lanual Triad TriadSubject/ Run Type
Figure 4.2 Overall Assembly Times
4.5 Comparing manual and Triad assemblies
4.5.1 Overall time
Table 4.4 shows the average assembly times of all the test runs. As stated earlier, the
Triad times show a distinct improvement for the operator, comparable to the manual times
of the next more experienced operator. Figure 4.2 shows the same information in graphical
form.
SubjectControl
Grab BeamJointGrab SleeveSlide SleeveStowTotal Time
Experienced L. Exper.Manual PD Manual PD
12.2 34.830.0 38.87.3 9.34.8 16.7
16.2 16.370.5 116.0
Table 4.4 Overall Assembly Times
37
500 -
450 -
400 -
350 -
o : 300 -0·D 250 -
v]
200 -
150 -
100 -
50 -
El Stow
IZ Slide Sleeve
[ Grab Sleeve
U Joint
1 Grab Beam
70
0 .1 1.1 IExpert
PD -Type
96
Less Exp.PD-TypeManual
N'ivePD-TypeManual
ExpertPID-Type
Manual
NaiveManual PD153.5205.528.530.334.8
452.5
ExperiencedManual PID
19.759.511.813.823.0
127.8
L. Exper.Manual PID
24.034.810.010.216.7
95.7
L. Exper.Triad
7.739.15.24.87.7
64.6
NaiveTriad11.269.66.42.06.9
96.0
BA~
K
i
rz A \q R-\J
.I
I-
w I I i I X !! ,
4.5.2 Joint completion time
As stated above, since Triad does not replace the entire joint-making portion of the
assembly, the times for this portion of the assembly remain variable for the Triad runs. The
task is still the same. The operator must move the master arm to build up a command
position error on the slave arm to apply force on the beam sufficient to set the rocker. The
amount of the force is not always the same due to the differences between rockers, the
position of the right arm grip on the beam end, and the position of the cluster in the left
arm.
For the less experienced operator, the joint completion portion is not significantly faster
than for manual completion. But for the naive operator, the time for joint completion is
much improved, two thirds faster than his manual time. This is perhaps due to the lowering
of workload on the operator. The naive operator can now concentrate on learning and
performing the joint completion. The lower workload and the faster completion times also
lead to lower fatigue levels for the naive operator allowing for better performance.Average Assembly Times without Joint
250 -
200 -
,)
o0la>
100-
50 -
0
40
77
247 1
UX
L1 Grab Beam
68 6161
25 26Ong
+ + l l l
Expert Less Exp. Nive Expert Less Exp. Less Exp. Na'ivePD-Type PD-Type PD-Type PID-Type PID-Type PID-Type PID-TypeManual Manual Manrual Manual Manual Triad Triad
Subject/ Run Type
Figure 4.3 Overall assembly times showing Triad replaced portions only
38
[] Slide Sleeve
U Grab Sleeve
__J__,, ~ ~ - . -
4.5.3 Tasks covered by Triad
Figure 4.3 shows the overall assembly times only for the portions of the assembly
replaced by Triad. There are two major points here.
· First, the decrease in assembly times are concentrated in these four portions of the
assembly, so the differenced are more pronounced.
* Second, the Triad times for the less experienced and naive operators is nearly the same,
verifying that Triad assembly does not depend on experience.
39
5. FULL EASE STRUCTURE ASSEMBLY
5.1 Results of NB-67
5.1.1 Test setup and procedure
In January of 1987, during test NB-67, BAT successfully completed the EASE
structure at MSFC-NBS using manual control and a P-type control law on the arm. This
was the first full scale demonstration of teleoperated structural assembly in zero gravity.
The intent of this demonstration was to generate data to be used in trade offs between using
teleoperators and humans in space. The testing is detailed in [5].
Figure 5.1 NB-67 Structural assembly setup
The MSFC-NBS consists of a cylindrical tank of water 12m deep and 23m across. A
mockup of the space shuttle payload bay across the bottom of the tank was used as a base
for BAT's EASE structure assembly. The EASE base cluster was attached to the side of
the payload bay. Since the shuttle bay doors were not included in the mockup, BAT could
approach the base cluster from outboard and below. Beam and cluster supplies were
40
simulated by a rod attached to the other side of the mock up. Docking to this rod, BAT
would receive a beam or cluster from a support diver.
ICS was located along a walkway outside the tank. The operator had no direct view of
BAT. Together with the video from the cameras onboard BAT, ICS was also equipped
with video from cameras on the bulkhead of the payload bay and on the side of the tank.
These external views were very useful for planning longer flying trajectories and for
operator orientation.
Due to limitations on battery life and pressurization and pneumatic air supplies, BAT
was able to operate for one hour at a time, insufficient for a full assembly of the EASE
structure. Instead, the steps toward the completion were done separately and repeatedly
over several runs. Video tape data from these runs were then used to determine a time for
full structure assembly.
5.1.2 Times for assembly and proportions
Assembly of the Ease structure was divided into four major steps, each repeated three
times. Each of the major steps were then divided into three or four tasks and each task
divided into up to 16 primitive tasks. The full break down is listed in appendix V. The
major tasks are
1. Attach a cluster to a beam in the beam rack.
2. Attach an upright beam to the base cluster.
3. Attach a cross beam to a top cluster.
4. Complete a triangle joint. Attach the free end of a cross beam to the appropriate top
cluster. Structural constraints make the beam manipulation more difficult in this task.
Each major task is made up of four primitive task types. These are flying and docking,
beam retrieval, video switching, and joint assembly.
Using these divisions, the first full assembly time for the EASE structure was found to
be 89 minutes, slightly longer than the 71 minutes for the first neutral buoyancy assembly
41
by a pressure suited subject. The first BAT assembly was divided into 36% flying and
docking, 4% beam retrieval, 4% video switching, and 56% joint assembly.
5.1.3 Comments on Fatigue
The high percentage of joint assembly time prompted the development of Triad with the
intent of lowering the workload of the operator. One hour seemed to be the limit on
continuous teleoperation before the operator began to fatigue significantly. With this figure
it seems improbable that if BAT itself were capable of carrying sufficient consumables for
the hour and a half necessary for a end to end manual assembly, that the operator would be
capable of completing all 12 major tasks in one sitting. Decreased workload is another
driving force behind the study of automation of whatever portion of the assembly is
possible.
5.2 Results of NB-67C
5.2.1 Test setup and procedure
In January of 1988, during test NB-67C, BAT went back to MSFC-NBS for the
purpose of assembling the EASE structure with the addition of supervisory control.
This time the setup was changed to attempt a more realistic configuration. The
configuration used during STS flight 61B held the beams in a vertical rack with the clusters
placed on top. Since BAT requires more elbow room, and to avoid getting tangled up in
the payload bay, the beams and cluster were held in horizontal racks at the level of the top
of the payload bay. The base cluster was placed on the same pallet at the center of the
payload bay. See figure 5.2.
This set up is a more accurate approximation of an actual flight configuration. The
extensive use of divers in the NB-67 set up was eliminated.
Due to mechanical problems, it was not possible to complete the entire EASE structure
at MSFC-NBS. Repeated times for each task were recorded. Times for many of the tasks
involving Triad use were verified at the M.I.T. Alumni Swimming Pool.
42
Figure 5.2 NB-67C Structural assembly setup
The procedure again contained four major tasks as follows:
1. Attach a cluster to a beam in the beam rack. This involves docking to one of the
grappling points on the cluster rack with the left claw, retrieving a cluster with the right
arm, flying to the next available beam in the beam rack, docking and attaching the cluster to
the beam end.
2. Attach an upright beam to the base cluster. Once the clusters are attached to the first
three beams, the first two beams are attached to the base cluster as uprights. This involves
flying to the beam rack, docking to the next available grappling point, retrieving a beam
from the rack with the beam carrier, flying over to the base cluster, docking, and attaching
the beam to the base cluster.
3. Attach a cross beam to a top cluster. Once two riser beams are attached, the clusters
on their free ends are available. Between these, a cross beam is attached. This involves the
same procedure as in major task 2, except that the beam is attached to a top cluster instead
of the base cluster.
43
4. Complete a triangle. This involves completing the second connection to a cross
beam and immediately follows attaching the first connection to the cross beam. BAT
translates along the cross beam, docks to the free end of the beam and maneuvers it close to
the cluster. The operator then uses the right arm to grab the top cluster and bring it in to
make the joint.
5.2.2 Mechanical setbacks
The PID control system, in the process of tightening up the response of the arm, also
increases the wear. The point to point arm control system is very discontinuous in
acceleration. As each new command comes in, the duty cycle changes instantly, changing
the torque on the motor and giving a jerk to the ann. In comparison, the P-type motions
were more smooth due to the slow and linear change in duty cycle with respect to command
position error.
As a result, during the testing at MSFC-NBS, several of the arm components
malfunctioned, bringing testing to a sudden halt. During the course of NB-67C, one of the
wrist encoders failed due to moisture, the elbow bearings occasionally froze, the shoulder
pitch motor coil melted, and a brush on the shoulder yaw motor failed. All of these
problems were repairable. If, indeed, they had occurred simultaneously, they could have
been dealt with without loss of too much testing time. They were not simultaneous,
however. The more the arm was run using the high PID gains of Triad, the more
breakdowns occurred. Only after three weeks of overhaul back at M.I.T. was the arm
completely functional again.
5.2.3 Estimation of Triad assembly times and proportions
Using the task component times developed during NB-67C and subsequent pool tests
at M.I.T., an assembly time of 72 minutes was established. Considering that the operator
did not have extensive experience with the full EASE structure, the assembly can be
considered a first assembly and is comparable to the naive pressure suited subject time of
44
71 minutes. The time spent on assembly was broken down to 51% flying and docking,
5% beam retrieval, 5% video switching, and 39% joint assembly.
5.3 Comparison of NB-67 and NB-67C data
5.3.1 Direct comparison of assembly times
There are two major differences between the assemblies in NB-67 and NB-67C. One
is the difference in setup, leading to flying times that are not directly comparable. The other
difference is, of course, the joint assembly (manual or Triad). These tasks are exactly the
same in result, and can thereby be compared directly. Table 5.1 shows the direct
comparison of NB-67 assembly times and those of NB-67C.
EASE Assembly BreakdownManualTriad Major Task (times in seconds)NB-67 NB-67C Task Component393 177 1. Attach a Cluster to a Beam in the Beam Rack97 46 A.Fly to cluster rack (from free beam end)62 31 B. Get cluster from cluster rack90 46 C. Fly to beam end
144 54 D. Attach cluster to beam522 472 2. Attach an Upright Beam to the Base Cluster56 103 A. Fly to beam rack (from cluster rack, base cluster, top cluster)41 38 B. Load a beam in the beam carrier
109 180 C. Fly to the base cluster316 151 D. Assembly beam to base cluster442 433 3. Attach a Cross Beam to a Top Cluster46 148 A. Fly to beam rack (from base cluster or top cluster)34 37 B. Load beam in beam carrier
116 110 C. Fly to proper top cluster246 138 D.Assemble beam to top cluster427 364 4. Complete a Triangle Joint
91 81 A. Fly to the free end of the beam32 18 B. Fly beam end close to cluster
304 265 C. Assembly joint53524338 Total Assembly Time
89.2 72.3 minutes
Breakdown (times in minutes)31.9 36.6 1. Fly and Dock3.8 3.7 2. Beam Retrieval (from rack)3.5 3.4 3. Video Switching
50.2 28.5 4. Joint AssemblyTable 5.1 Direct comparison of assembly times
45
The flying times differ by nearly five minutes overall. The significance of this will be
discussed in the next section. The beam manipulation and video switching times were
nearly the same. The big difference, as one might expect, is in joint assembly, where the
Triad time shows a 43% reduction from the manual time. Again, the Triad assembly still
includes the manual setting of the rocker, the most time consuming portion of the
assembly. This shows a significant advantage to supervisory control, even in this primitive
application.
5.3.2 Weighted comparison
The setup for NB-67 was very different from that of NB-67C. This leads to different
proportions in flying times. The flying times during NB-67 do not have a defined
beginning point, only a defined end point. When getting the beam, the operator would
dock to the rod shown in figure 5. 1, or receive the beam from a diver at an undefined
location. The position of the base cluster was not constant, changing position depending
on the other testing being performed at the time. In NB-67C, the process is exactly the
same each time, starting at the same beam rack grappling point or the same top cluster.
This is a more realistic simulation of an orbital assembly.
For the purpose of better comparing the overall times, table 5.2 shows the NB-67 joint
assembly with NB-67C flying times. It is important to note that the operators during both
test doubled or tripled their operation experience during the test. It is easy to accept that an
operator with more experience free flying open loop could easily lower these times.
46
AmalgamationManual Triad Major Task (times in seconds)NB-67C NB-67C Task Component298 177 1. Attach a Cluster to a Beam in the Beam Rack46 46 A.Fly to cluster rack (from free beam end)62 31 B. Get cluster from cluster rack46 46 C. Fly to beam end
144 54 D. Attach cluster to beam637 472 2. Attach an Upright Beam to the Base Cluster103 103 A. Fly to beam rack (from cluster rack, base cluster, top cluster)
38 38 B. Load a beam in the beam carrier180 180 C. Fly to the base cluster316 151 D. Assembly beam to base cluster541 433 3. Attach a Cross Beam to a Top Cluster148 148 A. Fly to beam rack (from base cluster or top cluster)37 37 B. Load beam in beam carrier
110 110 C. Fly to proper top cluster246 138 D.Assemble beam to top cluster403 364 4. Complete a Triangle Joint
81 81 A. Fly to the free end of the beam18 18 B. Fly beam end close to cluster
304 265 C. Assembly joint56374338 Total Assembly Time
94.0 72.3 minutesBreakdown (times in minutes)
36.6 36.6 1. Fly and Dock3.8 3.8 2. Beam Retrieval (from rack)3.5 3.5 3. Video Switching
50.2 28.5 4. Joint Assembly
Table 5.2 Comparison of manual and Triad assembly times with NB-67C flying
From Table 5.2, it is clear that the addition of Triad alone has lowered the estimated
total assembly time by 23%, and the joint assembly time specifically by 43%.
5.4 Limitations of the present configuration
Triad, by comparison with other supervisory control methods, is an automation of only
a limited portion of the assembly process. The present hardware and sensor configuration
of BAT limits what can be done. These limits will be discussed in detail in chapter 6.
47
6. CONCLUSIONS AND RECOMMENDATIONS
6.1 Conclusions
Teleoperation is needed for task completion in dangerous environments. Supervisory
control extends the abilities of manual control for better repeatability, speed and duration.
A method was presented for applying a task primitive supervisory control to the Beam
Assembly Teleoperator, and compared with manual control modes. The supervisory
routines, known as Triad, allowed the operator to relinquish control of BAT's dextrous
arm to the computer for several portions of the joint assembly.
Manual and Triad enhanced control were compared by repeated assembly of the EASE
joint by three operators of varied experience, and by assembly of the full EASE structure.
Various types of manual control were also used. A PD-type manual control system proved
best for the operator experienced in using a P-type control system. Command inputs by the
experienced operator were shown to contain a higher order control strategy to optimize the
performance of the PD control. A PID-type manual control system reduced assembly times
for the less experienced operator by 20% due largely to improved tracking. The
experienced operator's times, however increased by 80% from the PD- to the PID-type
system, attributable mainly to unlearning of previous control techniques.
The addition of Triad produced a decrease of 80% average assembly time for the naive
operator and 30% for the less experienced operator. Half of the less experienced operator's
times under Triad equaled or exceeded the experienced operator's fastest manual time. For
the portions of assembly controlled by Triad, average assembly times were nearly the same
for the less experienced and the naive operators, showing an independence with respect to
training.
For full EASE structural assembly, Triad produced an estimated full assembly time of
72 minutes, 20% faster than the previously established manual time of 98 minutes, despite
48
increased times for flying and docking. The times for the portions assembly under Triad
control were decreased 43% from the corresponding manual times.
6.2 The future of BAT
The purpose of BAT as set out in Eric Shain's thesis [10] is to extend the Space
Systems Lab's work in the area of human assembly of simulated space structures in the
direction of man-machine systems. BAT was designed specifically for assembly of the
EASE structure. Productivity results could then be directly compared with those produced
by manual assembly. Shain envisioned a more dextrous arm, stereo vision systems, and
innovative control schemes in the future.
One area yet to be explored is that of coordinated control of the body of BAT and its
arm together. The need to coordinate is inherent in a zero gravity environment. In
manipulation of some object of finite mass, the base of the teleoperator will also move,
causing errors. John Spofford in [11] and Craig Carignan in [12] deal with this problem in
detail. In the case of BAT, the manipulator arm is missing a degree of freedom in rotation.
Coordinated control would allow for the use of the propulsion base to make up for this lost
ability.
Presently, BAT gets around the problem by docking to some object defined as fixed
and manipulating objects in a reference framed based on that object. In space, there are
instances in which this will be unacceptable. One example is that of completing a triangle
in the construction of an EASE structure. In order to complete a triangle, the operator
docked to the top beam and flew it over to upright beam. On arrival, he maneuvered the
base of BAT to align the cluster and the beam, in some cases actually moving the entire
EASE structure. Only after the beam and cluster had been properly aligned and the cluster
brought into the range of the right arm, could the operator power up the arm and complete
the task.
49
Herb Viggh, in [5], tried several methods of combining control of the propulsion base
and the arm at the same time, a total of eleven degrees of freedom. Using the head
controller for rotation, he controlled three DOF with his head, one hand on the translation
joystick, and the other in the master arm controlling the right arm. In another mode, he
used a finger switch to use the master arm alternately to control the right arm and the
rotational DOF of the propulsion base. With enough repetition these modes might have
become natural to the operator, but the biggest barrier was that the propulsion system and
the right arm positioning were independent. Using coordinated control, the operator need
only be concerned with the position of end effector and allow the control systems to figure
out what combination of propellers and servos are required to get it there. The barrier
between BAT and coordinated control is a lack of sensor capability. The propulsion
system currently runs open loop, without feedback. The Three Dimensional Attitude
Positioning System, 3DAPS, under development by the SSL, shows promise for
providing absolute positioning information.
Improvement of the right arm control involves modeling. Due to water drag, water
currents, motor damping, backlash, encoder noise and non-linear duty cycle to torque ratio,
modeling would be quite difficult. Implementation of a model based control system would
be facilitated by joint velocity feedback and determination of joint torque.
Another direction is that of compliance control. With the addition of force sensors to
the wrist of the right arm, elements of force control could be added. This would be
especially advantageous for joint completion. A force controller could slide the beam end
and mushroom together and control the force necessary to set the capture rocker.
The addition of proximity sensors in each of the claws would increase the information
available to a program such as Triad. Many of the errors possible with Triad could be
avoided if the system knew whether the right claw was approaching a target or whether the
beam carrier actually held a beam to be retrieved.
50
Considering these possible directions of research, the preceding chapters should be
considered a report on the progress of the Beam Assembly Teleoperator, not its
completion.
51
REFERENCES[1] Akin,D.L., Minsky,M.L.,Theil,E.D.,Kurtzman,C.R.Space Applications of
Automation, Robotics and Machine Intelligence (ARIMIS) - Phase II, NASA CR 3734,1983.
[2] Sheridan,T.B.,Supervisory Control of Remote Manipulators, Vehicles, andDynamic Processes: Experiments in Command and Display Aiding. Cambridge: Man-Machine Systems Laboratory Report, 1983.
[3] Akin, D.L., et al., EASE Final Report, in preparation.
[4]Spofford, J.R., Beam Assembly Teleoperator: Coordinates and Kinematics. MITSpace Systems Laboratory Report #6-87, 1987.
[5] Viggh, H.E.M, Artificial Intelligence Applications in Teleoperated RoboticAssembly of the EASE Space Structure, M.S. Thesis, M.I.T., 1987.
[6] Brady, M. "Trajectory Planning", Robot Motion: Planning and Control,Cambridge: MIT Press, 1982, pp.2 2 1 -2 4 3 .
[7] Marra, A., Human Operator Performance in Dynamic Multi-Task Environments,M.S. Thesis, M.I.T., 1988.
[8] Astrom, K.J., and Wittenmark, B, Computer Controlled Systems, Theory andDesign, Prentice-Hall, 1984.
[9] Ziegler, J.G., and Nichols, N.B., "Optimal Settings for Automatic Controllers,"Trans. ASME, v64, pp759-768, 1942.
[10] Shain, E.B., "Design and Control of a Beam Assembly Teleoperator ", M.S.Thesis, M.I.T., 1983.
[11] Spofford, J.R., "Coordinated Control of a Free-Flying Teleoperator ",PhDThesis, M.I.T., 1988.
[12] Carignan, C.R., "Control Strategies for Manipulating Payloads in Weightlessnesswith a Free-Flying Robot ", ScD Thesis, M.I.T., 1987.
52
APPENDIX I. BAT mobility using RMS
In January of this year, during test NB-67C, an opportunity arose to use the neutral
buoyancy version of the shuttle Remote Manipulator System (RMS) for BAT's mobility.
The back side of BAT was attached to the RMS end effector and BAT's thrusters were
disabled.
During the short test, the RMS operator maneuvered BAT to dock to a cross beam of a
completed EASE tetrahedron, then translate along the beam and dock to the other end of the
same beam. The first docking took 19 minutes. The translation and second docking took 7
minutes. These are compared with average free flying times of 1.5 minutes for each
maneuver.
The operating conditions were difficult. The RMS operator at the MSFC-NBS is
stationed on the second level on the outside of the tank with only a view through a porthole
to work with. Distortion through the glass and a working distance of lOm made depth
perception difficult. The ICS operator, with the assistance of BAT's belly and tilt and pan
stereo cameras, gave directions to the RMS operator in vehicle coordinates. The operator
then figured out which joints to move to produce the cartesian movement. The mechanical
condition of the RMS was also not perfect. Potentiometers controlling several of the joints
of the RMS were not steady, making station keeping non-trivial.
Still, the demonstration was successful. The RMS positioned BAT sufficiently for
docking.
There are advantages to using an arm for base mobility. Since the RMS is mounted to a
sufficiently large mass, station keeping and reaction forces during manipulation are not as
important. BAT can swing a beam without the beam and BAT swinging toward each
other. A by-product is that BAT need not dock to any other fixed target in order to interact
53
with it. This does assume an arm that provides rigid positioning, not completely true for
the RMS.
This particular demonstration warrants repetition under better conditions. First, the
RMS controls at MSFC-NBS are two 3DOF hand controllers, with each DOF directly
controlling one joint of the RMS in rate. Using a resolved rate joystick control has been
shown to be much more productivel in manipulation. The key is to make the control of the
RMS as transparent as possible. If the operator is working from the vehicle cameras, the
control system should take input in vehicle coordinates. Second, the RMS operator should
have a good view of the scene, such as shuttle bay bulkhead cameras, RMS cameras, and
vehicle cameras, perhaps under the control of the vehicle operator. A stereo image is more
helpful than a single image2. The sum of this is that the operator of the teleoperator should
not feel the difference between free flight and RMS positioning, except for the advantages
in the increased station keeping inertia afforded by the anchoring of the RMS.
1Poulton, E.C., Tracking Skill and Manual Control, New York: Academic Press, 1974.
2 Cole, R.E., Pepper, R.L., and Pinz, B.E., The Influence of Head Movement Parallax on Perceptual
Performance Under Direct and TV-Displayed Conditions. San Diego NOSC Technical Report #678, May,
1981.
54
APPENDIX II. BATSOFT/ - ---------------------------- --/* The following is a listing of the PC portion of the BAT software.** It is a bit jumbled due to the number of authors, but rve tried to** strearmlirl it as much as possible. Nonfunctional subroutine have** been commented out, but are keep as a record. TRIADl.c and** TRIAD2c, found at the end, are entirely my own. DEA 3/88 *//* --------------------- ----- - - ---------
/* -- BATSOFT.c -- Main Programs for BAT operation. *//* Requires support files as follows: *//* SUPPORT1, SUPPORT2, SUPPORT3, SUPPORT4, SUPPORTS, DATERS, PCIO** Triadl, andTriad2 *//* Beam Assembly Teleoperator Controller
version 6.4October 1987
(revisions: Finger Switch access to Triad)John Spofford, Tom Waschura, Tony Manganiello, Herbert Viggh
& David E. AndersonSpace Systems Laboratory
Massachusetts Institute of Technology */
#include "DAT.H" / defines data logging */#include "PORTNUMSH" /* defines io ports & commands */#defineRABKDZ 8 /* deadzone for backup arm pots */#define RASTDZ 24 /* dz on stick control */#define SWITCH_TC 12 /* 13 sec lockout at 9 samples/sec */#define ACTCOLS 17 /* display actuator columns in screen */
/* -------------------------------------------------------------
int testing; /* flag for development */mainO
extm int testing;char tempc;
scrdr0;initialize_bat();calibrate_bat();screen();run bat();shutdown_bat();
/* --------------------------------------
/* initialize_bat -- set up io ports, set initial values,** */
initialize_batO
inti;
scr_rowcol(23,0);printf("Initializing\n");batports();
outport(P4C,0); /initialize video switching - inactive since v5.4*/outport(POC,OxB8); /* cs high, rnaster&puma stb hi *1outport(POA,0);outport(P1B,0);outport(P1C,OXC0);/* 11000000 spare pue high default /outport(P2C,0xlF); /* 00011111 JM-STB high, all pnuematics default */outport(P3A,0);outport(P3B,0);outport(P3C,O0);outport(POX,C6HI); /* reset JCS */outport(P2X,C7HI); /* reset propulsion controller */for (i = 0; i < 20; i++); /* pulse width */outport(POX,C6LO);outport(P2X,C7LO);for (i= 0; i< 36; i++)
synchronizeO; /* let JCS check memory */
printf("Loading JCS software\n");if (load_control_system0)
printf('n%cError loading control system software\n",7);shutdown_bat();exit(0);
start_logO; /* init data recording buffers */
/*----------------------- ----- SI--------------/* calibrate_bat --** */
/* triad preset variables */int funmelspeed;char triad_data;/* ------------------------ /
55
int stickoff[6];int rbkoff[5],masoff[5]; /* backup & master offsets */float rbkmul[5],masmul[5]; /* backup & master multipliers *//*This has been added to the current batsoft for the purposeof slaving thbe tilt and pan unit to the head controller.The head controller has five pots from which canpitch. yaw,androll can be calculated. The mux assigrments are:
pot name pot label(x,y) pot#
top yaw 0,5 1top pitch 0,6 2roll 10,0 3botpitch 11,0 4botyaw 12.0 5
tilt = cpitch = bot pitch - top pitchpan = cyaw = bot yaw + top yawroll = roll HV 2/6/85 */
intpotlabelx[5] = 0 0 101112 };int potlabely[5] = { 5 6 0 0 0 };int headoff[5]Ahpot[5];float cpit-mult = 1.0;float cyawmult = 1.0;int cpitchcyaw;int wra_off,wrb_offelb_off;float p_mult,rmult,ymult; /* arm flying */float ppit_mult,pyaw_mult,prol_mult; /* head flying */float joymult[6];int pheadoff[5];int ppitch,pyaw,proll;
calibrate_ba)
static int maxindex[5] = ( 9, 6, 5, , 2 };static int min_index[5] = { 7, 8, 4,1, 3 };static int count_index[101 = { 6, 6, 7, 7, 5, 5, 4, 3, 4, 3 };extem int stickoff[6];extem int rbkoff[5]masofflS5]; /* backup & master offsets */extem float rbkmul[5],masmul[5]; / backup & master multps */int i, dummy, word, fp, count, tdat;,char tempc;float tmpf;float batmax[5], bat min[5];int batmp[l10];extem intmaxjcs_val[8], minjcsyval[8];extem char imvt2[8], icnvt[8];extem float align gain[8];extem int alignoffset[8];extem int headoff[5];extem float opitmult'cyaw_mult;float gain[13];extem float p_mult,rmnult,y_mult; /* arm flying */extem float ppitmult,pyawmult,prol_mult; /* head flying */externm int wra_off,wrb_offelb_off;extem int pheadoff[5],h_pot[5];extem int furmelsped;extem char triad_data;
funnel_speed = 0x400;triaddata =FALSE;
scrrowcol(23,0);scr_drlO;printf("Calibrating, return joysticks to center.');for (i = 0; i <= 32000; i++)
dummy = 1 *2*3*4*5;dummy=1 * 2* 3 *4 *5;dummy=1 *2*3*4*5;
stickoff[O] = convert(0,8) & OxFFF;stickoff[l] = convert(0,10) & OxFFF;stickoff[2] = convert(0,9) & OxFFF;stickoff[3] = convert(6,0) & OxFFF;stickoff[4] = convert(7,0) & OxFFF;stickoff[5] = convert(8,0) & OxFFFP;for (i = 0; i <= 5; i++)
stickoffli] = 1024 - stickoff[i];
scr_setmode(0);if ((fp = open("BAT_SET.ARM",0)) != -1)
for (count = 0; count < 10; count++)
while((tempc = getc(fp)) !=':');fscanf(fp,"%fin' ,&tempf);battemp[count] =tempf;
for (count = 1; count < 3; count++)
while ((tempc = getc(fp)) != ':');fscanf(fp,"%fW',&tmpf);
56
maxjcsval[count] = tempfwhile ((tempc = getc(fp)) != ':');fscanf(fp,"%fn`",&trmpfO;min jcs_val[countl = tempf;
for (count = 0; count < 13; count++)
while ((tempc = getc(fp)) !=':');fscanf(p, "%f\n",&tempfO;gain[count] = tempf;
for (count = 0; count < 6; count++){while ((tempc = getc(fp)) = ':');fscanf(fp,"%fn",&tempf);joymultcount] =tempf;
close(fp);
else
scr_setmode(2);printf('n\n%c==> BAT armnn data not found <---n",7);exit(1);}
for (i=O; i<5; i++){align_gain[i+3] = gain[i];}
cpitmult = gain[5];cyawmnult = gain[6];pmult = gain[7];rmult = gain[8];ymult =gain[9];ppit_mult = gain[10];pyawmult = gain[ll];proLmult = gain[12];for (i = 3; i <8; i++)
tdat = (convert(icnvt2[i],icnvt[i]) & OxFFF) -1024;tdat = adjust(tdati);batmax[i-3] = (float) batJenmp[max-index[i-3]];batmin[i-3] = (float) bat tenp[min_index[i-31];word = (int) ((batjnax[i-3]+bat_min[i-3])/(2.0*aligngain[i]));align_offseti] = word - tdat;maxjcsval[i] = (int) batmax[i-3];minj cs_val[i]= (int) batmin[i-3];
wra_off = convert(2,0) - 1024;wrb_off = convert(1,0) -1024;elb_off = convert(3,0) -1024;
read _had();for (i=O; i<=4; i++) /* liad controller offsets
{eadoffi] =h-pot[i];pheadoffi] = h_pot[i];
/* -------------------------------------/*run_bat-- */
r The following RAM is set aside for joint positioncontrol. The arrays are used as follows:
maxp .. maximum positive positionmin_p....... aximum negative positiondiv ormul..left or right shifts?pgain..n....umber of bits to shiftprangeerr..a range error occured on that joint
Note, all are indexed from 0 to 7 which correspond todifferent joints. The actual correspondence is:
0............left arm1............camera tilt2...........camera pan3............wrist a4............wrist b5............elbow6............shoulder yaw7............shoulder pitch
These are software definable as to the addresses andcommands in iaddr and icmnd.
T.E.W. April 24,1984 */
char *potname[8] ={"Left ArmN0", "Camera TiltNO", "Camera PanNO",
57
"Wrist A\0), "WristBVY, Elbow\0","Shoulder Yaw\D', 'Shoulder Pitch\0"};
......-------------.. Lcft,CarmT,CamP, WrA, WrB,Elbow, ShY, ShP)*/char icnvt2[8]
={ 0, 0, 0, 2, 1, 3, 4, 5);char icnvt[8]
={ 2, 5, 6, 0, 0, 0, 0, 0);intmrnaxp[8]
= { 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024};int minp[81
= { -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1024);int div_or_ mul[8]
= { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);int pgain[8]
={ 0, 0, 0, 0, 0, 0, 0, 0);int prangeerr[8]
= { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);static char iaddr[8]
={ 3, 4, 4, 1, 1, 3, 2, 2};static char imnd[81
= { 0x90, 0x80, 0x90, 0x80, 0x90, 0x80, 0x90, 0x80);int maxjcs_val[8]
= {0x07FF,0x0 78 , x0600,OxO7A,0x0780,0x0660,0x0140};int minjcs_val[8]
= { xF800,OxF880,0xF80,0xF880,OxFA20,xFC00,0xF960,OxFB80};int alignRoffset[8]
= { 0, 0, 0,xFE90,0x0213,0x03DF,OxOD48,0xFC06};float aligngain[8]
= { 1.0, 1.0, 1.0, 3.00, 3.00, 1.75, -4.00, 1.25);int cardorder[8]
={ 6, 7, 8, 1, 2, 5, 4, 3);/*-------------{ Left, CamT, CamP, WrA, Wr B, Elbow, ShY, ShP)*//* dataset 4/13/84 JRS */int nnf[8] = {3, 4, 7, 6, 5, 0,1, 2);int slave_toggle; /* variables for slaverest()*/int currmaster[5],curr_h_pot[5];int set_triad;int Gain[9], alpha[9], beta[9], alg[9], pos[9], multl [9], mult2[9];int joint_pos[8], jointcom[8];char comr_disp;char mdat[30], mcom[30], madd[30];char data_flag, boost_flag; /*logical flags*/char leftclaw_state, masterconnected;char head_controller, pumaon, draw, right_dclaw;char head_ctrlconnected, slave_arm_on;char masterflying, head_ctrl_flying;char beam_carrier, beamC_daw;char sparel, spare2; /*spare pnuematics toggles*/
/* successive triad counters for forward and reverse assembly */int trifor, trirev;
DATATAG cnt[TAGSIZE] = ("ALAoop counter"};DATATAG thO[TAGSIZE] = {"BIFjoystisk tbr");DATATAG thl[TAGSIZE] = "CIFtrimmed thr"};DATATAG rawmfTAGSIZE] = {"DIEraw master"});DATATAG jcomTAGSIZ] = {"ElEjoint com"};DATATAG jpos[TAGSIZE] = ("FlEjoint pos");DATATAG zcnt[TAGSIZE] = "GIAz80 loop");DATATAG adty[TAGSIZE] = {"HEarmn duty");P--------- ------------------------- 4/
runbat(
extem char comnm_dip;extemn pos[9];extem char mdat[30],mcom[30],madd[30]; /* master transmit buffer */charpdat[10];extem char cswitch[16]; /* ICS control switches */char ij,ktempc;char comrow,pos_row,thr_old_row[6] ,old_corn_row[8] ,oldposrow[8],col;char row; /*display parameters */int dvec[8][ACTCOLS+1]; /* display filter */int thrraw[6], thrJtrim[6], temp; /* x,y,z,p,r,.y */extem int maxjcsval[8], minjcsval[8];extem char icnvt2[8],icnvt[8];extern int set_triad;float spw;
int mlast,plast;int proll,p_pitchpaw,px_yaw,pxp_y,pz;int tdat,actdat[8];int a_syaw,a_spit,a_elbo,a_wrol,a_wyaw,aJeft;extem int testing;
extem char dataflag; /* logical flags */extem char left_claw_state, master_connected;extem char headcontroller, puma-on, draw, rightLaw;extem char headctrl_conncted, slave_arm_on;extem char masteriflying, headctrl flying;extem char beam_carrier, beamcdaw;extem char keep[MAXGRPNUM]; /* select variables */int rawmaster[5];
/* puma transmitbuffer */
/* fast loop index, temp */
/* master,puma buffer ends */
/* temp & data */
58
int posm[8];exte int joint com[8], joint_pos[8];int thr_boost[6];
int tran um;char jump, /* flag for arm jump */extem int curr_master[5];extem int stickoff[6];extem int rbkoff[5],masoff[5]; /* backup & master offsets */extem float rbkmul[51,masrmul[5]; /* backup & master mults */int counter; /* mainloops */extem int slavetoggle; /*toggle to reset slave arm gains*/extem int potlabelx[5],potlably[5]; /* head controller muxes */extem int headoff[5]; / hc offsets */extem float cpit_multcyaw_mult /* he multipliers */int extem h_pot[5];int extem cpitch,cyaw;int oldheadofflS],old_hpot[5];int loopz80, armduty[5];extem int curr hpotl5];
exte int wra_off,wrb_off clb_off;it wra_raw,wrb_raw,elb_raw;int a_adelta_b,delta_c;extem float p_multr_mult,y_mult;extem float joy_mult[6];extem ppitch,proll,pyaw;/* successive triad counters for forward and reverse assembly */extem int tri for, trirev;
for (i = 0; i < 8; i++) * aet up display filters */
spw = ((float) (maxjcs_vali]-minjcs_val[i]))/((float) ACTCOLS);dvec[i[0] = maxjcs_val[il;dvec[i][ACTCOLS+11] = minjcs_val[i];for (j = 1;j <= ACTCOLS; j++)
dveci][j] =max jcsyal[i - (int)(((float)j)* spw);
trifor = 1;tri-rev = 1;comm_disp =FALSE;puma_on = FALSE;head_controller = TRUE;draw = TRUE;dataflag = FALSE;leftdclawstate =FALSE;boost_flag = FALSE;masterconnected = TRUE;headctrl connected = TRUE;slavearm_on =TRUE;masterJlying = FALSE;head_ctrl_flying = FALSE;rightdlaw =FALSE;slavetoggle = 0;beam_carrier = TRUE;beamclaw = FALSE;sparel = FALSE;spare2 = FALSE;jump = FALSE;set_triad = 0;
outport(X,C7HI); /* reset propulsion controller */for (i = 0; i < 20; i++); /* pulse width */
outport(P2X,C7LO);for (i = O;i < 6;i++)
pdat[i] = 128; /* zero each command */tranpuma(pdat,5); /* Prevent thruster start-up */
screen2();for (i = 1; i <= 4; i++)
startjc(i); /* start card #1,2,3,4 */for (i = O;i <= 5; i++)
throld-row[i] = 13;oldcomrow[i] = 13;old..posrow[i] = 13;
old_com.row[6] = 13;old_comrow[7] = 13;old_pos_row[6] = 13;old_posrow[7] = 13;
outport(P2X,COLO); /I ACTIVATE POWER RELAY */
/* avoid randonmss */
synchrncize0;for (counter = 0; TRUE; counter++) / as long as in sync...*/
statO;ff(dataflag)
indexlog();outport(Y2X,C6HI); / --- 1* TEST lTMING: WATCH P2C6 ** */
59
/* get in sync I/
/* --- set up loop paramters */mlast =-1; /* nada in buffers *plast = -1;
check_switchesO; /* updates offsets and flags */
/* convert appropriate BAT pots,massage & transmit to master card */
if(head_ctrLconneted&& !head ctrl flying){readjhead();for (i=0; i<5; i++)
curr_h_pot[i] =h_pot[i;headcamslavel0;trantpO;
else
read hLad();for (i=0; i<5; i++)
currh_pot[i] = hpot[i];
if(maslerconnected && !maser_flying)
if (slave_toggle = 1) slaverest(2); /*reset gains if powering up*/for (i = 3; i <= 7;i++)
{raw master[i-3] = (convert(icnvt2[i],icnvt[i]) & OxFFF) -1024;curr master[i-3] = adjust(rawmaster[i-3],i);pos[cardlorder[i]] = align(currmaster[i-3],i) & OxOFFF;
tran_armO; /* transmit commnand to arm*/
else
if (slavetoggle = 1)
tran_zero; /* zero out residual commands */slaverest(2);
for (i = 3; i <= 7;i++)
rawnaster[i-3] = (convert(icnvt2[i],icnvt[i]) & OxFFF) - 1024;currmaster[i-3] = adjust(rawmaster[i-3],i);
/* display command and arm position -DEA 11/86 */if(draw)
readjoint(jointcomrjoint-pos);if(setriad = 3) leanrecord();for (i=0; i<=7; i++)
if ((joint_com[i] & 0x8000) = 0) /*negative command */{/rright shift 12 bit number and sign extend */joint_com[i] = (joint_com[i] >> 4) 1 OxF000;
if(i = 3 I i = 611 i=4) /*elb, shy, ct counter intuitive*/joint_corn[i] = -jointcomli];
else
joint-comfi] =jointcom[i] >>4;if (i = 3 11 i 611 i==4) /*elb, shy, ct counter intuitive*/
jointLcom[i] = -jointcom[i];
if ((joint pos[i] & Ox8000) = 0) /*negative position*/
posm[i] = (jointpos[i] >> 4)1 OxF000;if (i = 3 11 i = 611 i=4) /*elb, shy, ct counter intuitive*/
posm[i]= -posm[i];
else
{posm[i] = joint-pos[i] >> 4;if(i = 3 11 i = 611 i=4) /*elb, shy, ct counter intuitive*/
posm[i] = -posm[il;
corn row =0;pos_row = 0;for (j=l;j <= ACTCOLS+1; j++)
if((jointcom[i] >= dvec[nnfli]]U]) && (jointcont[i] <= dvec[nnfli]][j-1]))comrow =j+l;
if((posm[i] >= dvec[nnf[i]]Uj]) && (posm[i] <= dvc[nnrf[i]][j-1]))posrow =j+l;
col = (i << 1) + 24;if(comrn_row != old_comrrow[i])
{/*cover up old command position */scr_rowcol(old_comrow[i],col); scrco(179);oldcorn_row[i] = comrow;
60
if ((posrow & OxlF) !=(old_pos row[i] & OxlF),col){/* cover up old arm position I/
scrrowcol(old_posrow[i],col); scr_co(179);old_posrow[i] = pos_row;
if (com_row = posjow){/* command and position coincide */scr_rowcol(com_row,col); scr_co(219);}
else{/* show new cormmand and arm positions I/scrrowcol(cornow,col); scrco(233);scrrowcol(posrow,col); scr_co(4);
/* --- convert appropriate PUMA pots,massage & ransmit to PUMA controller */
thrraw[O] = -(convert(7,O) - 1024 + stickoffi4])joy_mult[0]; /*X*/tbr_raw[l] =-(convert(8,0) - 1024 + stickoff[5])*joy_mult[l]; /*Y*/thrraw[2] = -(convert(6,0) - 1024 + stickofl3])*joy_mult[2]; /fZ*/
if(masterflying)
if(mastercormncted)
wraraw = (convert(2,0) - 1024 - wra_off);wrb_raw = (convert(l,O) - 1024 - wrb_off);elb_raw = (convert(3,0) - 1024 - elb_off);delta_a = wra_raw;deltab = wrbraw;deltac = delta-a - delta_b;thrraw[3] = -(lb_raw * pmult);thrraw[4] = (deltaa -(delta_c * 0.5)) * rmult;thrraw[5] = (delta_c* 0.5) ymult;
else
thrraw[3] = 0;thr-raw[4] = 0;tbhr_raw[5] = 0;
else if(head_ctrLflying)
if (head_ctrlconnectd)
read_hbead();headpumaslavelO;tbrraw[3] = ppitch;thr_raw[4] =-proll;tbrraw[S] = -pyaw;
else
thrraw[3] = 0;thrraw[4] = 0;thbrraw[5] = 0;
else
thr_raw[3] = -(caovert(0,9) - 1024 + stickoffl2])*joy_mult[3]; /*P*/thr_raw[4] = -(convert(0,10) - 1024 + stickoffll])*joy_mult[4];/*R*/tbrmrw[5] = (convert(0,8) -1024 + stickoff0])*joy_mult[5];/*Y*/
for (i=O; i<6; i++)
if (thr_raw[i] > 1024)thrraw[i] = 1024;
else if (thrraw[i] < -1024)thrraw[i =-1024;
if(boostflag)
calc_boost(iointcomjoi ntpos,thr_boost);for (i = 0; i <= 5; i++)
thrraw[i] += thrboost[i];
imtruthrrawtrtrimthrrawthr);for(i =0; i <= 5; i++)
temp = tbrtrim[i];temp = (temp > 127) ? (127): (temp); /* limit I/temp = (temp < -127) ? (-127): (tnmp);pdat[i] = (temp + 128);
61
if(pdat[i] = OxFF)pdat[i] = OxFE;
/* DISPLAY THRUST LEVELS */if(draw)
for (i = O;i <= 5; i++)
row = 17 -(pdat[i] >> 4);if (row != throld_rowi])
col =(i<< 1) + 1;scrrowcol(row,col);scr_co(219);scr_rowcol(throld_row[il,col);scr_co(179);throldrow[i] = row;
}
if(puma_on)tran_pura(pda45);
else{for (i=O; i<=5; i++)
pdat[i] = 128;tran_purna(pdat,5);
if(comnm_disp)comm_display();
outport(P2X,C6O); /* -- ** TEST TIMING: WATCH P2C6 ** */temnpc = scr_csts();if (tempc = 0)
synchronize; /* avoid sync loss from printing */else if (tcmpc = 9)
break; /* shutdown on a tab*/else
keyboard_cornmand(tmpc); /* process */syncbronize();
if(dataflag && keep[l])logint(cnt,counter);
if(data flag && keep[2])logint_a(thO,thr_raw);
if (dataflag && keep[3])logint_a(thl ,thr trim);
if(dataflag && kecp[4])logint_a(rawmnrawmaster);
if(dataflag && keep[5])logint_a(comnjointco );
if(dataflag && keep[6])logint_a(posjoint_pos);
if(dataflag && koep[8])
arm_duty[O] = pck(OxC,OxE880);annrmuty[l] =peek(OxD,OxE880);armduty[2] = pek(OxCOxE900);annrmduty[3] = peek(OxD,OxE900);armduty[4] = pck(OxC,OxE980);loginta(adty,arnnduty);
if(data flag && kecp[7])
loopz80 = peek(0xlO,OxE900)(peexk(Oxll,OxE900) << 8);logint(zcntloopz80);
scrrowcol(10,0);printf"('%LOST SYNCHRONIZATION\n"); /* go to shutdown */
/---------------------------------------/* shutdownbat --** *lshutdown_bat()
int i;
outport(P2C.7); / DEACTIVATE POWER RELAY and claws */
outport(POX,C6Hl); /* reset JCS */outport(P2X,C7HI); /* reset propulsion controller */for (i = 0; i < 20; i++); /* pulse width /outport(POX,C6LO);outport(P2X,C7LO);scr_setmode(2);}
62
/* ------------------------------------- - ------/* This function checks all of the switches and toggles theproper logic flags and updates offsets. - HV */
int old_master[5], oldoffset[5];int old_hpot[5], oldheadoff[5];int foldheadoff[5], fold_h_pot[5];char triadfn[10][15];
check_switches()
extem char data_flag, boostflag;extem char leftclaw_state, master_connected;extem char head_controller, puma_on, draw, right_claw;extem char head ctrl conmted, slave_arm_on;extem char masterflying, headctrflying;extem char beam_carrier, beam_claw;extem char sparel, spare2; /*spare pnuematics*/extem int align_offset[8];extem int curr_naster[5],curr_h_pot[5];extem int jointpos[8];exterm int old_master[5], oldoffset[5];extem int foldmaster[5], fold_offset[5];exter int wra_off, wrb_off, elb_off;extem int hpot[5], headofi[5], pheadoff[5];extem int old_headoflf5], old_bhpot[5];extem int set_triad;extern char triadf n[0][15]; /*list of file naxes for triad*/int i,dummy;extem char cswitch[8];extem int fold headoff[5],foldh_pot[5];extem int tri_for, tri_rev; /* for successive triad use */read_switches(; /* --- check ICS switches */
if (cswitch[0]) /-RED-*/
shutdownbat0;exit(2);
if (cswitch[1])/* start/stop recording data */
if(settriad=0)
dataflag = !dataflag;co(7);sceen2();
else if(setjriad=l)
co(7);poinLtopoint(;
else if(settriad>=2)
co(7);learnO;
if(cswitch[9]) /*-BLE-*/{ /* thruster toggle *pumaon = !puma_on;co(7);scren2();
/*--------------------------Removed for triad switching-------- *//I if(master flying)
if(cswitch[7]) * TURN OFF *
masterflying = FALSE;screen2();co();if (master_connected)
if(slave_armnn){slaverest(l); realign master arm with slave arm *slave_toggle =0; * keep slaverest from reloading gains*resetpidO;
elsefor (i=0; i<5; i++)
align_offset[i+3] = oldoffset[i] + oldmaster[i -currmaster[i];
else *STILL ON*
else
if(cswitch[7]) * TURN ON *
63
tasterjlying = TRUE;scrn2();co(7);wraoff = covert(2,0) - 1024;wrboff = ccnvert(1,0) - 1024;elboff = convert(3,0) - 1024;if (asterconnectd)
for (i=O; i<5; i++)
old_offset(i] = alignoffet[i+3];oldnaster[iJ =curr_rnaster[i];}
else *STILL OFF
if(headctrlflying)
if(cswitch[5]) * TURN OFF *
head_ctr_flying = FALSE;if (head_ctrl_conected)
for (i=0; i<5; i++)
hcadofflil=fold_hadofflil+currh_otfi]-foldhpot[i];
else
for(i=0; id; i++){old_headoff[il = foldhadoffi];oldh-pot[i] = foldhpot[i];
co(7);scren20;
else *STILL ON*
else
if(cswitch[5]) * TURN ON *{hadctrlflying = TRUE;read had;for (i=0; i<5; i++)
p_headofftil = hpot[i];if (head_ctrl_connected)
for (i=O; i<5; i++)
foldheadoffli] = headofi];fold3hpot[i] = currhpot[i];
else
for (i=O; i<5; i++)
foldheadoff[il = oldheadoff[i];fold_hpot[i] = old_h_pot[i];
co(7);screen20;
else * STILL OFF *
/*switching for easy triad acccess DEA*/if(cswitch[2]) /*initite trajectory cgrab */
strcpy(triadfi[0],"cgrab.trd");srcpy(triadfn[1 ],"0");pointtopoint();
if(cswitch[4]) /*take arm from stow to general area of clustcr */
strcpy(triadf[0],"ctri.trd");strcpy(triadfn[],"0");point_to_pointO;}
64
if(cswitch[5]) /*index finger push does successivc forward assembly*/
if(tri_for = 1){strcpy(triadfn[O],"grabbeantrd");strcpy(triadf[ 1l],"joint.trd");strcpy(triadf2n[21,0");point_to_point();scr_rowcol(23,16); puts("Grabslv ");
if(trifr = 2)
strcpy(triadfn[O] ,"grabslv.trd");strcpy(triadfn[l],"slideslv.trd");strcpy(triadfn[2],"0");point_to_point(;scr_rowcol(23,16); puts("Stow ");
if(trifor = 3)
srcpy(triadfn[O],stow.trd");strcpy(triadfn[l],"0");pointtopoint;_to_scrrowcol(23,16); puts("Grabbeam ");
trifor = trifor + 1;if(tri_for = 4) tri_for = 1;
if(cswitch[71)
if(trirev = 1){strcpy(triadfn[O] ,"cjoint.trd");strcpy(triadfn[l],O"');point_to_point();scrrowcol(23,25); puts("Rgrabslv ");
if(trirov = 2)
strcpy(triadfn[O] ,"rgrabslv.trd");strcpy(triadfn[ 1 ] "rsldslv.trd");strcpy(triadfn[2],O");pointtopoint();scr_rowcol(23,25); puts("Rstow ");
if(trirev =3)
strcpy(triadf[O] ,"rstow.trd");strcpy(triadn[l ],"O");pointto_point();scrrowcol(23,25); puts("Cjoint ");
trirev = trirev + 1;if(trirev = 4) trLrev = 1;
if (cswitch[3]) / incrernnt next up triads*/
trifor = trifor + 1;if(trifor = 4) trifor = 1;tri_ev =tri_rev + 1;if(trirev = 4) ti rv = 1;scren2(;}
/*8_--------------------------------------if(cswitch[11]) / toggle right claw */
{rightclaw = !rightclaw;/*------for default right claw --------if (rightclaw)
outport(P2X.C2LO);else
outport(P2X,C2-I);-------replace with pnue 1-----------*/if(rightclaw)
outport(PlX,C6LO);else
outport(PlX,C6HII);co(7);screen2();
if (cswitch[8]11 cswitch[l5) /*left claw toggle(was p2cl,now using plc7)*/
leftclaw_state = !leftclawstate;if (leftclawstate)
outport(PlX, C7LO);else
outport(PlX, C7HI);co(7);screen2();}
65
if(masterconnrmcted)
if(cswitch[6]) /* DISCONNECT i/
masterconnected = FALSE;scr2;co(7);if(!maserjflying)
for (i=0; id; i++)
old_offset[i] = align_offset[i+3];old_master[i = currmaster[i];
else /* still cormected /
else
{if(cswitch[6]) / CONNECT */
master_connectcd =TRUE;screen20;co(7);if(masterflying)
wraoff= convert(2,0) - 1024;wrb_off = cnvert(l,0) - 1024;elb_off= convert(3,0) - 1024;
if(!master_flying)
if(slave_armon)
slaverest(l);J*realign master with slave*/slavetoggle = Of;*keep slaverest from reloading gains */resetpid();
if(!slavearmon)for (i=O; id; i++)
align_offset[i+3] = old_offset[i] + old_master[i] - curr master[i];
else /* still disconnected I/{
if(cswitch[10]) /*slave toggle switch*/
if (slave_armeon)slaverest(0);
elseslaverest(l);
coC7);
if (hadctrlconrzctd)
if(cswitch[13]) /* DISCONNECT */
ead_ctrlconncted = FALSE;for (i=0; id; i++)
old headoffli] = headoff[i];co(7);screen2t;
else /* STILL CONNECTED */{for (i=0; id; i++)
old_h_pot[i] c ;urhpot[i;
else
if(cswitch[13]) /* CONNECT */
head ctrl conncted =TRUE;for (i=0; id; i++)
headoftli] = old_hcadofffi]+currhpot[i]-old_h_pot[i];readhead;for (i=0; id; i++)
pheadoffti] = hpot[i];co(7);scrcn2);
else /* STILL DISCONNECTED */
}
66
if(cswitch[12) /*ogW beam carir*/
beamcmrier = lbeamar r,
outport(P2X,C3HI); /xxld bean m carr/
else
outpo(P2XC3LO); /etract beam carrir*/
co(7);scmn20;
if(cswitch[14]) /togle beam carir claw (was also cswitch[3])*/
beamclaw = !beamdaw;if(beamclaw)
outpor(P2XC4LO); dclose bam carrier claw/
elm
outpot(PXC4H ); /openbeam carrier daw*/
co(7);scmen2;}
if (cswitch[]) *spara mmatics 1Ispael = Isparol;if(apamnl)
oatporPX,C6LO);
else
outpol(X,C6HI);
co(7);
if (cswith[) *spam pmnumaics 2*
spae2 = sp-a2;if(spam2)
aotportP1X.C7LO):
eLa
outporn(PlX,C7HI);
co(7);
if(cswih[])stowO;
*/
*acuate spare pnuematics 1'
/* End of Batsoft.c */
67
.1
/* SUPPORT1.C -- BAT support routines version 6.4** by John Spofford and Tom Waschura and David E. Anderson,** M.I.T. Space Systemrns Laboratory December 4,1987** revisions include Joint step input routine */#include "PORTNUMS.H"#include "DATH"#define READ CNT 21/* -------------------- *//* FEEDBACK.C -- interacts with the BAT/joint card/master card loop *feedback()
{int not_done, selcctioni;
not_done =TRUE;while (not_done)
selection = getsel2(; * light pen soon? *switch(selection)
{case 1:case 2.case 3:case 4:
shut_card_off(selection);work_card(selection);beak;
case 0:not_done = FALSE;breal
case 9:testroutine0;bseak;
defaultbeep4(25);scr_rowcol(l,1);printf("lnvalid Selection');pause(100);
shut_card_off(l);shut_card_off(2);shut_card_off(3);shut card off(4);
beep4(n)int n;{int i;
outport(0x61,0x43);for (i=0;i<n*25;i++);outport(0x61,0x40);retur(0);
paint_menu_3()
scr_setmode(0);scrdr0o;scrrowcol(2,0);printf(" M.I.T. SSL\n");printf(" Beam Assembly Teleoperatoh\n");printf(" Hierarchical Control Evaluation\nhnu');printf(" 1. Wrist A + B\n");printf(" 2. Shoulder Pitch + Yaw\n");printf(" 3. Elbow + Left \n");printf(" 4. Camera Tilt + Pan\n");printf(" 0. EXIT\n");printf(" 9. Debugging test routine");scr_rowcol(22,0);printf(" Enter Selection ");retum(0);
a {-int query;
paint menu3();scrrowcol(22,19);printf(" ");scrrowcol(22,19);scanf("%d,&query);
retum(query);
char read_buffer[40];
work_card(card_addr)int card_addr;
68
extern char read buffer[];int i, posx, posy;
scrcursoffO;paintnenu4();scrrowcol(3,0);switch(cardaddr)
case 1: printf(" Wrist A Wrist B); break;case 2: printf(" Shoulder Pitch Yaw"); break;case 3: printfl" Elbow Left Arm"); break;case 4: printf" Camera Tilt Pan"); break;default prinrf"ERROR");
while( !(scr_cstsO = 13)) * unless CR *
rqstmstr(card_addr);read_mast(READ_CNT);
* posx = read_buffer[0] + read_buffer[l *256;posy = readbuffer[2] + read_buffer[3]*256;scrrowcol(14,10);printf("%04x %04x"); *
scr_rowcol(14,0);for (i = 0;i <READCNT;i++)
printf(" %02x",rea_buffer[i]);while( scr_csts( = 32); * stop a while *
read_mast(cnt)int cnt;
extern char readbuffer[];char i, waitc;
for(i= 0; i < cnt; i++)
for (waitc = 0;!(inport(P4B) & 1);waitc++) * JM-RDY hi *if (waitc> 250)
printf"R");break; * timnout *
read bufferlil = inport(P4A);outport(P2X, CSHI); * JM-STB high *for (waitc = 0;inport(P4B) & 1;waitc++) * JM-RDY hi *
if (waitc > 200){printf"r");break; * tirneout *
outport(P2X, CSLO); * JM-STB low *
paint_nenu_40
scrcr0;scrrowcol(0,0);printfi"CARD:\n');printf(" Channl X Y \n");printf(" \n");printf(" n");printf(" Gain\n");printf(" Ref Posn");printf("Joint Pos\n");
shut_cardoff(card)int card;
unsigned jcseg;
jcseg = SEGOFF + Ox80 * card;poke('S',COMM_FLAG,j_seg);while (peek(JCSTATUSjcsog) != W')
scrcsts(); * no hangup *poke('G.,COMM_FLAGjc_seg);while (peek(JC_STATUSjc_seg) != 'C')
scrcsts(); * no hangup *
char tenp_ch;*-----------------*
testroutine(
char strobe, ready_var, jnd_data, buffer[150], i;extem char ternmpch;
69
scrcldr0;scr rowcol(0,0);printf("l= STB hi, 2= STB lo, 3= log, 4= conftnXa");printf"RDY STB DATAn');while(l)
{tempch = scr_csts();switch (temp_ch)
{case '1': strobe = 1;
outport(P2X,CSHI); * jm-stb hi *blealq
case '2: strobe = 0;outport(P2X,C5LO); * jm-stb lo *break;
case '3': * read 150 bytes *outport(P2X,C5LO);for (i = O;i < 150;i++)
buffer[i] = readjm(; * get data *scr-rowcol(5,0);for (i = O;i < 150;i++)
printf(" %02x",buffer[i]);while(!scrcstsO);
case '4': * cont. read *outport(P2X,C5LO);while(!scrcstsO)
#asm; ASM88 *
Modified READJM.C for speed
CSEG
mov dx,311h ,port 4Bin al,dx ;get datamov ahO ;char valueand ax,lcmp ax,0Ojnz a_12jmp all
a_12:mov dx,310h ;port4Ain al,dx ;get datamov temp_ch-al ;retum in tempchmov ax,l 1 ;C5 HImov dx,30Bh ;Port 2Xout dx,al ;put it out..
a_3:mov dx,311h ;Port 4Bin al,dx ;get daamov ah40 ;char valueand ax,lcmp ax,Ojz a14jmp aJ_3
a14:mov ax,l0 ;CSLOmov dx,30Bh ;Port 2Xout dx,al ;put it out..
case 13: retum;default break;
scr_rowcol(3,0);readyvar = (inport(P4B) & 1); * JM-RDY *jmd_data = inport(P4A); * JMData printf("%2x %2x %02x",ready var,strobejmd_data);
*-*------------
* rcadjrmc -- reads joint control system master card *a produces assembly code *readjm(
char tempc;
while(!(inport(P4B) & 1)); * wait for rdy *tempc = inport(P4A); * get data *outport(P2X,CSHI); jm-stb hi *while(inport(P4B) & 1); * wait for rdy low *outport(P2X,CSLO); * jm-stb lo *retum(tempc);
-------------------- */#defime CAMERAADDR 4#define WRIST ADDR 1#define SHOULDER ADDR 2
70
#define LEF_ARM_ADDR 3#define CAMERATILT 0#define CAMERAPAN 1#define WRIST_A 0#define WRIST B 1#define SHOULDERPITCH 0#defm SHOULDERYAW 1#define LEFIARM 1#define ELBOW 0/*1--------------------*char databuffer[411];static int rows[] = { 5, 6, 7, 8, 9 );static int pot[] = { 0, 1, 2, 3, 4 };char commandbuffer[41] = { OxE0, OxCO, 0xA0, 0x80, 0x01,
OxFO, OxDO, OxB0, 0x90, 0x03,0xEO, OxCO, 0xA0, 0x80, 0x01,OxFO, OxD0, OxB0, 0x90, 0x03,OxEO, OxCO, OxAO, 0x80, 0x01,0xF0, OxDO, OxB, 0x90, 0x03,OxE0, OxCO, OxAO, 0x80, 0x01,OxFO, OxDO, OXB, 0x90, 00 };
char addrbuffer[41] = ({ 4,4, 4, 4, 44,4,4,4,4,
1,1,1,1,1,1, 1, 1, 1, 1,2,2.2, 2,2,2,2,2.2,2,3,3,3,3,3,3, 3, 3,3,3,0);
char *algorithn[6] = { "P-typoe 0", "PID-typeY', "SVC-type\0","* OL. *NV","ERROR \0", "ERROR \0");
char cur_command_buffer[41], cur_databuffer[41];/* WRA WRB SHP SHY ELB PMP CT CP*/float scale[9] = 0.0, 50.272, 50.272, 67.28, 50.272, 63.104, 50.272, 50.272, 50.272};int Gain[9], alpha[9], beta[9], multl[9], mult2[9], alg[9], pos[9], mult3[9];/---------------------setupjoints(t
intnot_done,i;char selection;char fame[15];notdone =TRUE;while (not_done)
selection = getselectionO; /* light pen? */switch(selection)
case '1':tunejoint(CAMERA_ ADDR, CAMERA TILT,7);bieak
case '2':tuncjoint(CAMERA_ADDR, CAMERA_PAN,8);beak;
case '3':tunejoint(WRISTADDR, WRISTA, 1);break;
case '4':tunejoint(WRIST_ADDR, WRISTB, 2);breakl
case '5':tunejoint(SHOULDER_ADDR, SHOULDER_PITCH, 3);break;
case '6':tunjoint(SHOULDER_ADDR, SHOULDER_YAW, 4);biak;
case '7':tunejoin(LEFT_ARM_ADDR, ELBOW, 5);break;
case '8':tuncjoint(LEFTARM_ADDR, LEFT_ARM, 6);
case '9':printf" Load filename [.BDT]: ");scanf("%s\n",fiamn);strcat(fname,".BDT");load_from file(fname);scrrowcol(21,0);prinft" Data Transmitted to BAT");pause(100);bzak
case '0':notdone = FALSE;
defaultbeep(25);scrrowcol(l,1);printft"Invalid Selcction, Dude! Try a number.");pause(200);
printf(" Write filenamc [.BDT]: ");scanf("%s\n",fname);
71
strcat(fiame,".BDT");writ_out_data(fname);
/* -------------------.beep(n)
intn;
int i;
outport(Ox61,0x43);for (i=O;in*100;i++);outport(Ox61,0x40);retra(O);
/* --------------------/paint_mrnenu_l0
scrsetmode(O);scr dr();scr_rowcol(2,0);printf(" M.I.T. SSL\n");printf(" Beam Assembly Teleoperatornn");printf(" Joint Algorithm Tuning\n\n\n");printf(" 1. Camera Tiltn");prinff(" 2. Camera Pan\n");printf(" 3. Wrist An");printf(" 4. Wrist Bn");printf(" 5. Shoulder Pitch'n");printf(" 6. Shoulder Yaw'n");printf(" 7. Elbow \n");printf(" 8. Cooling Pump\n");printf(" 9. LOAD From File'n");printf(" 0. END JOINT TUNING");scrrowcol(22,0);print" Enter Selection: ");retum(O);
/*---------- --------getselectionO
char quer,
paintmenul();scr_rowcol(22,19);prirntf(" ");scr_rowcol(22,19);scanf("%c",&query);rtum(query);
/*______________...*/tunejoint(cardaddr, xory, joint)int cardaddr, xory, joint;
extem float scale[9];extem int Gain[9], alpha[9], beta[9], multl[9], mult2[9], alg[9], pos[9], mult3[9];float gainf,alphaf, betaf, multlf, rmult2f;float K, A, B, C;int i, done, transmit;int tem,char query, direct, inputt, dh, dl, conversion;int jseg, joff;inputt = FALSE;transmit = FALSE;conversion = FALSE;jsegm = OxE800 + card_addrOx80;joff = x_ory * 2;paintmenu_2);scr_rowcol(0,19);switch(joint)
case 1: printf("Wrist A");bkral
case 2: printf("Wrist B");break;
case 3: printf("Shoulder Pitch");break;
case 4: printf("Shoulder Yaw");break;
case 5: prinf("Elbow");break;
case 6: printf("Cooling Pump");break;
case 7: printf("Camera Tilt");break;
case 8: printf("Camera Pan");break;
default: printf("ERROR");
poke('l,TOZ80,jsegm);dl = peek((joff+0x84)jsegm); dh = peek(joff+0x85)jsegm);temp = dl + (dh <<8);scrrowcol(5,21);
72
printf("%4x ",ternmp);dl = peek((joff+Ox88)jsegmn);temp = dl + (dh<< 8);scrrowcol(6,21);printf("%4x ",ternp);dl = pek((joff+Ox8C)jsegm);temp = dl + (dh << 8);scrrowcol(7,21);printf("%4x ",temp);dl = peek(joff+ Ox80jsegm);temp = (dl >> 4) + (dh << 4);scrrowcol(8,21);printf("%d ",(signext(temp)));temp = peek(((joff/2)+0x90)jsegm);scrrowcol(9,21);printf("%s",algorithm[temp]);dl = peek(joff+0x9Cjsegm);temp = dl + (dh << 8);scr_rowcol(10,21);printf("%4x ",temp);dl = peek(joff+OxAOjsegm);ternmp = dl + (dh << 8);scr_rowcol(11,21);printT"%4x ",temp);dl = peek(joff+OxA4jsegm);temp = dl + (dh << 8);scrrowcol(12,21);printf("%4x ,ternmp);poke('O',TOZ80 jsegm);scrrowcol(13,20);printf("Transmit OFF');scrrowcol(13,00);printf"type I to input");scrrowcol(14,20);printf("Conversions C: OFF");domne = FALSE;scr_rowcol(14,0);printf"Input Varables");scr_rowcol(15,0);printf(" [000->FFFI: ");while (done = FALSE)
{if(inputt)
iif(conversin)
else
dh = peek(joff+Ox89)jscgm);
dh = peek((joff+Ox8D)jsegm);
dh = peek((joff+0x81)jsegm);
dh = peek(joff+0x9D)jscgm);
dh = peek((joff+OxAl)jsegm);
dh = peek((joff+0xA5)jsegm);
scr rowcol(17,20);printf("Set K: ");scanf("%f",&K);scrrowcol(18,20);print("Set A: ");scanf( %f,&A);scrrowcol(19,20);printf("St B: ");scanf("%f',&B);scr_rowcol(20,20);printf("Set C: ");scanf("%f',&C);scrrowcol(21 ,20);printf("Position: ");scanf("%d",&pos[joint]);scr_rowcol(22,20);printf("Int Sat(hex): ");scanf("%4x",&mult2[joint]);scrrowcol(23,20);printf("Int Mult(hx): ");scanf("9%4x",&mult3[joint]);multlf= C*65536.0;if (multlf >= 65536.0) printf("multl overflow");multl oint] = (int) multlf,gainf=scaleUjoint]*K*(B + 1.0);if(gainf >= 65536.0) printf("gain overflow");Gainljoint] = (int) gainf;alphaf = scaleUoint]*K*(A - C - 1.0 -2.0 * B);if(alphaf <= -65536.0) printf("alpha overflow");alphaljoint] = -((int) alphaf);betaf = scale[joint]*K*(B -A*C + C);if (betaf >= 65536.0) printf("beta overflow");beta[ioint] =(int) betaf;
scr_rowcol(16,0);printf("Set G: ");scanf("%4x",& Ga int jo ]);scrrowcol(17,0);printf("Set Alpha: ");scanf("%94x",&alpha[joint);scrrowcol(18,0);printf("Set Beta: ");scanf("%4x,&bcta[joint]);scrrowcol(19,0);
73
printf("Position: );scanf("%d ",&pos[joint]);scrrowcol(20,0);prmh SetMultl: ");scanf("%4x",&multl[joint]);scrrowcol(21 ,0);printf("Set Mult2 ");scanf(%4x",&mult2ljoim);scrrowcol(22,0);prinff("Set Mult3: );scanf("%4x",&mult3[joint]);
scr_rowcol(5,30);printf("%4x ",Gain[jointl);scr_rowcol(6,30);printf("%4x ",alpha[joint]);scr_rowcol(7,30);printf("%4x ,betajoint]);scrrowcol(8,30);printf("%d ",p
os [joint]
);
scr rowcol(10,30);pin"%.4x ",multl[loint]);scrjowcol(11,30);printf("%4x ",ult2[joint);scrrowcol(12,30);printf("%4x ",mlt3[joint]);scr rowcol(9,30);printf(%s",algorithm[alg[joint]]);inputt = FALSE;
/* put raten onto screen *1while(peek(FROMZ80jsegm) = 'U);poke('R',FROMZ80jsegm);temp = peek(OxO4+joffjsegm) l(peek(OxO5+joffjscgm)<<8);scrowcol(13,35);printf("%4x",temp);pokc('O'.FROMZ80jsegm);query = scrCsts(;switch(query)
case 0: brea;case T':case Y:
scr rowcol(13,30);if(transmit)
transmit = FALSE;print("OFFP");
else
trasmit =TRUE;printf("ON ");
bskcase '0':case '1:case '2:case '3':
algojoint] = query - '0';scrrowcol(9,30);printf("%s",algorithm[alg[joint]]);brealk;
case 'i':case T
inputt = TRUE;if(conversion)
scr rowcol(17,20);printf( ");scrrowcol(18,20);prinrf(" );scrrowcol(19,20);printf(" );scrrowcol(20,20);printf(" ");scr-rowcol(21 ,20);printf(" ");scrrowcol(22,20);prinlf(" ");scrrowcol(23,20);printf(" ");
else
scrrowcol(16,0);prinff(" \a");printf(" ");
printf(" n");printf(" n");prinff(" aN);
74
printf(" . );
breakcase 'c':case 'C:
scr_rowcol(14,37);if(conversion)
conversion = FALSE;printf("OFF");scr_rowcol(15,20);printf(" );scr_rowcol(16,20);printrf(" ");scrrowcol(14,0);printf("Input Varables");scr_rowcol(15,0);printf(" 000->FFF]: );
else{conversion = TRUE;print("ON ");scrrowcol(15,20);printf"enter PID parameters");scrrowcol(16,20);printf(" [00.000 -99.999] ");scr_rowcol(14,0);printf(" ");scrrowcol(1S,0);printf(" ");}
brea*;case 13: done =TRUE;
beak;default becp(25);
scr_rowcol(23,0);printf("Invalid Key ");pause(200);scr_rowcol(23,0);printf(" ");
if(transmit)
randirect(jsegm, joff, joint);
/*--------------------*/paint_menu_2()
scrdrO;scrrowcol(0,0);printf("Joint Tuning for.n\n");printf(" Current Newn");printf(" Param eter Value Value\n\");printf(" GainS");print(" Alphaa");printf(" Beta\n");printf(" Position\n");printf" Algorithmnn");printf(" Multla");printf(" MultZan");printf(" Mult3");
/* --------------------*/loadfom_ file(fame)char finare[15];
int ij,fn, seg;extem int Gain[9], alpha[9], beta[9], pos[9], alg[91], multl[9], mult2[9], mult3[9];
if((fn = open(fname,0))= -1)
scr rowcol(22,0);beep(25);printf("ERROR in loading");pause(250);
else
for(i=l; i<=8; i++)
Gain[i] =getw(fn);alpha[i = getw(fn);beta[i] = getw(fn);pos[i] = getw(fn);alg[i] = getw(fn);multl[i] = getw(fn);mult2[i] =getw(fn);mult3[i] = getw(fn);}
75
dlos(fn);seg =OxE800;for(i = 1;i<=7;i=i+2)
scg = seg+0x80;while(peek(TOZs0,seg) = 'R');poke(U',TOZ80,seg);/* put parameters to dual port ram jcl*/poke(Gain[i] & OxFF,Ox84,seg); poke(Gain[i] >>8,0x85,seg);poke(Gain[i+l] & OxFF,Ox86,seg); poke(Gain[i+l] >>8,0x87,seg);poke(alpha[i]& OxFFP,Ox88,seg); poke(alpha[i]>>8,0x89seg);poke(alpha[i+1]& OxFF,Ox8A,seg); poke(alpha[i+l]>>8,0x8B,seg);poke(beta[il & OxFF,Ox8C,seg); poke(beta[i] >>8,0x8D.seg);poke(beta[i+l] & OxFF,Ox8E,seg); poke(beta[i+] >>8,0x8F,seg);/* no position input for anything but pump i/if(i=5)
poke((pos[i+ll << 4) & OxFF,Ox82,seg);poke((pos[i+l] >> 4) & OxFF, 0x83.seg);
poke(alg[i] & OxFFOx90,seg);poke(alg[i+l] & OxFF,0x91,.seg);poke(multl[i] &OxFF,Ox9C,seg); poke(multl[i] >>8, Ox9D,seg);poke(multl[i+l] & OxFF,Ox9E,seg);pok(multl[i+l] >>8, Ox9F,seg);poke(mult2[i] & OxFF.POxAO.seg); poke(mult2[il >>8, OxAl.,seg);poke(mult2[i+l] & OxFF,OxA2,seg);poke(mult2[i+l] >>8, OxA3,seg);poke(mult3[i] & OxFF,OxA4,seg); poke(mult3[i] >>8, OxA5,seg);poke(mult3[i+l] & OxFF.OxA6,seg);poke(mult3[i+1] >>8, OxA7,seg);pokc('N',TOZ80,seg);
/* .--------------------pause(n)
int n;{inti j;for (i=O;i<n*100;i++)
j=j+l;
/*--------------------*writeoutdata(fname)char fnam[15];
int fn, i,j;extem int Gain[9], alpha[9], bcta[9], pos[9], alg[9], multl[9], mult2[9], mult3[9];
if((fn = creat(frame)) = -1)
scrrowcol(0,0);beep(25);printf(lUnable to Write File");pause(25
0);
else
for(i=l;i<c-=8;i++)
putw(Gain[il,fn);putw(alpha[i],fn);putw(beta[il,fn);putw(pos[i],fn);putw(alg[i],fn);putw(multl [i],fn);putw(mult2[i],fn);putw(mult3[i],fn);
close(fn);
/*n tse----------------------------t ----------tran-irect(osegmjoffjoint)intjsegm,joffjoint;
{extrm int Gain[9], alpha[91, beta[9], pos[91, multi [9], mult2[91, alg[9];while((peek(TOZ80jsegm))='R);poke('U',TOZ80jsegm);poke((multl[joint] & OxFF)joff+Ox9Cjsegm);poke(((multl joint] >> 8) & OxFF)joff+Ox9Djsegrn);poke((mult2ljoint] & OxFF)joff+OxAOjsegm);poke(((mult2joint] >> 8) & OxFF)joff+OxAljsegm);poke((mult3[joint] & OxFF)joff+OxA4,jsegn);poke(((mult3joint] > 8) & OxFF)joff+OxA5jsegm);poke((alpha[joint] & OxFF),joff+Ox88)jsegm);poke(((alphaUjoint] >> 8) & OxFF),(joff+Ox89)jsegm);poke((betafjoint] & OxFF),(off+Ox8C)jsegm);poke(((betaUjoint] > 8) & OxFF),(joff+Ox8D)jsegmn);poke(algjoint],((joff/2)+0x90)jsegm);poke((Gainljoint] & OxFF),Ooff+Ox84)jscgm);poke(((Gainfjoint] > 8) & OxFF),(joff+Ox85)jsegm);poke(((posjoint] <<4) & OxFF),(joff+Ox80)jsegm);poke(((posljoint] >> 4) & OxFF),(joff+Ox8l)jsegm);
76
poke ('N,TOZ8Ojsegm);
/*------- ----- --------------------- - --------------- /tran_zero() /*zero out all commands in the arm joint*//* revision 8/4/87 -- for the purposes ofjlt arm control algorithm,this must include a zeroing of the upper byte of mult2 to reset theintegrator summation */
/* zero out any residual commands jcl*/while(peek(FROMZ80,0xE880) = '); poke('R',FROMZ80,0xE880);while(peek(TOZ80,xE880) = R'); poke('U,TOZ80,xE880);pokc(peek(OxOO,OxE880),0x80,0xE880); poke(peek(OxOl,OxE880),0x81,OxE880);poke(peck(x2,xE880),0x82,0xE80); poke(pek(0x03,xE880),0x83.,OxE880);poke(O,OxAl,OxE880); poke(O,OxA3,OxE880);poke('N',TOZ80,0xE880);poke('O',FROMZ80,0xE880);/* zero out any residual commands jc2*/while(peek(FROMZ80.0xE900) -= J); poke('R',FROMZ80,0xE900);while(peek(TOZ80,0xE900) = R'); pok('U',TOZ80,xE900);poke(peek(OxOO,OxE9E 90 0); pok(peck(OxOl,OxE900),0x81,OxE900);poke(peek(x0O2,OxE900),Ox82,0xE900); poke(peek(0x03,OxE900),0x83,OxE900);poke(O,OxAl,OxE900); poke(0,OxA3,OxE900);poke('N,TOZ80,0xE900);poke('O',FROMZ80,0xE900);/* zero out any residual commands jc3*/while(peek(FROMZ80,0xE980) = UY); pokc('R'.FROMZ80,0xE980);while(peek(TOZ80,0xE980) ='R'); poke(U,TOZ80, 0xE980);poke(peek(OxOO,OxE980),0x80,xE980); poke(peek(OxOl,OxE980),0x81.OxE980);poke(O,OxAl.OxE980);poke('N,TOZ80,xE980);poke('O',FROMZ80,0xE980);
P------------ --------- -------------------
tranarm/) transmits to commands to the arm *//* due to pots, pos[i] is 12bits left justified but we reed to *//* poke 12 bits leftjustified into 16 bits*/
extemn int pos[9];while(peek(TOZ80,xE880) = R'); poke('U',TOZ80.xE880);poke((pos[l] << 4) & OxFF,0Ox80,xE880); poke((pos[ll] >>4) & OxFF, 0x81,xE880);poke((pos[2] << 4) & OxFP,0x82,OxE880); poke((pos[2] >>4) & OxFF, 0x83,OxE880);poke('N',TOZ80,0xE880);while(peek(TOZ80,xE900) = 'R'); poke('U',TOZ80,0xE900);poke((pos[31 << 4) & OxFFP,0x80,OxE900); poke((pos[3] >>4) & OxFF, x81,OxE900);poke((pos[4] << 4) & OxFF,0x82,OxE900); poke((pos[4] >>4) & OxFF, 0x83,OxE900);pokc('N,TOZ80,OxE900);while(peek(TOZ80,0xE980) = R'); poke('tJ.TOZ80.xE980)poke((pos[5] << 4) & OxFF,0x80,OxE980); pokc((pos[5] >>4) & OxFF, Ox81,xE980);poke('N,TOZ80,0xE980);
/*---- .. ------------------- ----------intposl[8];tran_ann() /* transmits to commands to the arm in XXXO form*/
/* pos[i] isl2 bits left justified into 16 bits */
extent intposl[8];while(pek(TOZ80,xE880) == 'R'); poke('U',TOZ80,xE880);poke(posl[O] & OxFP,0x80,xE880); pokc((posl[O] >>8) & OxFF, 0x81,OxE880);poke(posl[l] & OxFF,0x82,OxE880); poke((posl[l] >>8) & OxFF, 0x83,0xE880);poke('N,TOZ80,xE880);while(peek(TOZ80,0xE900) == 'RD; poke(lJ',TOZ80,0xE900);poke(posl[2] & OxFF,0x80,OxE900); poke((posl[2] >>8) & OxFF, 0x81,xE900); poke(posl[3] & OxFF,Ox82,0xE900); poke((posl[3] >>8) & OxFF, 0x83,OxE900);poke('N',TOZ80,0xE900);while(peek(TOZ80,xE980) == 'R'); poke(U',TOZ80,OxE980);poke(posl[4] & OxFP,0x80,xE980); poke((posl[4] >>8) & OxFF, 0x81,O0xE980); poke(''N,TOZ80,0xE980);
---------------------------------------------- ----
tran_tp() /* transmits to commands to the tilt and pan */
extem pos[9];while(peek(TOZ80,OxEAOO) = R'); poke('U',TOZ80,0xEAOO);poke((pos[7] << 4) & OxFF,0x80,xEAOO); poke((pos[7] >>4) & OxFF, 0x81,OxEAOO); poke((pos[8] <<4) & OxFF,0x82,OxEAOO);poke((pos[8] >>4) & OxFP, 0x83,OxEAOO);poke('N',TOZ80,0xEAOO);
signext(i)inti;{if((i & 0x800) != 0)
i=i I OxFOOO;
retum(i);
/* ..........--------------- - ...--------- ------------ /comm_display() /* this just displays what duty cyde is being sent -DEA */
int trmp,scr rowcol(16,24);printf("%2x",peek(OxC,OxE880));scr_rowcol(15.26);
77
printf("%2x",peek(xD,OxE880));scr_rowcol(16,28);printf("%2x",peek(OxC,OxE900));scrrowcol(l5,30);printf("%2x",peck(0xD,OxE900));scr_rowcol(16,32);printf("%2x",peek(OxC,OxE980));scr_rowcol(15,36);printl("%2x",peek(OxC,OxEA0O));scr_rowcol(16,38);print("%2x",peek(OxD,OxEAOO));
/*.------------...--------.----------..-----------
/* Joint Step is meant to allow the operator to apply a step command to a jointand record the results via the daters routines. I will use a more directmethod of addressing the joint cards than tranjcs_dpr. The dual port ram thatacts as the two way closet between the pc and the joint card z80's can beaccessed simply by peeking and poking the variables by which they communicate.No complex pointer/buffer system is required.
David E. Anderson, March 8,1987 *DATATAG onejnt[TAGSIZE] = "GlAone joint po" };
DATATAG oncom[TAGSIZE] = {"HIAone joint comn};DATATAG cntt[TAGSIE] = {"IIAstep counter"};joinstep(
extemrn char dataflag;exten float scale[9];extem int Gain[9], alpha[9], beta[9], pos[9], multli [9], mult2[9], alg[9];int joint;char testing, looking, transmit, dl, dh;char written, direct, inputt;int jsegm, counter, temp, jnt, algjc, joff;int posjc, templ;float tempf, multlf, mult2f, gainf, alphaf, betaf;float K, A, B, C;transmit = FALSE;testing = TRUE;looking = TRUE;direct = FALSE;inputt = FALSE;while(testing)
while(looking)( * paint a joint selection menu *paintmenul0;scrrowcol(5,0);printf(" PID Joint Step Algorithm ");scr_rowcol(15,7);printf("G. Daters Initialization\n");printf(" T. Calibrate Control Loop Time "n");
printf(" 0. End Joint Step ");scr_rowcol(22,19);scanf("%c",&jnt);painmenu0; paint the runtime menu *scr_rowcol(0,0);printf("Stcp Input For: ");looking = FALSE;joff= 0;jnt = toupper(jnt);switch(int)
{ * see which joint was selected *case '1':
printf("Camera Tilt");jsegm = OxEA00O;joint = 7;break
case '2:printf("Camera Pan");joff= 2;joint = 8;jsegm = OxEAOO;break
case '3':printf("Wrist A");joint = 1;jsegm = 0xE880;break
case '4':printf("Wrist B");joff= 2;joint = 2;jscgm = OxE880;beak
case '5':printf("Shoulder Pitch");jsegm = OxE900;joint = 3;break
case ':
printf("Shouldr Yaw");joff= 2;joint = 4;
78
jsegm = OxE900;break
case '7':prinff(Elbow");jsegm = OxE980;joint = 5;break
case 'G':setdata0;joint = 6looking = TRUE;break
case T:timeJoop0;looking = TRUE;break
case '0':testing = FALSE;break
default:looking = TRUE;boep(25);scr_rowcol(1,1);printf(" Invalid Selection. Try a number.");pause(200);
if(!looking){ paint the rest of the runtirme nenu *scrrowcol(10,12);printf("Runtim: Position:);scr_rowcol(ll,0);print" Direct inp: An");printf(" Start Step: Tln");printf(" Zero command: Zsn");printf(" Take input n");printf(" Change Joints: J\n");printf(" TakeData D");printf(" Exit: X")if(data_flag)
scr_rowcol(16,19);printf("SELECrED");
}
temp = sccstsO;tmp = toupper(tenp);switch(temp)
{ * check for commands *case 0:
breakcase 'X: * return to main loop *
testing = FALSE;break
case ': * quick power down ** zero out any residual commands jc3*while(peek(FROMZ8Ojsegm) = 'U'); poke(R',FROMZ8Ojsegm);whilc(peek(TOZ80jsegm) = 'R); poke('U',TOZ80jsegm);poke(peck(OxOl+joffjsegm) joff+Ox80jsegm); poke(peek(OxOl+joffjsegm),0x81+joffj segm);poke('N',TOZ80jsegm);poke('O',FROMZ8Ojsegm);break;
ease 'A':if (direct)
direct = FALSE;scr rowcol(11,19);printf(" ");
else
direct = TRUE;inputt = TRUE;scrjowcol(11,19);printff("ON);
breakcase ':
if(direct)
inputt -- TRUE;scr_rowcol(18,0);printf" \n");printf(" W);printf(" \n");printf(" \n);
breakcase 'D':* take data during run *
data_flag = !dataflag;scrrowcol(16,19);if(dataflag)
79
printf("SELECrED");else
printf( ");beaq
caseT : * go back to joint select *looking = TRUE;break
case '0': * set algorithm *alg[joint] = O;
case '1':
case '2:
case '3':
alg[joint] = 1;bra;lc
alg[joint] =2;breal
alg[joint] =3;breal;
case T: * set flag to start a run *trasmit = TRUE;break
defaultscr_rowcol(23,0);printf("Invalid Key");pause(200);scrrowcol(23,0);printAf(" );break
read the present dpr variables. Note that all but the algorithm are *12 bit numbers right justified in 16 bits *
dl = peek(off+0x84)jsegm);temp = dl + (dh << 8);scr_rowcol(5,21);printf("%4x ",temp);dl = peek((off+Ox88)jsegm);temp = dl + (dh << 8);scr_rowcol(6,21);printi"%4x ",temp);dl = peek((joff+0x8C)jsegm);temp = dl + (dh << 8);scrrowcol(7,21);printf"%4x ,terp);dl = peek(joffjsegm);posjc = (dl>>4) + (dh << 4);scr_rowcol(8,21);printf("%d ",(signext(p
osjc)));
temp = pek(((joff/2)+0x90)jsegm);scr rowcol(9,21);printf('%s",algorithm[temp);
* Now read pots to set input variables for run *if(direct)
if(inputt)
dh = peek((joff+0x85)jsegm);
dh = peek((joff+0x89)jsegm);
dh = peock((joff+Ox8D)jsegm);
dh = peek((joff+l)jsegm);
scr_rowcol(5,30); printf(" );scr_rowcol(6,30); printf(" ");scr_rowcol(7,30); printf(" ");scr rowcol(18,0);printf("Set K: ");scanf("%f',&K);scrrowcol(19,0);printf("sct A: );scanf("%f",&A);scr_rowcol(20,0);printf("Set B: ");scanf("%f.,&B);scr_rowcol(21 ,0);printf("SetC: ");scanf("%f",&C);scr_rowcol(22,0);printf("Position: ");scanf("%d",&pos[joint]);multlf = C*(float) 65536;multl[joint] = (int) nrultlf;mult2f = (C(float) 1) * (float) 65536;mult2joint] = (int) mult2f;gainf = scale[joint]*K*(B + (float) 1);Gain[joint] = (int) gainf;alphaf = scale[joint]*K(A + C -(float) 1 -(float) 2 * B);alpha[joint] = -((int) alphaf);betaf= scale[jointl*K(B + A*C -C);beta[joint] = (int) betaf;scrrowcol(5,30);printf("9%3x",Gain[joint);scr_rowcol(6,30);prir"%3x",alpha[joint]);scr_rowcol(7,30);printf("%3x",beta[joint]);scr_rowcol(8,30);printf("%d ,pos[jointl);
80
inputt =FALSE;
else
posUojont] = convert(0,3) - 1024;*command** and put them on the screen *
scrrowcol(5,29);printf(" %4x ,GainUoint]);scrrowcol(6,29);prinf(" 9b4x ",alphaUjoint]);scrrowcol(7,29);printf(" %4x ",beta[ointl);scr rowcol(8,29);signext(pos[joint]);printf" %d ",posljoint]);scr_rowcol(9,30);printf("%s",algorithm[algjoint]])temp = peek((joff/2)+OxCjsegm);scxrjowcol(15,36);printf"%3x",temp);temp = peek((joff/2)+0xEjsegm)&0xl;scrowcol(16,36);if(temp) printf("rv");else printf("for");temp = peek(joff+Ox8jsegm)l(peek(joff+Ox9jsegm) << 8);scr_rowcol(17,36);printf("%4x",tcmp);
algjoint] = 1;* tirme to start the run *
if(transmit)
sc_rowcol(12,20);printf("Transmitted*ANY KEY*");scrrowcol(13,30);printf("*TO EXIT*");logint(onecompos[joint]);scr_rowcol(15,28);printf("Duty:');scrjowcol(16,28);printi'"Dir:");scr_rowcol(17,28);printf("Ctrl:");scr_rowcol(18,24);printf("count");scrrowcol(l9,24);pritf"ratex");sctrowcol(20,24);printf"rat4y");
* input runtime variable to dual port ram, poking cornmand position last *tran_direct(jscgmjoffjoint);
*let it go until a key is hit *while(!scr_csts)
scrrowcol(10,30); * put the present position on the screen *posjc = (peek(joffjsegm) > 4)+(peek((joff+l)jsegm) << 4);printf("%od ",(signext(posjc)));temp = peek(off2)+OxCjsegm);scrjrowcol(15,36);printf("%3x",temp);temp = peek((joff2)+0xEjsegmn)&Oxlscrrowcol(16,36);if(temp) printf("rev");else printf("for");temp = peek(joff+Ox8jsegm)l(peek(joff+x9jscgm) << 8);scrrowcol(17,36);printf("%4x",tcmp);counter=peck((joff+Ox1 O)jsegm)+(peck((joff+Ox 1) l)jsegm)<<8);scrrowcol(18,32);printf("%d",countr);scrrowcol(19,32);* put raten onto screen *while(peek(FROMZ80jsgm) = 'U');pok('R',FROMZ80jsegm);temp = peek(x04jsegm)l(peek(0x05 jsegm)<<8);templ = peek(OxO6jsegm)l(pek(xO7 jscegm)<<8);poke('O'FROMZ80jsegrn);printf("%d ",temp);scrrowcol(20,32);printf"%d ",templ);****data logging***if(dataflag)
logint(cntt,counter); * keep the counter *logint(onecom,pos[joint]); * keep commanded position*logint(onejnt,posjc);* and the output arm position*
* zero out any residual corunands jc3*while(peek(FROMZ80jsegm) = 'U);poke('R',FROMZ80jsegrn);while(peek(TOZ80,jsegm) = 'R'); poke(',TOZ80jsegm);
81
poke(poek(Oxo0+joffjsegm) joff+Ox80jscgm);poke(peek(OxOl+joffjsegm),0x81+joffjsegm);
poke(0.0x88+joffjsegm); poke(0,x89+joffjsgm);pokc(0,0x84+joffjsegm); pokc(O0,0x85+joffjsegm);pok(0,0xSC+joffjscgm); poke(0.0x8D+joffjsgm);pokc(O,Ox9C+joffjscgm); poke(0,0x9D+joffjsegm);pokc(0,OxAO+joffjsegm); poke(0,0xAl+joffjsegm);poke('N',TOZ80,j segm);poke('O'FROMZ80jscgm);transmit =FALSE;scrrowcol(12,20);prtf(" );scrrowcol(13,30);printf ");scrrowcol(l5,28);printf(" ");scr_rowcol(16,28);printf(" ");
screon0;screen2);
timeloop(seg)int seg;
chartirm[9];long cntr, end;while(peek(FROMZ80,seg) = 'I);cntr = peek(0x10,seg) + (peck(Oxll,scg) << 8) + (pock(0x12,scg) << 16);times(tire);scrdclr;scr rowcol(5,5);printf("loop counter: %d",cntr,"n");printf("time: %s",ime,'Nn");end = catr + 100000;while(cntr < end)
cntr = peek(OxlO,seg) + (peek(Oxll,seg) << 8) + (peek(Ox12,seg) << 16);inmes(time);
scr rowcol(8,5);printf("loop counter: %d",cntr,"n");printf("tim: %s",tim,"n");printf(type any key to exit");while(!scrcstsO);}*/
82
/* SUPPORT2.C -- BAT support routines version 6.4** by John Spofford, Herbie Viggh, and David Anderson** M.I.T. Space Systems Laboratory*/#include "PORTNUMS.H"/*#define MASBUFLIM 100 * # of buffer checks before timeout *//*#define MASREDLIM 100 * # of ready checks before timeout *//* ------- 1-------------/* tran mast -- transmitbuffers to master control card tran_mast(mdata,mconmmaddr,mlast)char mdata[] mcomm[] maddr[];int mlast;
int retval, waite; * timeout variable *int i; * loop index *
puts("Using old tran_mast\n"); * use tranjcsdpr! *
retum(0);retval = 0;* master buffer full? if so, error *if (inport(P1A) & 0x40)
print("** MASTER BUFFER ERROR AT START **\n");*retval =-1; * -1 is start buffer full error *
* master has hung joint card? if so, error *if (inport(P1A) & 0x80)
printf("** MASTER HAS HUNG JOINT CARD **n");*retval = -2; * -2 is hung joint card error *
for (i = 0;i <= mlast;i++) * transmit to master *
/* master buffer full? try timeout *for (waite = 0;inport(P1A) & 0x40;waitc++)
if (waitc > MASBUFLIM)
printf("** MASTER BUFFER TIMEOUT ERROR **E");*retval = -3; * -3 is buffer full timeout error *break
* is master ready? try timeout *for (waite = 0;!(inport(P1A) & 0x20);waitc++)
if (waite > MASREDLIM)
printi(" * MASTER NOT READY FOR TRANSMIT * %");*retval = -4; * -4 is ready timeout error *break
if(mcomm[i] -0) * dont pass a zero command *
retval = -5;continue;
* output to master *outport(P3Amdata[i]); * data *outport(P3B,mcomm[i]) command *
outport(P3C,maddr[i]); * address (low 3) *outport(POX,CSLO); * strobe lo *outport(POX,CSHI); * and hi *
} *end of transmit to master *
outport(POX,CSHI); * leave it high *retun(retval); * all is okay *
*-__________________ #1
/* tranpuma -- transmit buffers to puma control card */#define PUMLIM 23#define PUMSYNC OxFF/* -------------------- /tran_puma(pdat,plast)char pdat[l;int plast;
int waite; /* timeout variable */int i; /* loop index */
/* is puma ready? try timeout *1for (waite = 0;!(inport(P1A) & Ox02);waitc++)
if(waitc >PUMLIM)
printf"'* PUMANOT READY FORTRANSMIT *\n");*/retum(-2); /* -2 is ready timeout error */
/* send PUMA sync code /outport(PlB,PUMSYNC); /* send sync */outport(POX,C3LO); /* strobe lo *1outpott(POX,C3HI); /* and hi */
83
for (i = O;i <= plast;i++) /* transmit to puma */
/* is puma ready? try timeout */for (waitc = O,!(inport(P1A) & OxO2);waitc++)
if(waitc > PUMLIM){printi'"** PUMA NOT READY FOR TRANSMIT *%a");*/retun(-2); /* -2 is ready timeout error I/
/* output to puma */outport(P1B,pdat[i]); /* data */outport(POX,C3LO); /* strobe lo */outport(POX,C3HI); /* and hi */} /* end of transmit to puma */
return(0); all is okay */}
/*.-------------------*/
/* adctest.c -- convert analog inputs using AD364 *//* convert -- returns signed integer (-2048..2047)** 9999 onerror */convert(ais_ch, muxch)int aisch, muxch; /* the two input multiplexers */
int highS, low4, value;
if ((ais_ch > 15 11 aisch < 0) II (mux_ch > 15 muxch < 0))retun(9999); / error return big num */
outport(POA, (aisch << 4) 1 mux_ch); /* ais high, mux low */
/* start conversion (need 15us delay after setting muxes) */outport(POX,C1LO); /* AO select 12 bit conversion /outport(POX,C2LO); /* R/C set to convert */outport(POX,COHI); /* CE trigger conversion */outport(POX,COLO); /* CE drop trigger */outport(POX,C2HI); /* R/C set for read */
/* wait for end-of-conversion */while (inport(Pl A) & 1); /* STATUS */
/* read data */outport(POX,COHI); /* set CE for read */high8 = inport(POB);/* AO already low */outport(POX,C1HI); /* AO select low 4 bits of data */low4 = inport(POB) & OxFO, /* in upper 4 bits */outport(POXCOLO); /* reset CE low */
/* massage & return */value = ((high8 << 4) 1 (low4 >> 4)); /* adjust to form a number */return(value-2048); /* return centered at zero */
/* --------------------rqstmstr(cardnum)char cardnum;
intretval, waitc;* timeout variable *
retval = 0;* master buffer full? if so, error *if (inport(P1A) & 0x40)
* printf("* MASTER BUFFER ERROR AT START *'");*retval = -1; * -1 is start buffer full error *
* master has hung joint card? if so, error *if (inport(P1A) & Ox80)
* printf("** MASTER HAS HUNG JOINT CARD **\n");*retval = -2; * -2 is hung joint card error *
* is master ready? try timeout *for (waite = 0;!(inport(P1A) & Ox20);waitc++)
if (waite > MASREDLIM)
* printf("* MASTER NOT READY FORTRANSMIT **\n");*retval = -4; * -4 is ready timeout error *break;
* output to master *outport(P3A,0); * data *outport(P3B,0); * command outport(P3C,cardnum); * address (low 3) *outport(POX,CSLO); *strobe lo outport(POX,CSHI); * and hi ** end of transmit to master *retum(retval); * all is okay *}
84
---------------------- /
/* syn c -- waits for time interrupt and then returns.** it returns -1 ift was a time fault error */
#define TLOFF Ox6C /* offset of PC BIOS timer_low counter */#define TLSEG 0x40 /* segment of PC BIOS timer_low counter *//* --------------------/synchronize()
static char last_low;char peek;
if (pcek(T_LOFF,TLSEG) = last_low) /* look for error */
lastlow = peek(T_L_OFF,T_LSEG); /* set to new */return(TRUE); /* crror if flag already set /
while (peek(TL_OFFT_LSEG) = last_low); /* wait for new count */
last_low = peek(T_L_OFFT_L_SEG); / set itto new */retumr(FALSE); /* back to work */
/* --------------------/int addr, data;/*------------- ---- */irport(a)inta;
extern int addr, data;
addr = a;#asm;ASM88 /*
MOV DX, WORD addr_IN AL,DX ;get dataMOV AH, 0 ;char valueMOV WORD data, AX
;*/
#retum(data);
/* ---------------- /--outport(a,d)int a,d;
extern int addr, data;
addr = a;data = d;
#asm; ASM88/*
MOV DX, WORD addr_MOV AX, WORD dataOUT DX AL ;output char
#/*--------------------*1unsigned offsetl6, segmentl6;char byte8;/* --------------------/char peek(o,s)unsigned o,s;
extem unsigned offsetl6, segmentl6;extem char byte8;
offsetl6 = o;segmnentl6 = s;
#asm; ASM88 /*
MOV DI, WORD offsetl6MOV ES, WORD segmentl6_MOV AL, ES:[DI] ; kMOV byte8 AL ;return it
;*/
return(bytc8);
/* --------------------/poke(c,o.s)char c;unsigned o,s;
extem unsigned offsetl6, segmentl 6;extern char byte8;
offsetl6 = o;segmentl6 = s;byte8 = c;
#asm
85
AL, byte8_DI, WORD offsetl 6ES, WORD segmentl6_;poke
·---- *
/*clip & adjust position values*/
if((tdat & 0x800) != 0) /*sign extend*/
tdat = tdat I OxF00;
if (tdat > 1024)retum(1024);
else if (tdat < -1024)return(-1024);
elseretum(tdat);
/* offset and scale from master to real arm */align(dater ix)int dater, ix;
int ixy;extem int align offset[8];extent float aligngain[8];extem int maxjcsval[8, minjcsval[8];extem int masoff5]; /* master offset */extem float masnul[5]; /* master mult */
dater = aligngain[ix] * (dater + lignoffset[ix]);if (dater > maxjcsvalix])
retum(maxjcsval[ix]);else if (dater <minsjcs_val[ix])
retum(minjcsval [ix]);else
returm(dater);
/* read control station switches -return via extemal cswitch[i]TRUE = switch activated. comps for swapped leads on blue */
/* ------ */char cswitch[16];char old8, old9, oldlO, oldll;char initflag = TRUE;read_switches()
char iixnmask;int temnpc;extem char cswitch[16];extem char old8, oldlO, oldl 1, old9;extem char initflag;
I 0(F) 1 (T) Location0 on off1 on off2 off on3 on off4 on off5 on off6 on off7 on off8 on off9 an off10 on off11 on off12 on off13 on off14 on off15 on off
Modified from direct i/o port reading of switches to scaning through a 16 to1 mux. -10/86 DEA
*//*
/*5
as of 10/28Function (run bat)
panel: red shutdown & exitpanel: white slave togglepanel: blue toggle PUMA enablepanel: black master flyingann: out/pull(lB) conect headamr out/push(lA) toggle left clawarm: i/pull(2B) master connectarm: in/push(2A) toggle right clawfoot: far left Beam carrier togglefoot near left Beam carrier clawfoot: near right head flying togglefoot: far righthand contright spare pnuematics 1hand contmiddle spare pnuematics 2hand contlefthand conetrigger
tempc = inpart(P4C); ***direct i/o port code***for (i = 0,i < 8;i++)
cswitch[i] = !((tempc >> i) & 1);if (cswitch[2]) cswitch[2] = 0;
else cswitch[2] = 1;returm(tempe); */
serial port reader*/
tempc = 0;for (i=0;i<16;i++)/Iscan through all 16 switches*/
/* switch address, i, is sent to P3C3-6. Note that P3CO-2 areinitialized to 0, but are used by the feedback() function.*/
outport(P3C,((i<<3) & 0x78)); /*now send addresses with strobe lowered */x = (inporlt(PlA)>>2)&0xOl;
86
; ASM88 /*MOVMOVMOVSTOSB
;*/
}
Padjust(tdat, i)inttdat, i;
------------ --------- -- ----- - ----- ---- -------
if (i=2)x = !x;
/*read the switch -output is at P1A2 so shift by 2 bits and mask tocut out garbage. Note that output is inversion of switch state.When switch i is grounded, output, x, is high. Switch 2 leads arebackwards, so we invert x there.*/
/* installed 11/86 due to high beam foot switches, which are not impulseswitches like the rest -DEA*/
if(initflag)
if (i8) old8 = x;if(i---9) old9 = x;if (i=10) oldlO = x;if(i=11)
oldll =x;initflag = FALSE;
if (i=9)
if (x != old9)
old9 =x;x=1;
else
if (i=10)
if(x != oldlO)
else
if(i=-ll)
if(x !=oldll)
old9 = x;x =0;
oldlO = x;x=l;I
oldIl = x;
oldll =x;x=l;
else
oldll =x;x=O;
if (x != old8)
old8 =x;x=1;
else
cswitch[i] = (x & OxOl);tempc I= (x & OxOl)<<i;
old8 = x;x = 0;
/*set appropriate cswitch /
retum(tenpc);
/* ..------------------------------------------- -//* This function reads the five pots on the head controller. -HV */
readhead()
int i tdat;extern int potlabelx[5], potlabely[5];extem inthpot[5];
for (i=O; i<=4; i++)
tdat = (convert(potlabelx[i],potlabely[i]) & OxFFF) - 1024;h.pot[i] = tdat,if(hpot[i] > 1024)
h_pot[i] = 1024;
87
if(i==8)
else if(h_pot[i] <-1024)hpot[i] = -1024;
/*--------------------------- -------------------------------- //* This function calculates jes commands for the tilt an pan from thehead controller pots. -HV revised DEA */
head_canmslavel()
int i, tcpitch, t_cyaw;extem int hpot[5], headoff[5];extern int cpitch, cyaw, pos[9];extem float cpitmult, cyaw_mult;extem int maxjcs_val[8], minjcs_val[8];
for (i=0O; i<5; i++)hpot[ij = hpot[i] -headoff[i];
t_cpitch = hpot[3] -hpot[l];tcyaw = h_pot[4] + h_pot[];cpitch = tcpitch * cpitmult;cyaw = tcyaw * cyaw_mult;
if(cpitch > maxjcs_val[ 1])cpitch==maxjcsval[l];else if (cpitch < minjcs_val[l])
cpitch =minjcs_val[l];if(cyaw > maxjcs_val[2])
cyaw = maxjcs_val[2];else if(cyaw < minjcsval[2])
cyaw = minjcs_val[2];pos[7] = (cpitch) & OxFFPF;pos[8] = cyaw & OxFFF;
/* -------------------------------------/* This function calculates the PUMA commands for flying BAT rotationsfrom the head controller. -HV */
headpuma_slavelO
int i, t_ppitch, t_pyaw, t_proll;extem hpot[5], p_headoff[l5];extem float ppitmult, pyawmult, prol-mult;extem int ppitch, pyaw, proll;
for (i=0; i<S; i++)hpot[i] = hpot[i] -p_headoff[i];
tppitch = hpot[3] -h_pot[l];tpyaw = h_pot[4] + hpot[0];tproll = hpot[2];
ppitch = tppitch * ppitmult;pyaw = tpyaw * pyaw_mnult;prol = tproll * prol_nult;
/* ------------------------------------- */
88
/* SUPPORT3.C -- BAT support routines version 6A** by John Spofford, M.I.T. Space Systems Laboratory** revisions by DavidE. Anderson*/#include "PORTNUMS.H"#include "DAT.H"#define PI 3.1415926536#define PI2 1.5707963268#define R2D 180.0/PI#define D2R PI/180.0/*-------------------- */char jcs_codc[2048];unsigned load_addr;unsigned total;char jcstat[8] = {FALSEALSEALSEFALEALSEF SEA LSESEFALSE};DATATAGjc2pc[TAGSIZE] = {"KIBJC2pos corn"};DATATAG jc2pm[TAGSIZE] = { "MIBC2 pos meas" };/* -------------------- */load_control_system()
int i, j, k;extem char jc_stat[];
for (i = 1; i <= 4; i++)
if(load_dulram(i)){printf("\n%c Dual-port RAM loading failed (JC-%d)\n",7,i);for (j = 0; j <= 10; j++)
dawdle(' '); /* time to read message */
elsejc_stat[i] = TRUE; /* card is OK */
retum(FALSE);
/* -------------.--..*/load-jcs_buffer(fp)int fp;
extemrn char jcscode[2048];extem unsigned loadaddr;extem unsigned total;int i, byte, count, namecnt, code_ptr;char lastblock;
rl6(fp);nament = r8(fp)*256 + r8(fp);for (i = 0;i < namecnt;i++)
r8(fp);r8(fp);if (r8(fp) != OxAO)
printf("nNot a Z80-type file.\n");closeU(fp);return(TRUE);
lastblock = FALSE;code..ptr = 0;if ((count = r16(fp)) < 257)
lastblock = TRUE;count -= 5;total = count;rl6(fp);load addr = rl6(fp);for (i = 0;i < count;i++)
jcscode[code_ptr++] =r8(fp);if(!last_block)
while (Ilastblock)
rl6(fp);if ((count = rl 6(fp)) < 257)
last_block = TRUE;count -= 5;total += countr16(fp);r16(fp);for (i = 0i < count;i++)
jcs_code[code_ptr++] = r8(fp);
if (code-ptr != total)printf('ncodcptr != total"); /* just checking */
if((byte = codeptr % 16) != 0)for (i = 0; i < (16-byte); i++)
jcos_code[code[od_ptr++] = 0; /* even 16-byte blocks */total = codeptrclose(fp);retum(FALSE);
/* .*--------------------
89
r8(fp)int fp;
int byte;
if ((byte = getc(fp)) !=-1)retun(byte);
printf('n%cError reading file\n",7);close(fp);exit(O);}
/* _....--...--.. ...*/rl6(fp)int fp;
retum(r8(fp) + r8(fp)*256);
/* ================================lload_ dualram(jc)intjc;
int i, fp, rrc;char *JC_file;unsigned jcseg, u;exte char jcscode[2048];extem unsigned load_addr;extemn unsigned total;
JC_file = "J1.OBJ";
if ((fp = open(JCfile,O)) = -1)
printf('\n--> joint code [J1.OBJ] not foundn");rtumr(IRUE);
if (loadjcs_buffe(fp))return(TRUE);
if (total > Ox7FC)
printf('\nCode > 7FC bytesn");return(TRUE);
jc_seg = SEG_OFF + 0x80 * jc;printf'"\nwaiting for JC ready...");errc = 0;while (peek(FROMZ80,jcseg) != 'r') /* wait Z80 ready */
if (peek(FROMZ8Ojc_seg) ='m')
printf('WnJC-%d indicates bad mnmorn",jc);return(TRUE);
dawdle('.); / check for BREAK */if (++erc > 10)
return(TRUE);
prinff('\nCopying into JCS menoryn");jmove(totaljcscode,showds(,0jceg); /* use canned move */for (u = 0; u < total; u++) /* test for errors */
errc = 0;for (i = 0; i < 3; i++) /* three trys */
if (pek(ujcseg) != jcs_code[u)errc++;
if (errc > 1) /* rtry if too many errs*/
poke(cs-code[u],ujcseg);if(peek(ujcseg) !=jcs_code[uJ)
/* give up */printr("*** Error at %04xn",u);retumn(TRUE);
poke('c,TOZ80jc_seg); /* code loaded flag */print"waiting for code running flag...");errc = 0;while (peek(FROMZ80jc_seg) !='f) /* wait code running flag */
{dawdle('.'); /* check for BREAK */if (++errc > 5)
returnCI(RUE);
retumm(FALSE);
daweh)============= ===== ===*/dawdle(ch)
90
char ah;
putchar(dh);synchronize();synchronize);synchronize);synchronizeO;synchroniz();
static char tran slate[14]2] = * (old corn, ew offs} X,Y *{{0x8, 0x80}, {0x90, 0x82} * reference D *{0OxEO, 0x84), {0xFO, 0x86) * gainD *{0xCO, 0x88}, {0xDO, 0x8A} * alphaD *{0OxAO, x8C), {xBO, 0x8E} * beta D *{0x01,0x0), x90} {0x03,0x91) *algorithm*{0x04, 0x92), {0x05, 0x94} *pr-dither{0x06, 0x96), (0x07, 0x98}};* post-dither *
tranjcs_dpr(d,c,alast)char d[], c[], a[];int last;
int i, n, jc, dat;char corn, dh, dl, jc2_hit;unsignedjc_seg, jc._offs;extem char jstat[l;intjc2com[2];extem char keep[], data flag;
jc2_hit = FALSE;for (n = 0; n <= last; n++)
{ * for each entry *jc =a[n];if (!jcstatcj])
continue; * if JC is inactive, pass on *jc_seg = SEG_OFF +jc * 0x80;corn = c[n] & 0xFO;for (i = 0; i <= 7; i++)
{ * scan thru data cormmands*if (cor = tran-slate[i][0])
break;
if(i 7){ *ahit*
jcoffs = (unsigned) tran slate[i][1];dh = d[n];dl = (c[n] << 4) & 0xF0;dat = + (dh << 8);if(i =1)
jc2com[i] = dat;jc2 hit = TRUE;}
while (peek(lOZ80jc_seg) = 'R'); * wait for JC read *pokeC('UTOZ80jc.seg); * set Update flag *poke(dl jc_offs++ jc_seg);poke(dhjc_offsjc_seg);poke('N',TOZ80j_cseg); * set New data flag *
else{ * chck renmaining *
corn = c[n] & OxOF;for (i = 8; i <= 13; i++)
{ * scan thru other cormnands *if (com = translate[i][0])
break
if (i <= 13){ *ahit*jcoffs = (unsigned) tran_slat[i][l];while (peek(TOZ80jcseg) = 'R'); * wait for JC read *poke('U',TOZ80jc_seg); * set Update flag *poke(d[nljc_offsjc_seg);poke('N',TOZ80jcseg); * set New data flag *
} * otherwise ignore command *
* if (dataflag && jc2hit && keep[l 1])logint_a(jc2pcjc2co);
1*--------------------*1startjc(n)intn;
unsigned j__seg;int count, i;char gg;
if (!jc stat[n])
91
return(TRUE); /* cant start a dead JC */jc_seg = SEG_OFF + 0x80 * n;for (i = 0x80; i < COMM_FLAG; i++)
poke(0,ijc_seg); p clear command area */for (count = 0; peek(JC_STATUSc_seg) !='W'; count++)
{ /* JC should set Waiting flag */synchronize(;if (count > 36) /* 2 sec limit */
shutdownbat(;printf"%c'nJC-%d not ready for starn",7,n);exit(2);
poke('G',COMM_FLAGjc_seg); / Go flag to JC */if (peek(COMM_ FLAGjcs-eg) !='G)
poke('G'.COMMFLAGjc_seg); /* try again */gg = peek(COMMFLAGjseg);
for (count = 0; peek(JCSTATUSjc_seg) != 'C; count++)/* check for Controlling flag */
synchronize();if(count > 18) /* 1 sec limit */
shutdown_bat();printf("%cnJC-d did not respond to start\n",7,n);dawdle(gg); dawdle(gg); dawdle(gg); dawdle(gg);exit(2);
log-joints(
exten char keep[];int jc2treas[2];
* read back joint card *jc2meas[0] = peek(0,0xE900) + (peek(1,0xE900) << 8);jc2meas[1] = peek(2,0xE900) + (peek(3,OxE900) << 8);if(keep[13])
loginta(jc2pmjc2eas);
monitorjc(
int sel;
while (TRUE)
sel = monjcxenuO;switch (sel)
case 1:
case 3:case 4:
watchjc(sel);
case 0:retumC(TRUE);
default:co(7); /* beep */break
/# =========================== ===== /watchjc(n)intn;
unsignedjcseg;char d, dl, dh, *oneb, *twob;long ld;
oneb = "%02x";twob = "%02x%02x";scrcdlrO;scrjrowcol(0,0);puts(" - X- -Y-\n");*O*/puts(" n");/*l */puts(" COMMANDED POSITION XXXX XXXX\n");1*2*/puts(" INDICATED POSITION XXXX XXXX\n-);/*3*/puts(" INDICATED RATE XXXX XXXX\n")J*4*/puts(" \n");/*5*/puts(" GAIN XXXX XXXX\n");/*6*/puts(" n");/*7*/puts(" n");/*8*/puts(" CALCULATED CONTROL XXXX XXXX\n");/*9*/puts(" DUTY CYCLE XX XX\n")'*10*/
92
putsC" DIRECTION CCC CCC\n")ll11*/puts(" LOOP COUNTER XXXXXX n");/*12*/puts(" n");/*13*/puts(" n");/*14*/puts(" n");/*15*/puts('cn Iit any key to exit");
scr_rowcol(O,2);printf("JC-%d",n);jc.seg = SEGOFF + Ox80 n;while (!scr_cstsO)
/* cn pos *dl = peek(0x80jc_seg);
scr_rowcol(02,25);dl = peek(0x82jcseg);
scrrowcol(02,33);/* ind pos */dl =peek(OxOOjcseg);
scrrowcol(03,25);dl = peek(0x02jc_seg);
scr_rowcol(03,33);/* ind rat */d = pek(xO4jc_seg);
scrjrowcol(04,25);dl = peek(Ox06jc_seg);
scrrowcol(04,33);/* gain*/dl =pek(Ox84jcseg);
scrrowcol(06,25);dl = peek(Ox86jc_seg);
scr rowcol(06,33);/* calc ctr */dl =peek(OxO8jcseg);
scr rowcol(09,25);dl =peek(OxOAjc_seg);
scrrowcol(09,33);/* duty cy */d = peck(Ox0Cjc.seg);
scrrowcol(10,27);d = peek(0x0Djc_scg);
scrrowcol(10,35);/* direct */d = peek(OxOEjcseg);
if(d) puts(d = peek(OxOFjcseg);
if(d) puts(/* loop t */scr-rowcol(12,23);d = peek(0xl2jc.seg);d = peek(Oxl ljcseg);d = peek(OxlOjc_seg);}
printprintprit
dh = peek(Ox81 jcseg);printf(twob,dhdl);
dh = peck(0x83 jc_seg);printf(twob,dh,dl);
dh = peek(OxOl jcseg);printf(twob,dhdl);
dh = peek(0x03jc_seg);printf(twob,dh,dl);
dh = peeki0x(O05(OxOjcseg);printf(twob,dh,dl);
dh = peek(OxO7cseg);printf(twob,dh,dl);
dh = peek(Ox85 jcseg);printf(twob,dh,dl);
dh = peek(Ox87 jcseg);printf(twob,dhdl);
dh = peek(0x09jc_seg);printf(twob,dh,dl);
dh = peek(OxOB jcseg);printf(twob,dh,dl);
printf(oneb,d);
printf(oneb,d);
scrrowcol(11,26);("REV"); else putsCFOR");
scrrowcol(11,34);:"REV"); else puts("FOR");
f(oneb,d);tf(oneb,d);foneb,d);
/*= . .. ........... ========........... '/monjc menuO
int query,
scrlrO;scr_rowcol(2,0);printf(" MIT SSL BAT/ICS\n\n");printf(" Monitor Joint Cardn\n");printf(" 1. WRIST A & B\n");printf(" 2. SHOULDER P & Yn");printf(" 3. ELBOW & LEFT ARMn");printf(" 4. CAMERA T & P'n");printf(" . EXl\n\n");printf(" EnterSelection: ");scanf("%dn",.&query);retum(query);
readjoints(comn,post)/* reads positions and conmmands for all power modules. Note that outputis a 12 bit number left shifted into a 16 bit number. */int com[8], post[8];
char d, dh;
/* command pos */dl = peek(0x80,0xE880);com[O] = dl + (dh << 8);dl = peek(0x82,0xE880);comrn[l] = dl + (dh << 8);dl = peek(0x80,0xE900);com[2] = dl + (dh << 8);dl =peek(0x82,0xE900);com[3] = dl + (dh << 8);dl = pek(0x80,0xE980);com[4] = dl + (dh << 8);dl = peek(Ox82,0xE980);
/* wristA*/
/* wrist B */
/* sh pitch *
/* sh yaw */
/* elbow */
dh = peek(0x81 ,OxE880);
dh = peek(0x83,xE880);
dh = peek(Ox81,OxE900);
dh = peek(0x83,0xE900);
dh = peek(0x81 ,0xE980);
dh = peek(Ox83,0xE980);
93
com[5] = dl + (dh << 8);dl = poek(Ox80,xEAOO);com[6] = dl + (dh < 8);dl = peek(Ox82,0xEAOO);cornm[7] = dl + (dh << 8);
/* indicated pos */dl =peek(OxOO,OxE880);post[O] = dl + (dh << 8);dl = poek(OxO2,0xE880);post[1] = dl + (dh << 8);dl = peek(OxOO,OxE900);post[2] = dl + (dh « 8);dl = peek(OxO2,OxE900);post[3] = dl + (dh << 8);dl = peek(OxO0,OxE980);post[4] = dl + (dh << 8);dl = pek(OxO2,0xE890);post[5] = dl + (dh << 8);dl = peek(OxOO,OxEAOO);post[6] = dl + (dh << 8);dl = pe(Ox020xEAOO);post[7] = dl + (dh << 8);
/* cooling pump */dh = peek(Ox81,OxEAOO);
/* camnra tilt (pitch) */dh = peek(0x83,OxEAOO);
/* camera pan (yaw) */
dh = peek(OxO1,OxE880);/* wrist A */
dh = peek(0x03,OxE880);/* wrist B */
dh = peek(OxO1,OxE900);/* sh pitch */
dh = peek(0x03,OxE900);/* sh yaw */
dh = peek(0x01,OxE980);/* elbow */
dh = peek(0x03,OxE890);/* cooling pump */
dh = peek(Ox01,OxEAOO);/* camera tilt (pitch) */
dh = poeek(0x03,0OxEAOO);/* camera pan (yaw) */
display_arm()
int allpos[8], armpos[5], dummy[8], i, v;float gripx, gripy, grip_z, angles[5];exten char potnamell;
scrdrc0;scrrowcol(O,O);puts(" ENCODER\n");*O*/puts(" HEX DEC JOINl\n");/*1*/for (i =3; i< 8; i++)
scr_rowcol(i.,18);puts(potnam[i]);scr rowcol(i + 7,5);printf("%c%c",233,i - 3 + 1');
scrrowcol(19.4);puts("Hit any key to exit");scrrowcol(9,10);puts("ANGLE (DEG)");
while (!scr_cstsO)
readjoints(dunmy,allpos);armpos[0] = allpos[0];armpos[l] = allpos[ll];armpos[2] = allpos[4];armpos[3] = allpos[3];armpos[4] = allpos[2];enc2tht(arrnmpos,angles);batfor(angles,&grip_x,&grip_y,&gripz);for (i = 0; i <5; i++)
scr_rowcol(3+i,0);v = annrmp[i];printf(" %04x %6d",v,v);scrrowcol(10+i,10);printf("%6.2f',angles[i] * R2D);
scrrowcol(16,4);printf("X = %5.lf Y = %5.lf Z = %5.l",gripx,grip_y,grip.z);
_ _ _ _ _}*
94
/* SUPPORT4.C-- BAT support routines version 6.4** by John Spofford and David E. Anderson, M.I.T. Space Systems Laboratory*
#include "PORTNUMSH"1* --------------- -------- ---- *adjustpots()
int number, newval, i, temp, fn, iii;char tempc, done, done2;extm int div_or_ mul[8], p_gain[8], maxp[8], min_p[8];extem char icnvt[8], icnvt2[8];extem char *potnam[8];extem float aligngain[8];extem int alignoffset[8];
done = FALSE;while(!done)
{scr_dr(;scrrowcol(3,0);printf(" ICS Pot Adjustments'n\n" );for (i = 0;i < 8;i++)
printf(" %ld %s\n",i+l,potname[i]);printf(" S Save to file\n");printf(" L Load from file\n");printf("[CR Exitn");printf(\n\nEntrr Selection: ");tempc = scr_ci0;switch(tempc)
case 13:done = TRUE;bSak
case 'S':case 's':
if((fn= creat("ICSDAT")) = -1)
beep(25);printg("UNABLE TO WRITE FILEn");pause(250);
elsefor (i = 0;i < S;i++)
putw(div_ormul[il,fn);putw(p_gain[i],fn);putw(max_p[i],fn);putw(minp[i],fn);putc(icnvt[i],fn);putc(icnvt2[i],fn);
close(fi);brea
case 1':case 1':
if ((fn = open("ICSDAT",0)) = -1)
beep(25);printf("UNABLE TO OPEN FLE\n");pause(250);
elsefor (i = O;i < 8;i++)
{divormul[i] = getw(fn);pgain[i] = getw(fr);maxp[i] = getw(fn);min_p[i] = getw(fn);ivtli] = getc(fn);icnvt2[i] = getc(fn);
close(fn);break,
case '1':case ':case '3':case 4':case '5':case '6':case '7':case '8':
iii = tempc -'1';scrdrO;scrrowcol(1 ,0);printf("Joint: %s\n",potname[iii]);printf(" Current Settingsa");prind(n"n);printf(" -Maximum Position: %5dn",maxp[iii]);printf("2--MinimumPosition: %Scn",min_p[iii]);printf("3-Pot Shifts: %Sdn",p_gain[ii]);printf"4--Shifl Direction ");
95
if(divor_ml[iii])printf("RIGHT");
elseprintf("LETFW");
printf"CnWn");printf("5--Pot convert(");printf("%2d, % 2d)\n",icnvt2[iii],icnvt[iii]);printf("[CR--Exit");done2 = FALSE;while(!done2)
scr_rowcol(18,0);printf("Enter Selection: ");scr rowcol(18,18);while((tempc = scrcstsO) 0)
scrrowcol(15,10);temp = (convert(icnvt2[iii],icnvt[iii]) & OxFFF;printf("Adjusted pot:%5dadjust(temp - 1024, iii));
scrjowcol(18,17);printf(%c",tempc);sc_rowcol(21.0);printf(" ");
switch(tempc)
case 13:done2 = TRUE;biak
case '1':max_p[iii] = getnw_val(4,31);b-lq
case '2':min_p[iii] = getLnewval(5,31);beak;
case '3':pgain[iii] = getnew_val(6,31);beak
case 4':getnew_val(21,16);div_ormul[iii] = !divormul[iii];scrowcol(7,31);if(div_or_mul[iii])
printf("LEF ");else
printf("RIGHT");bmea
case '5':temp = get_new_val(10,31);newval = getnew_val(10,31);scrrowcol(21,0);print(" );scrowcol(10,31);printf(4(%2d,%2d) ",tempnewval);icnvt2[iii] = temp;icnvt[iii] = wval;bseak
case '6':scrrowcol(21 ,0);printf("Enter offset value (int)");scanf("%dn",&alignoffset[iii]);scrjowcol(22,0);printf("off: 9%4d, ",alignoffset[iii]);printf("gain: %8.5f',aligngain[iii]);
case '7':scrrowcol(21 ,0);printf(Enter gain value (float)");scanf( "% fn,&align_gain[iii]);scrrowcol(22,0);printf("off: %4d, ",align_offset[iii]);printf("gain: %8.5f',align_gain[iii]);break
defaultscrrowcol(22,0);printf("%clnvalid Resp.,Please Reenter",7);pause(100);scrjowcol(22,0);printf(" ");bacak
b;ealdefault
scrrowcol(22,0);printi"%clnvalid Entry, Please Re-Enter".7);pause(100);scrrowcol(22,0);printf(" ");scrrowcol(15,17);printf(" );scrrowcol(15,17);
96
brcak;
get new val(worJoc)int wor, loc;
intret_val;
scr_rowcol(21,0);printf("Enter New Value");scr_rowcol(worJoc);printf(" ");scrjrowcol(worjoc);scanf("%d",&rtval);retumrn(rt_val);
/* stat --- check status *//* JC_STATUS: C = controlling, W = waiting */statO
char statword;char jc;unsignedjseg;ext char jcstat[];
/* is PUMA ready? */statword = inport(P1A);scr_rowcol(6,21);if (statword & 0x02)
scrco(2);else
scr co(25);
for (jc = 0; jc <7; jc++)if (icstatjc])
/* ifjc loaded */jseg = SEGOFF +jc * Ox80;statword = peek(JCSTATUS jseg);scr_rowcol(5,16 + jc);scr co(statword);
/* ------------------------------------------ */* batports.c -- initialize PC ports for BAT** *
/* batports.c - sets the PPI ports for BAT control */baports()
setport(0,0,l,0); /* OA:out OB:in OC:out */setport(l,1,0,0); /* 1A:in lB:out C:out */setport(2,1,1,0); /* 2A:in 2B:in 2C:out */setport(3,0,0,0); /* 3A:in/out 3B:out 3C:out */setport(4l,1,,0); /* 4A:in 4B:in 4C:out */
/* -------------------- -----------------..---/* setport.c -- sets a 8255s ports to input or output mode */setport(portnum,a,b,c)int portnuma,b,c;
char cw; /* mode control word */int addr, /* port address */
if (portnum < 0 11 portnum > 4)return (-1); /* on anerror /
if(a--0) /*port A*/cw = Ox80;
elsecw = Ox90;
if(b !=0) /* port B '/cw =cw +2;
if(c != 0) /* port C*/cw = cw + 9;
addr = 0x303 + (portnum << 2); /* addr range is 300..313 hex */outport(addr,cw); /* control ports are 303,307,...,313 */return (0);
/* -------------- -------------------------
/* screen.c -- sets up BAT video background. 1/8/84 jrs */screen()
sacr_setmode(0);scrsetupO;sc_cursoffO;
puts("");printf(" THRUSTERS %cfffffff%c ff ACTUATORS ff ",218,191);/* 0 */
97
puts(" BsATSOFT2 ");/* 1 */puts(" 2 2 2 2 2 2 2 V 6.4 2 2 2 2 2 22 2 ");/* 2 */printf(" 2> 2 2 2 %cfffffffc 2 2 2 2 2 ",192,217);/* 3 */puts(" 2 2 2 2 2 2 > 2 > 2 2 2 > > "):/* 4 */puts(" 2 2 2 2 2 JC: .... 2 2 2 2 ");/* 5 */puts("> 2 2 > 2 > PUMA 2 5 5 5 5 5 5 2 ")/* 6 */puts(" 2 2 - 5 _5 2 5 5 2 2 2 5 ");/* 7 */puts(" S 2> 2S 2 5 555 -2 5 ");/* 8 */puts ( " 22sS2oos s DRAW ... 2 > 2 > 2 > > 2 ");/* 9 */puts (" Ooos 5ooo HEAD ... +>+>+>+>+>+ +>+") :/* 10 */puts(" 2 2 52 2 5 MAST ... 5 55 2 5 2 55 ");/* 11 */puts(" 2 2 2> > 2 SLAVE ... -5 2 5 5 5 52 "):;/* 12 */puts(" - 5 5 52 FLYING: > > > 5 5 2 5 5 ");/* 13 */puts("- 2 2 55 ...... 2 2 2 2 ");/*14*/puts(" 2 2 2 2 RCLW ..... 2 22 2 2 2 "):/* 15 */puts(" -> 5 52 LCLW ..... 2 2 2 5 5 5 ");/* 16 */puts(" 2 2 2 2 BMCR ..... 2 2 " );/* 17 */puts(" BCLW ..... 2 5 5 5 2 555 ");/* 18 */printf(" X Y Z c %c %c ",232,233,234) ;:/*19*/puts(" W W S S E C C ");/* 20 */puts(" A B P Y L T P "):/* 21 */printf(" command:%c actual:%c ",233,4);/* 22 */puts(" ");/* 23 */puts(" MIT SSL Beam Assembly Teleoperator ");/* 24 */
/* --------------------------------------screen2(
extem char draw,puma_on,head_controller, dataflag;extem char boost_fag,head_c'l _cccmd;extem char master_cometed,slave_am_onmatr_flying;extem char head_ctrl_fyinrigh_claw.left_claw_ste;extem char beam_carrier, beamdaw;extem int set triad;extem int tri_for, trirev;/* for successive triad use */scrrowcol(21,3);puts("thruster");
scr_rowcol(09,19);if (draw) puts("ON ");else puts("OFF");
scr_rowcol(1,4);if(puma_on) puts("ON");else puts("COFF);
scrrowcol(08,15);if(data_lag) puts("DATA");else if(settriad = 0) pus(" ");
scr_rowcol(07,15);if (boostflag) puts("BOOST");els iset triad O) puts(" ");
scrrowcol(10,19);if (h ad_ctrl_comcted) puts("ON ");else puts("OFF");
scrrowcol(11,19);if (master_concted) puts("ON ");else puts("OFF");
scrrowcol(12,19);if (slave_arm_ on) puts("ON");else puts("OFF");
scrrowcol(14,15);if (master_ying) puts("MASTER");elseif(head ctrlfying) puts("HEAD ");else puts("STICK ");
scr_rowcol(l5,18);if (rightclaw) puts("CLOSE");else puts("OPEN ");
scrrowcol(16,18);if (left_claw stae) puts("CLOSE");else puts("OPEN ");
scr_rowcol(17,18);ifbeamncarrier) puts("BACK ");pcounterintuitive for Huntsville*/else puts("OUT ");
scr rowcol(18,18);if(beamclaw) puts("CLOSE");els puts("OPEN ");
scrrowcol(23,0);puts(" TRIAD Up Next: ");if(trifor = 1) puts("CGrabbeam ");if(trifor = 2) puts("Grabslv ");iftri_for = 3) pus("Stow ");iftrirev = 1) pus("Cjoint ");if(trirev = 2) puts("Rgrabslv ");
98
if(tri_rv = 3) puts("Rstow ");
strange()
int val2, vail;char i, signc;extern int align-offset[5];exten float aligngain[5];extem char icnvt[8], icnvt2[8];extem char *potnae[81];
scrcO);scr_cursoff);scrrowcol(,0);puts(" BAT Master Ann MonitoX\nn");puts(" Joint pot adjust align\\n"");/* .0123456789a123456789b123456789c123456789..line*/for (i = 0;i < 8;i++)
printf"%s\n %6.3f %5dn",ponamx[i],align gain[i,align_offset[i]);while (scr_csts( != 13)
for (i = O;i < 8;i++)
va12 = adjust((convert(icnvt2[i],icnv[i]) & OxOFF) - 1024, i);vail = align(val2i) & OxOFFF;signc ='-';if(val2 < 0)
val2 = -va12;else
signc =scrrowcol(i*2 + 5,13);print"(%2d,%2d)%c%04x%03x",icnvt2[i],icnvt[i],signc,val2,val 1);
/* ..------- ------....-.-..-..-.................keyboardconuand(tempc)char tempc;
extenm char ccamn_disp;extem char data_flag; /* logical flags */extem char masterflying, slave_arnnon;extem char left_claw_state, masterconoectcd;extcm char headcontroller, pumna_ n. draw;extem char beacarrier, beamclaw;extem char sparel, spare2; *spare pnuematics 1 and 2*/extemint pgain[8];exten int set_triad;extcm char icnvt[8], icnvt2[8];int i;tePnpc = toupper(ternpc);switch (tempc)
case 'C: r change camera control drive*/print %c",7); /*beep*/scrrowcol(14,15);if(haad_controller)
headcontroller = FALSE;icnvt1] = 9;icnvt[2] = 10;p_gain[ll] = 0;p_gain[21 = 0;puts("STICK");
else
head4controller = TRUE;icnvt[1] = 5;icnvt[2] = 6;p_gain[l] =0;pgain[2] =0;put(HEAD ");
break;case ¶': /* transmit to puma */
printf('%c",7);scr_rowcol(1.4);pumaon = !puma_on;if(pumaon)
putsCON ");else
puts("OFF");bmak;
case )': /*start or stop datalogging */dataflag = !dataflag;scseen20;break
case'E': /* draw to screen */printf(%c",7);draw = !draw;scrrowcol(9,19);
99
if(draw)puts("ON ");
elseputs("OFF"):
breakcase 'R': reset cs /
outport(POX,C6HI); /* reset JCS */outport(P2X,C7HI); / reset propulsion controller */for (i = 0; i < 20; i++); /t pulse width /outport(POX,C6LO);outport(P2X,C7LO);for (i = 0; i < 36; i++)
synchronize0; /* letJCS check memory for (i = 1; i <= 4; i++)
startjc(i); /* start card #1,2,3.4 */break
case T: /* tune joints I/setupjointsO;screcn;screen2(;break;
/* excess fat removedcase T: * adjust right arm *
adjustpots();screen();screen20;break
case 'B': * test feedback from BAT *feedback;scn0;screen2();break
case 'X':stange0;screenO;screen2(;break
cas 'L':leftclaw state = left clawjstatc; /* toggle */if (ftdawstate)
outport(P2X.C1LO); /* dose dclaw */else
outport(P2X,C1HI); open daw */co(7);scren2();break
case 'U':jointstepO;screen(;screen20;break;*/
case '?':print_help();scren(scren2);beak
case W': /* supervisory control calls setup menu for TRIAD*/triadO;screen(scrcn2();break
case 'F:setrimO;screenO;scmon2(;break
case 'G':setdataO;screenO;scren20;break;
case 'J:monitorjc);
screen();break
case 'A':displayarm();scrn0;,scren20;break
case 'Z':seLtboost(;scr2n0;
beakcase 'M':
beam_carrier = !beamcarrir;if(beam carrier)
outport(P2X,C3HI); /pextcnd beam carrier*/)
100
else
outport(PX,C3LO); /*etract beam carrier*/}
co(7);screen2();b-ak
case 'N':beam_claw = !beamclaw;if(beamclaw)
outport(PX,C4LO); /*close beam carrier claw*/
else
outport(P2X,C4HI); /*open beam carrier claw*/
co(7);scrcn2();beak
case 'S':if(slave anrmon)
slaverest(O);else
slaverest(1);break
case '0':sparel = !sparel; /*toggle spare pnuatics 1 iif(sparel)
outport(PlX,C6LO);
else{outport(P1X,C6HI);
co(7);break
case 'Y':commdisp = !cormdisp;break
case 'Q':spa2 = !spare2; /*toggle spare pnuematics 2*/if(spare2)
outport(P1X,C7LO);
else
outport(P1X,C7HI);
co(7);break
case 'V:if(settriad=l)
Ico(7);pointto_point0;
else if(settriad>=2)
coC7);leanmO;
beakcase 'K':
load_from_filc("zcro.bdt ");break
case '1':load_from_file("frcdpid.bdt ");beak
case '2':load_fom file("wrst.bdt ");break;
case '3':load_from_filc("cltst.bdt ");beak
case '4':load_from_file( " shptstbdt ");beak
case '5':load_from_file("shytst.bdt ");breaks
case '6':load_fromffle("tptst.bdt ");break
case '7':load_from_file("triadl.bdt ");break
case '8':loadfromfile("triad2.bdt );break
101
case '9':
case '0':
loadfromfileCtriad3.bdt );
load_from_file("fred.bdt ");bmak
scrclr();scrowcol(0,0);puts(" BAT / ICS Keyboard Assignments (Main)puts" (6.4)puts("A: display arm pos 2S: slave rest/resetputs("B: 2T: set joint cntrlputs("C: cam head/stick 2U:puts("D: toggle data log 2V: TRIAD activateputs("E: dis/enable draw W: TRIAD setupputs("F: thrust trim 2X: monitor masterputs("G: record data -Y: show commandsputs ("H: > Z: boost arm/thrustputs("I: > ?: print this listputs("J: monitor joint cd21: load fredpidputs("K: kill jc duty cyc>2: load wrtstputs("L: use left claw 23: load eltstputs("M: deploy beam cr 24: load shptstputs("N: use beam cr claw25: load shytstputs("O: use spare pnue 16: load tptstputs("P: dis/enable PUMA 27: load triadlputs("Q: use spare pnue 28: load triad2puts("R: reset JCS i tab: shutdown/exitputs(" ");puts(" Type CR) to retum tomain loop ");while (scrcsts( = 13);
"I ;
'1);"I ;
''I;"I ;11);.1);
11);1.);11);.1);11);11);11);11);
/*Slaverest is a function designed to cutout excess use of the rightarm motors. slaverest can also be used to change the master arm offsetsfor smooth power-up.
(0) Power down slave arm. Gains to zero.(1) Prepare to power up. Set offsets to reconcile master and slave.(2) Offsets have been digested. Reset gains.
Dave Anderson 5/20/87 */slaverest(state)int state;
extem int align_offsct[8], currmastr[5], slavetoggle;extem char mastercormected, masterflying, slave_arm_on;extem float aligngain[8];int com[8], posr[8], i, fn, temp[5];int ord[5] = (0, 1, 4, 3, 2);switch (state)
{case O:
case 1:
case 2.
default
slave_arm_on = FALSE;screan20;/* save and zero out slave armnn gains */write_out_data("slavercst.BDT ");load_fromfile("slavezero.BDT ");break;
slavearmon =TRUE;screen2);read.joints(com,posr);for (i=O;i<;i++)
if ((posr[ord[i]] & 0x8000) = 0)posr[ord[i]] = (posr[ord[ill >> 4) 1 OxF000;
elseposr[ord[i]] = posr[ord[i]] >> 4;
alignoffset(i+3] = posr[ord[i]]/align_gain[i+3] - cutrmaster[i];
slave_toggle = 1;break
/* load gains to arm. */slave-toggle = 0;load_from fileC(slaverest.BDT ");
scr_rowcol(12,19);puts("ERg");brealS
resetpid()
int emp;/* reset integrators */while(peek(TOZ80,0xE900)= 'R'); poke(U',TOZ,0,OxE900);poke(0,OxAl,0xE900);poke(0,OxA3,0xE900);
102
print_elp()
}}
}1.·-- ·
poke('N',TOZ80,OxE900);while(peek(TOZ80,0xE880)= 'R'); polk(U'.TOZ80,OxE880);poke(O,OxA1.OxE880);poke(,OxA3,0x880);poke('lN.TOZ80,0xE880);while(peek(TOZ800xE980)= 'R'); poke(UJ',TOZ80,OxE980);poke(O,OxAl,OxE980);poke('N',TOZ80,OxE980);/* once the joint cards have read the zero (set toz80 to 'O')*//* replace original nmultl value */temp = peek(OxO,OxE80); /* read counter on jcl */while(teomp = peek(Oxl,OxE880)); poke('tU.TOZ80,0xE900);poke(1,OxA1,OxE900);poke(l,OxA3,OxE900);poke('N',TOZ80,xE900);poke(U'lTOZ80,xE880);poke(1,OxAl,OxE880);poke(1,OxA3,OxE880);poke('N',TOZ80,OxE880);pokc('IJ,TOZ80,xE980);poke(l,OxAl1.OxE980);poke('N'TOZ80,0xE980);
/---..--........
103
l--========-====I- = ===========*/* SUPPORT5.c -- fakes SUPERVIS.c & MOVE.c 10/23/85 */
#include "PORTNUMSH"#define FACTOR 0.002 /* for pot trim *#define PDEDZON 80 /* for pot trim */#include <mathfh>#define PI 3.1415926536#define PI2 1.5707963268#define R2D 180.0/PI#define D2R PI/180.0' ============================.*/
supervis({co(7); /* beep */
float a[6][6] = /* adjustment matrix */{ 0.67,0.0,0.0,0.0,0.0,0.0 }, { 0.0,0.67,0.0,0.0,0.0.0 },{ 0.0,0.0,0.33,0.0,0.0,0.0 }, { 0.00.0,0.0,.0.67,0.0,0.0 },{ 0.0,0.0,0.0,0.0,0.67,0.0 }, { 0.0,0.0,0.0,0.0,0.0,0.33 } };
trimthrust(j,x) /* adjust thruster commands */intj[], x[];
inti,k;float in[6], out;
for (i = 0; i < 6; i++)in[i] = (float) j[i];
for (i = 0, i < 6; i++){out = 0.0;for(k=0;k<6;k++)
out += a[i][k]*in[k];x[i] = (int) out;
/*======= .======.=============*/set_trim() /* set thruster trim matrix */
int sel, i,j;floatv;char pdat[7];
for (i = O;i < 6;i++)pdat[i] = 128;
tranpuma(pdat,5);while (TRUE)
/* zero ach command *//* Prevent thruster start-up */
load_trim(;break
savetrim0;break
puts(r\nnX=0, Y=l, Z=2, P=3, R=4, Y=S\n");puts(" I is thruster output\n");puts(" J is joystick inputn");puts("Enter I, J: ");scanf("%d,%d'n"',&i&j);printf("A[I[J] is %6.2fn",a[i]lj]);puts("Enter new A[I[J]: ");scanf("%fn",&v);if((i >=0) &&(i < 6) &&(j >=0) &&(j <6))
a[i][j] =v;else
co(7); /* beep I/break
puts(\n\nX=0, Y=I, Z=2, P=3, R=4, Y=5\n");puts(" Iisthruster outputs(" I is tr otpt");puts(" J is joystick inpun");puts(C\i");for (i = 0; i < 6; i++)
printf(" %d ",i);puts(n");for (i = 0; i < 6; i++)
printf("%d: ",i);for (j = 0; j < 6; j++)
printf("%5.2f ",a[i][j]);printr',n");
puts('nHit any key...");gtchaO);
104
sel = trim_selectO;switch (sel)
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
cass 0
break
puts('.nSELECT THRUST AXIS TO TRIM");puts("\nX=0, Y=1, Z=--2, P=3, R=4, Y=5: ");scanf("%dn",&i);if((i >= 0) && (i < 6))
joystick(i);else
co(7); /* beep */break
showthrust();break
retumCTRUE);
defaultco(7); /* beep */break
/* -------------------/joystick(ax)intax;
int thr_ctrl, thrin[6], throut[6], i, temp;extem int stickoff[6];float pot[5];char pdat[7];
scrdrO);scrrowcol(15,5);puts("Hit any key to exit...");
for (i = 0; i < 6; i++)thr_in[i] = 0; /* clear *
scrrowcol(2,0);switch (ax)
case 0: / X*Iprintf("- Y - I- Z - I- P - I- R - I- Y -I");break
casel 1: / Y *I/printf("l- X - I- Z - I- P -I I- R -I I- Y -I");break
case 2 p Z */pritf("l- X -II- Y -II- P-I I- R - II- Y -I");break
case 3: P*P*/printf"- X -I - Y -I I-Z -I I- R-l I- Y -I");break
case4: /* R */printf("l- X -I -Y-I I- Z-I -P-I I- Y -I");break
cases 5: /* Y *I/
default:
printf("l- X - I Y -- Z -I -P-I I- R -I");break
co(7); rbeep */retum(FALSE);break
scr_rowcol(8,0);printif"THRUSTERS ARE ENABLED");
while (!scrcsts())
synchronize0; /* not too fast*/scr_rowcol(4,0);for (i =0; i < 5; i++)
temp = convert(0,i) - 1024;if(temp<0) /*ldeadzone *l
if (temp > -PDEDZON)temp = 0;
elsetemp = temp + PDEDZON;
elseif (temp < PDEDZON)
temp = 0;else
temp = temp -PDEDZON;pot[i] = (float) temp * FACTOR;printf("%7.2f ",pot[i]);
switch (ax)
case 0: Px*/thr_in[O] = -(convert(7,0) - 1024 + stickoff[4]);a[ll]ax] = pot[0];
105
}
a[2][ax] = pot[l];a[3][]ax = pot[2];a[4][ax] = pot[3];a[5][ax] = pot[4];bmak
casel: /* Y*/thrin[l] = -(convert(8,0) - 1024 + stickoff[5]);a[0][ax] = pot[0];a[2][ax] = pot[l];a[3][ax] = pot[2];a[4][ax] = pot[3];a[Sl[ax] =pot[4];break
case2 /* Z*/thr_in[2 = -(convert(6,0) -1024 + stickoff[3]);a[0][ax] =pot[0];a[ll[ax] =potll];a[3][ax] = pot[2];a[41[ax] = pot[3];a[5][ax] = pot[4]bmeak
case3: /P */thr_in[3] = -(convert(0,9) -1024 + stickoff[2]);a[0[ax] = pot[0];a[][ax] = pot[1];a[2][ax] = pot[2];a[4][ax] =pot[
3];
a[5][ax] = pot[4];break
case 4: /* R */tbrin[4 = -(convert(0,10)- 1024 + stickoffI1]);a[Ol[ax] = pot[];a[ll[ax] =pot[l];a[2][ax] = pot[2];a[3][ax] = pot[3];a[5][ax] = pot[4];b-Iq
case 5: /*Y*/thrin[5] = (convert(0,8) -1024 + stickofflO]);a[0O[ax] = pot[0];a[ll][ax] =pot[l];a[2][ax] =pot[2];a[3][ax] = pot[3];a[4][ax] = pot[4];bleak;
tri_thrust(thr_in,throut);for (i = 0; i <= 5; i++)
temp = thr_out[i];temp = (temp > 127) ? (127): (temp); /* limit */temp = (temp < -127) ? (-127): (temp);pdat[i] = (temp + 128);if(pdat[i] = OxFF)
pdat[i] = OxFE;
tran_puma(pdat,5);
for (i = O;i < 6;i++)pdat[i] = 128; /* zero each command /
tran_puma(pdat,5); /* Prevent thruster start-up */
/* --------------- ----showhrust()
int thr_in[6], throut[6], i;extem int stickoffi6];
scrdrO;scr_rowcol(3,15);puts("RAW TRIM");scrrowcol(15,5);puts("Hit any key to exit...");scrrowcol(13,5);puts("Need PPF80 < TRIM < 0080");while (!scr_cstsO)
thr_in[] = -(convcrt(7,0) -1024 + stickoff[4]); /*X*/thr_in[] = -(convert(8,0) -1024 + atickoff[5]); /IY*/thr_in[2] = -(convert(6,0) -1024 + stickoff[3]); /*Z*/thr_in[3] = -(convert(O09) -1024 + stickoff[2]); /*P*/thr_in[4] = -(onvert(0,10) - 1024 + stickoff[1]); /*R*/thr_in[5] = (convert(0,8) -1024 + stickoff[O]); /*Y*/trim_tnust(thr_in,thr_out);for (i = 0; i < 6; i++)
{scrrowcol(5 + i,15);printf("%04x %04x",thr_in[i],throut[i]);
106
-------------------- /
trimmnenu()
scrdr();scr rowcol(2,0);printf(" M.I.T. SSLan");prinf(" Beam Assembly Teleperator\n\n");printf(" Thruster Adjustmentn\n");printfI" 1. LOAD FROM FILEn ");printf(" 2. SAVE TO FILEn");printf(" 3. SET VALUE IN MATRIXn");printf(" 4. DISPLAY MATRIXDn");printf(" 5. TRIM JOYSTICKS w/POTS\n");printf(" 6. SHOW JOYSTICK TRIMn");printf(" O. EXITn");scrrowcol(22,0);printf(" EnterSelection ");retun(0);
/*--------------------*/trimselect()
int query;
trinmrnu ;scr_rowcol(22,19);prin" ");scrrowcol(22,19);scanf("%d",&query);retun(query);}
/*--------------------*/loadtrim()
int i, k, fchar fnare[20];
print" Load filenam [.TDT: ");scan("%gn",fane);strcat(fam,".TDT");if ((fn = open(fnam-,0)) =-1)
scrrowcol(22,0);/* beep(25); */printf("ERROR in loading");/* pause(250); */
else
for (i = 0; i < 6; i++)
for (k = 0;k< 6;k++)fscanf(ffn,"%f ",&a[i][k]);
fscanf(fnn");
close(fin);
returnm();
/* --------------------*/save_trim()
int fn, i k;char fnaen[201;
printf(" Write filename [.TDT]: ");scanf("%s\n,fiamc);strcat(finani,".TDT");if ((fn creat(fnarnm)) = -1)
{scrrowcol(0,0);/* beep(25); */printf("Unable to Write File");/* pause(250); */
else
for (i = 0; i < 6; i++)
for (k = 0; k <6; k++)fprintf(fn,"%97.f ",a[il[k]);
fprintf(fn'n");}
close(fn);
calc_boost(jc,jp,tb)int jc[5], jp[5], tb[6];
107
float comtht[5], postht[5], xcyczc, xp,yp,zp;int zero;exiem float boost_x, boosty, boost_z;
zero = 0;enc2tht(jc,comtht);bat_for(comtht,&xc,&yc,&zc)enc2tht(jp,postht);bat_for(postht,&xp,&yp,&zp);tb[0] = (int) (boostjx * (xp -xc));tb[l] = (int) (boost y * (yp -yc));tb[2] = (int) (boostz * (zp- zc));tb[3] = zero;tb[41 = zero;tb[5] =zero;}/* =========================.===
batfor(tx,y,z)float t[5];float *x, *y, *z;
float cl, sl, c2, s2, c3, s3, c23, s23, c4, s4;extem float 11,12,13;
cl = eos(t[0]);sl = sin(t[01);c2 = cos(t[l]);s2 = sin(t[1]);c3 = cos(t[2]);s3 = sin(t[21);c4 = cos(t[3]);s4 = sin(t[3]);c23 = c2 * c3 -s2 s3;s23 = s2 * c3 + c2 s3;
·x =ll*cl*c2+ 12*cl*c23 + 13*(cl*c23*c4 -sl*s4);y =11'slc2 + 12*sl*c23 + 13*(sl*c23*c4 + cls4);z = 11 s2 + 12*s23 + 13*s23*c4;
/* ======================= *1float 11 = 16.0;float 12 = 14.1;floatl3= 3.5;
int shyoff= 1692;int shpoff= -3760;intelboff= -12656;intwraoff= 2992;int wrboff= -3925;float shy2thl = 6.41e-5;float shp2th2 = 4.80e-5;:float elb2th3 = -6.00e-5;float wry2th4 = 4.80e-5;float wrr2th5 = 5.15e-5;
enc2tht(enc,tht)int enc[5]; /* wra,wrb,elb,shy,shp */float tht[5]; /* shy,shpelb,wry,wrr */
Iint i, wra, wrb;
wra = enc[0] + wraoff;wrb =enc[l] + wrboff;tht[0] = shy2thl * (float) (enc[3] + shyoff);tht[l] = shp2th2 * (float) (enc[4] + shpoff);tht[2] = elb2tb3 * (float) (enc[2] + elboff);tht[3] = wry2th4 * (float) (wra - wrb);tht[4] = wrr2th5 * (float) (wra + wrb);
float boostx, boost_y, boostz;setboost
extem float boostx, boost_y, boost_z;char ch;float val;
scrclr0;scrrjowcol(5,0);printf(" CURRENT BOOST GAINS: X %5.1fn",boostx);printf(" Y %5.1 in"boost_y);printf(" Z %5.lfn",boostz);printf('n ENTER NEW BOOST GAIN LIKE THISn");printf(" x ff.f[CR] x = {X,Y,Z)\n ?");scanf("%c %fn",&ch,&val);ch = toupper(ch);switch (ch)
case 'X:
108
/* DATERS.C -Data logging andtiming functionsFunctions:
t/ statlog() logchar()PL index_log() logcharaOt" logint( logfoat()/* logintaO logfloata
/"t ~ dumplog()/jpL John Spofford June, 1985, Jan 1986
/* revised July 1987 DEA V#include "DATH" /* data defs */#include "PORTNUMS.HW#define INSIZE 18000#define CHSIZE 8#define FLSIZE 2#define GRPSIZE 6000
char l_index[TAGSIZE] = {"@IAlndx "};char keep[MAXGRPNUM]; /* init to FALSE */
static char *data_nanm[MAXGRPNUM;static char grp_size[MAXGRPNUM];static char data_type[MAXGRPNUM];static char logflag[MAXGRPNUM; ];/* init to FALSE */
static int recdcnt;int intstor[INSIZE];static int *impnt;float floamstor[FLSIZE];static float *floatpnt;char charstor[CHSIZE];static char *charpnt;char grpstor[GRPSIZE];static char *grppnt;
setdata0 /* set data logging /
int sel;
while (TRUE)
sel = datarenu();switch (sel)
case 1:startlog0;hrea,
case 2savedataO;
case 3:select_kp0;break
case 4:durmplog();while (!scrcsts()); /* wait for kcb-ea
casc 5:debuglog();while (!scr_cstsO()); /* wait for kebmak
case 0:retum(TRUE);beak
defaultcoC7); /* beep */
/*====== ==========--== '===*/selectkeep()
int sel;
while (TRUE)
sl =keep_mjnu();if((sel < 0) 11 (sel > MAXGRPNUM))
co(7);continue;
if(sel = 0)retum(TRUE);
keep[sel]= !keep[sel];
dr=================================datamenu()
1/
~1a'~1'
5/
a'1~~~~~~~~~~a'~~~~~~~~~'a'~~~~~~~~~':rsion 6.2 */
trsion 6.2 */
=*1
110
Iint query;
scrdrO;scr_rowcol(2,0);printf(" M.I.T. SSL\n");printf(" Beam Assembly Teleoperator\n);printf(" Data Recording Function\n");printf(" 1. INITIALIZE DATA STORAGESn");printf(" 2. SAVE DATA TO FILEn");printf(" 3. SELECT VARIABLES TO RECORD\n");printf(" 4. DISPLAY DATA LOG ON SCREEN\n");printf(" 5. debug data log\n");printf(" 0. EXrln\n");printf(" Enter Selection ");scanf("%dsn,&query);retumrn(quory);
keepmenu()
int query;char kp[MAXGRPNUM];
for (query = 0; query < MAXGRPNUM; query++)if(keepfquery])
kp[query] = ';else
kp[query]= '-';scr_dr();scrrowcol(2,0);printf(" MIT SSL BAT'n");printi(" Data Recording FunctinnaXn");printf(" Variable Selection\n);pritf("[%c] 1 LOOP COUNTER [%c]11 JC MEAS POS n",kp[ l],kp[l 11);printf"[%c] 2JOYSTICKS [%c]12JC MEAS RATE \n"p[2]kp[12]);printf([%c] 3 THRUST COM [%c]13 JCCOM POS 'n",kp[3],kp[13]);printf([%c] 4 MASTER ARM [%c114 \n",kp[4,kp[14]);printf("[%c] 5 JOINT COM [%c]15 \n",kp[5],kp[151);printf("[%c] 6JOINTPOS [%c]16 \n"Jcp[6],kp[163);printf"[%c] 7 Z80LOOP [%c]17 \n",kp7].kp[17?);printf("[%c] 8 ARM DUTY CYC [%c]18 \n"k8]p[8]p[18]);printf("[%c] 9 [%c]19 \n",kp[9],kp[191);printf("[%c]10 \n\n",kp[10]);printf(" 0 -EXlTN\n");printi" Enter Selection ");scanf("%d'n",&query);return(query);
/*--------------------*/save_data()
char fname[20];int i, j, siz, fn;int grplogcnt;char ans, grp, frmt[20];int *indmnpt = intstor;float *fldpt = floatstor;char *chdpt = charstor;
printf(" Write filenanme [DAT]: ");scanf"%sn",fiamm);strcat(fnamn,".DAT");if((f = creat(fnamn)) = -1)
scrrowcol(0,0);beep(25);printf("Unable to Write File");pause(250);
else
fprintf( fn,'"%s\"'n" ,fname);for (grp = 0; grp < MAXGRPNUM; grp++)
if(ogflag[grp])
fprintf(fn,'n\"%d %s ",grp,datajname[grp]);fprintf(fn," %c %d"",data_type[grpl,grpsize[grp]);
fprintf(fn'- -);grplogcnt = grppnt -grpstor; /* # entries in group store */for (i = 0; i < grplogcnt; i++)
grp = grpstor[i];siz = grp_size[grp];fprintf(fn,"\n%d:",grp);switch (data_type[grp])
caseFLDAT: /* float store */for (j =0;j < siz;j++)
fprintf(fn," %e",*fldmpt++);breal
111
case INDAT: /* int store /for (j = 0; j < siz; j++)
fprintf( fn," %d",*indmpt++);
case CHDAT: /* char store */for ( = ; j < siz; j++)
fprintf(fn," %d",*chdmpt++);beak;
defaultprintf("datatype[%d] =%d ERROR",grp,data_type[grp]);
}
close(fn);
/* ===...============================--=start-log(
iti;
intpnt = intstor;floatpnt = floatstor;charprt = charstor;grppnt = grpstor,for (i = 0; i < MAXGRPNUM; i++)
logflag[i] = FALSE;recdcnt = 0;
indxlog()
logint(lindx,++recdcnt);
logint(tag,var)int var;char tag[];
char grp;exem char data_flag;
grp = tag[0] - '@';if (!log_lag[grp])
logflag[grp] = TRUE;datatyp[grp] =tag[Ill;grp_size[grp] = tag[2] - '@';datanae[grp] = &tag[3];
if (tag[1] != INMDAT)printf("\n** Wrong type to logint '***a);
if ((GRPSIZE - 1) >= (grppnt - grpstor))if ((INSIZE -1) >= (ipnt - intstor))
*grppnt++ = grp;*intpnt++ = var;
else
else
scr_rowcol(24,0); scrcrl0;printf("**a INT STORAGE OVERFLOW **);data_flag = FALSE;screen2();
scrrowcol(24,0); scr_clrl);printf("*** GRP STORAGE OVERFLOW **");data-flag = FALSE;scren2(0;I
…/- -=-= = -/
loginta(tag,var)int var[];char tag[];
int i, dim;char grp;extem char dataflag;
grp = tag[] - '';if (!logflag[grp])
logflag[grp] = TRUE;datatype[grp] = tag[1];grp_size[grp] = tag[2] - '';data name[grp] = &tag[3];
112
}
if(tag[ll] =INDAT)printf('n*** Wrong type to logint_a ***n");
dim = tag[2] - '@';if ((GRPSIZE- 1) >= (grppnt - grpstor))
if ((INSIZE -dim) >= (intpnt - intstor))
*grppnt++ = grp;for (i = 0; i < dim; i++)
*intplt++ =var[i];
else{scr_rowcol(24,0); scrdrlrO;prinf("*** INT STORAGE OVERFLOW ***");dataflag = FALSE;scen2();
else
scrrowcol(24,0); scrdcrl0;printf("*** GRP STORAGE OVERFLOW ***");dataflag = FALSE;screen2(0;
/* .============================ = .===logchar(tag,var)char var,char tag[];
char grp;extem dar data_flag;
grp = tag[0] - '@';if (logflag[grp])
logflag[grp] =TRUE;datatype[grp] = tag[l];grp_size[grp] = tag[2] - '@';dataarsm[grp] = &tag[3];
if(tag[l] != CHDAT)printf("an*** Wrong type to logchar ***\n");
if ((GRPSIE - 1) >= (grppnt - grpstor))if ((CHSIZE - 1) >= (charpnt -charstor))
*grppnt++ = grp;*charapt++ = var;
else{scrrowcol(24,0); scrdrlO;print"*** CHAR STORAGE OVERFLOW ***");dataflag = FALSE;scren2(;
else
scrowcol(24,0); scrdrl0;printf("*** GRP STORAGE OVERFLOW ***");data_flag = FALSE;screon2();
logchar_a(tag,var)char var[];char tag[];
int i, dim;char grp;extem char data-flag;
grp = tag0] - '@';if (!logflag[grp])
log_flag[grp] = TRUE;datatype[grp] = tag[1];grpsize[grp] = tag[2] - '@';datarnergrp] = &tag[3];
if(tag[l] != CHDAT)printf(n*** Wrong type to logchar ***");
din = tag[2] -'@';if ((GRPSIZE - 1) >= (grppnt - grpstor))
if ((CHSIZE -dim) >= (charpnt -charstor))
*grppnt++ = grp;for (i = 0; i < dim; i++)
113
*charpnt++ = var[i];
elsc{scrrowcol(24,0); scrdclrl0;printf("*** CHAR STORAGE OVERFLOW ***");dataiflag = FALSE;
cid ~s 2(scclse
scr_rowcol(24,0); scrclrO;printif"*** GRP STORAGE OVERFLOW ***");dataflag = FALSE;screen20;
logfloat(tag,var)float var;char tag[];
char grp;extem char data-flag;
grp = tag[0] - '@';if(!log_flag[grpl)
logflag[grp] =TRUE;datatype[grp] = tag[l];grp_sizc[grp] = tag[2] - '@';datalaon[grp] = &tag[3];
if(tag[1] != FLDAT)printf('n*** Wrong type to logfloat **\n");
if ((GRPSIZE - 1) >= (grppnt - grpstor))if ((FLSIZE -1) >= (floatpnt - floatstor))
*grppnt++ = grp;*floatpnrt++ = var;
else
scrrowcol(24,0); scrdrl0;printf"*** FLOAT STORAGE OVERFLOW ***");dataflag = FALSE;screen();
else
scrrowcol(24,0); scr_clrl0;printf("*** GRP STORAGE OVERFLOW ***");dataflag = FALSE;scren2(;
logfloat_a(tag,var)float var[];char tag[];
{int i, dim;char grp;cxtem char dataflag;
grp = tag[0] - '@';if(!logflag[grp])
logflag[grp] = TRUE;datatypc[grp] = tag[1];grpsize[grp = tag[2] - '@';data_na[grp] = &tag[3];
if(tag[l] != FLDAT)printf(%n*** Wrong type to logfloat **n");
dim = tag[2] - '@';if ((GRPSIZE - 1) >= (grppnt -grpstor))
if ((FLSIZE -dim) >= (floatpnt -floatstor))
*grppnt++ = grp;for (i = 0; i < dim; i++)
*floatpnt++ = var[i];
else
scr rowcol(24,0); scrdrlO;printf("*** FLOAT STORAGE OVERFLOW ***");data_flag = FALSE;screen20;
114
else
scr rowcol(24,0); scr_dl();printf*** GRP STORAGE OVERFLOW ***");dataflag = FALSE;screoan2(;
/* ============-=__=======/bailout(errstr)char *enstr;
printf(errstr);exit(2);
dupJog()
inti, j, siz;int grplogcnt;char ans, grp, fmt[20];int *indmpt = intstor.float *fldmpt = foatstor;char *chdmrpt = charstor;
printf('nDisplay data log verbose? (Y/N): ")ans = getchar();if (ars = 'y')
ans = 'Y';printf(nHit any key to stop\n");grplogcnt = grppnt - grpstor; /* # entries in group store */for (i =0; i < grplogcnt; i++)
{grp = grpstor[i];siz = grp_size[grp];j=O; /* copy format string *if (ans 'Y')
printf("'n%s: ",data
_nam
c [grp]);
elseprintf("n9td:",grp);
switch (data type[grp]){case FIDAT: /* float store */
for (j = 0; j < siz; j++)pritf(" %e",*fldmpt++);
brealgcase INDAT: /* int store */
for (j = 0; j < siz; j++)printf(" %d',*indmpt++);
breakcase CHDAT: /* char store */
for (j = 0;j < siz; j++)printf( %d",*chdmpt++);
breakdefault
printf("datatype[d %d] = %d ERROR",grp,data_type[grp]);
if(scrcsts())break;
printf"Dump complet\n");
/* ==============================-.==debuglog()
int indpth, fldpth, chdpth, grpdpth, i;
printf('CnDEBUG: recdcnt = %d",recdcnt);indpth = inpnt - intstor;fldpth = floatpnt -floatstor;chdpth = chalpnt - charstor;grpdpth = grppnt -grpstor,
printi"\nGRP: depth = %dsn",grpdpth);printf('\nCHR: depth = %&n",chdpth);printf('nlNT: depth = %dn",indpth);printf('nFLT: depth = %dn",fldpth);puts('\n--- GROUP -----\n");for (i = 0;i < gpdpth;i++)
printf("%d ,grpstor[i]);puts('Nn--- CHAR -----\n");for (i = 0;i < chdpth;i++)
printf("%d',charstor[i]);puts('\n- INT ----\n");for (i = 0;i < indpth;i++)
printf("%d ",intstor[i
]);
puts(\n--- FLOAT -----n");for (i = O;i < fldpth;i++)
printf("%e ,floatstor[i]);
115
/* TRIAD1.C -- Support Routine for Supervisory Control version 63** for the Beam Assembly Teleoperator October 1987** by David E. Anderson MIT Space Systems Laboratory**---........1...-........ --..-/* Compiler: Desmet C** - ---------- */
/* Triadl contains the Triad access menu for setting up files to be played** back or files to be learned
#include "PORTNUMS.H"#include "DAT.H"/*Triad selection menu. *triacd()
char notdone, query;char fname[15];extem int funelspeed;extem char triadfn[10][15], triad_data;extem char data_flag; /* world data flag */extem int settriad;int i, f, j;not_done = TRUE;settriad = 0; /* default Triad inactive */funnelspeed = 0x100; /*default funnel speed. *//* (Funnel() moves the arm from where it is to where the file to be played ** back starts out )*/scr_clr); print out menu */scr_rowcol(O,);printf("%cc%cc%c%c%cc%c%c%cc",201,205,205,205,205,205,205,205,205,205,187);printi" %c %c\n",186,186);printf(" %c TRIAD %c\n",186,186);printf("%c%c%c%c%c%c%c%c% c%c%c%c%c%c%c%cc%c% c%c%c%c%c%c%c%c%c%c%ccc",201 ,205,205,205,205,205,205,205,205,205,205,205,205,188,200,205,205
205,205,205,205,205,205,205,205,205,20505,205,187);printf(" %c %c",186,186);printf(" %c SUPERVISORY CONTROL ALGORITHM %c",186,186);printf(" %c %c",186,186);printf("%c%c% c%c%c%c%c%c%c%cc%cc%cc c%c%c%c%c%c%c%c%c% cc%c%cc% c%c%c%c%c%cc%cn",200,205,205.205.205,205,205,205,205,
205,205,205,205,205,205,205,205,205.205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,188);
printf(" 1. Select File(s) for Playbaclin");printf(" 2. Set Up to Lear\n");printf(" 3. Full EASE Constructionmn");printf(" 0. Exit/TumoffTriad");while(not_dom) /* begin menu reading loop */
srrowcol(15,5);scanf("%c",&query); /* look for menu request */switch(query)
case '1': /* set up a file for play back */scrrowcol(15,0);printf("Set funnel speed [in hex]: ");scanf("%x",&funnel_speed); /* look for funnel speed */scrrowcol(15,26);printf(" %4x ",funne_speed); /* confirm funnel speed */scrrowcol(16,5);printf("Data? [y/n]: "); /* ask for data flag */triad_data = getchar);if(triaddata = 'y') triad_data = TRUE;else triad_data = FALSE;scr_rowcol(l7,5);printf("SELECT FILE [.TRDI:");for(i=0;notdone;i++)
{ / playback filename procurmnt loop */scr_rowcol(18+i,0);printf(" ->");gets(triadfitil);strcat(triadfn[i],".TRD");if(triadfn[i][0] '0)
strcpy(triadfn[i], "0");not done = FALSE;
scrrowcol(l8+i,5);printf("%s".triadfn[i]);
set_riad = 1; / activate Triad Playback mode */break;
case '2: /* enter learn mode set up */Ieamrn_stup();notdone = FALSE;bnak;
case '3': /* set up for full forward assembly */strcpy(triadfr[0], "grabbeamtrd");strcpy(triadfn[l ], "joint.trd");strcpy(triadfn[2], "grabslv.trd");strcpy(triadfn[3], "slideslv.trd");strcpy(triadfn[4], "stow.trd");strcpy(triadfn[5], "0");set_triad = 1; /* activate Triad Playback mode */notdone = FALSE;break;
117
case : /* exit */not_done = FALSE;break;
default: /* unrccognized command */scrrowcol(15,5);printf("MUDPIE command, try again");pause(250);scr_rowcol(15,5);printf(" ");b-*l
** Leam_set_up() saves a filenamn to save a learrnd trajectory to.* --------------- -----------------------
char fnamcr[15];leamsetup(
extern int settriad;extem char learning;extem char fnamer[15];sct_triad = 2; /* activate Triad ready to learn mode */scr_rowcol(15,5);printf("Set storage file [.TRD] -> ");gcts(fnamer);strcat(fnamer,'.TRD ");}
1*------------------------** Learnam() is called by a button push. Lamr starts and stops the process of saving actual ann positions.~ ......................................................................./
int frtt;leam0
extem int fntt;extem int settriad;extem char finaer[15];extemjointpos[81;ifsetriad=2) /* iffTriad in ready to learn mode active */
if((fnt = creat(famer)) = -1) /* make a new trajectory file */
scr rowcol(19,24);printf("Carnnot learn");beep(25);pause(150);scrrowcol(19,24);printf(" ");
else
set_triad = 3; /* activate Triad learn mode so save trajectory */scr_rowcol(19,24);print("Learing");
else /* if Triad leaving loam mode */{ /* save another command with EOF cod */
fprintf(fntt,"%4x %4x %4x %4 %4x Hn\n",joinLpos[O], jointpos[l, jointpos[2], joint_pos[3], joint_pos[4]);close(fntt); /* dose trajectory file */set_triad = 2; /* set to Triad ready to leam mode */scrrowcol(19,24);printf(" "); /* tun off learning sign */
P*-------------------------------------------------
** Lamrecord() is called once per Batsoft main loop. It saves the actual arm joint ** positions.
leam-record
extm int fntt;extem int jointLpos[8];fprinftf(fntt,"'4x %4x %4x % 4x %4x An", joint-pos[O], jointpos[1], joint_pos[2], jointpos[3]jointpos[4]);}
118
APPENDIX II. JCS code
; Z80 code for the JCS joint cards. Each Z80 controls two jointspage 60,132title BAT JOINT CONTROL CARD (w/DPR) Jlu.asm 8/4/87page 60,132* **** * ******** *********
Downloaded code for JC cardsuses dual-port RAM (DPR) for commands & data
;*********************************************by John Spofford, Tom Waschura, & David E. AndersonMIT Space Systems Laboratory
includeincludeinclude
zg0.macz80_math.macjoint.mac
;--------------------------------------MACROS START
macro b, reg, labelbit b, regjpc nz, labelendm
;--------------------------------------MACROS END
;---Set up all I/O Port Definitions
pio2a_datapio2a_cntlpio2b_datapio2b_cntlctc0ctclctc2ctc3pio3a_datapio3 a_cntlpio3b_datapio3b_cntl
;---Set up I/O
equ 4equ 5equ 6equ 7equ 8equ 9equ 10equ 11equ 12equ 13equ 14equ 15
related constants
bitmodebi_direc_modeinput_modeoutputmodeall_inputmaskall_output_maskinteruptctlno_interuptctlctc_vectorctc0_ctlctc 1 and2_ctltc_followsmin tc sizewaitcount
equequequequequequequequequ
equ OD7Hequequequequ
OCFH08FH04FHOOFHOFFH000H087H
007H010H ;%(LOW ctc_vectoraddr)
057H057H8OOAH ;for 10 ms loop should be 10
;---Set up Initial Value Constants for RAM Variables
dataram_lodataram_histack_topvar_page_size
equequequequ
0800hOBFFhdataram_hi + 0O100h
JPBIT
119
equequequequ
1000h17FDh1800h1FFFh
equ 1FFEhequ 1FFFhequ 1813hequ 1814hequ 189Ah
;see JRS labbook
;to PC;from PC
;---Define RAM
alpha_beta-ngain_nmultl_mult2_mult3_sigma_sign_nreferentheta_rcontro.
TCndelta_roldde]oolddtempitemplDstart_salgoritold_theoldcooold_ccdirecti(bits_2:n_abortinterrul
Variables (location, size and usage)
n
_n_n
n_n
ce_n
ln
ita_nelta_n
nignalhm_n
ta_nntrol_nontrol_nn_n
tptcnt
control algorithm coefficientcontrol algorithm coefficientcontrol algorithm coefficient
control algorithm coefficientintegrator on/off and integrator saturationintegrator multiplierintegration sum
present sign of error, used to reset sigma_nreference position indicated by IBM PCindicated position read from decoderscontrol signal outputted from controlalgorithm. (Note: not to be confusedwith TC_n)CTC time constanterror difference (reference - theta)OLD error differenceOld OLD error diference8 bit temporary RAM variable16 bit temporary RAM variablestart up FLAGcontrol algorithm selectionOLD indicated positionOLD control value
Old OLD control valuemotor direction indicatormulti-use port output byte
abort flagscount of CTC interrupt services
PID CONTROLLER:The PID compensator(control)/(error) = k1 + a/(z-1) + b(z-l)/(z+c)}+sigmawhere k is gain, a is (fake) integrator multiplier, b is differential mult.In batsoft, these are combined shifted to form a 0.16 fixed point binaryand sent to the dpr in the form of:
gain_nalpha_nbeta_nmultl_nmult2_n
mult3_nsigma_nsign_n
from_pc_vars
k(b+l) multiplier of error-k(a-l-c-2b) neg of mult of old errork(c-ac+b) mult of oold error
c mult of old controlupper byte: l=integrator on, 0=integrator off
lower byte: integrator saturationfraction multiple of each loop delta to add to sigmaintegrated sum. Upper byte added to control
keeps sign of delta. resets sigma when delta changes sign
START OF RAM DEFINITIONorg dataram_loequ $ ;order of variables is important!
120
coderam_locoderam_hidualram_lodualram_hi
to8088from8088wcjc_statuscomm_flag
==== == - -=========
reference_x, 2reference_y, 2gainx, 2
gain_y, 2 ;86alpha_x, 2alphay, 2beta_x, 2betay, 2algorithm_x, 1
algorithmy, 1predither_x, 2predither_y, 2postdither_x, 2 ;96post_dither_y, 2 ;98nothing, 2multl_x, 2multl_y, 2mult2_x, 2mult2_y, 2mult3_x, 2mult3_y, 2
$ ;order oftheta_x, 2thetay, 2rate_x, 2 ;ratey, 2calc_ctrl_x, 2calc_ctrl_y, 2 ;TC_x, 1TC_y, 1direction_x, 1 ;direction_y, 1 ;loop_counter, 3;
;80;82;84
;88;8A;8C;8E;90;91;92;94
;9A;9C;9E;AO;A2;A4;A6
variables is important!0002040608OA
;OC;OD
DEOF10
controlx, 2control_y, 2deltax, 2delta_.y, 2last_data_x, 2last_data_y, 2old_delta_x, 2old_delta_y, 2oold_delta_x, 2oold_delta_y, 2oold_control_x, 2oold_control_y, 2old_last_data_x, 2old_lastdata_y, 2vel_gain_x, 2
velgain_y, 2pos_gainx, 2pos_gainy, 2old_theta_x, 2oldthetay, 2old_control_x, 2
old_control_y, 2bits_2a, 1y_abort, 1x_abort, 1interruptcnt, 1tempO, 1temp_l, 1temp16_0, 2
defundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefun
to_pc_vars equdefundefundefundefundefundefundefundefundefundefundefun
defundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefundefun
121
defun templ6_1, 2defun status_2b, 1defun sigma x, 2defun sigma_y, 2defun sign_x, 1defun sign_y, 1IF $ GT dataramhi%out DATA RAM OVER-RUN!ENDIF
END OF RAM DEFINITION
-;__c__--- _== = -- ___ =----= ___-,-~==== -START OF Z80 CODEorg coderam_lojp beginroutine$org %(coderam_lo + 010H)
;---Place the Interupt VECTOR TABLE here, then jump to NMI service
ctc_vector_addr equ $dw ctcservicedw 00dw 00dw 00
$org %(coderam_lo + 30h)
;<<<<<<<<<<<<<<<<<<<<BEGIN MAIN CODE>>>>>>>>>>>>>>>>>>>>>>
;---Initialize all PIO's and the CTC
begin_routine equ $lri a, 'f' ;1/2/86 jrssta (to8088) ;free the PC
initpio %pio2a_cntl, %bitmode, %alloutputmask, %nointerupt_ctlinitpio %pio2b_cntl, %output_mode, 0, %nointerupt ctlinitpio %pio3a_cntl, %bitmode, %alLinputmask, %no_interupt_ctlinitpio %pio3b_cntl, %bitmode, %allinput_mask, %no_interuptctlinit_ctc %ctcO, %ctcO_ctl, ctc_vector, 0initctc %ctcl, %ctcland2_ctl, 0, 25init_ctc %ctc2, %ctcland2_ctl, 0, 25
;---Initialize CPU parameters
lrpi hl, stack_topIsphllri a, %(HIGH ctc_vector_addr)ldiaim2ei
;---Initialize both motor flip-flops OFF
lri a, 00000110B ;first set F-Flopsout pio2a_datalri a, 11100000Bout pio2a_datasta (bits_2a)lri a, tc_follows ;then reset them viaout ctcl ;the timers timing outout ctc2
122
lri a, 1out ctclout ctc2
;---Assuming the PC will not write to Joints until after initializing;---Initialize RAM Variables with their inital values
irpi hl, 0sthl (alpha_x)sthl (alpha_y)sthl (beta_x)sthl (beta_y)sthl (gain_x)sthl (gain y)sthl (reference_x)sthl (reference_y)sthl (theta_x)sthl (theta_y)sthl (ratex)sthl (ratey)sthl (controlx)sthl (controly)sthl (delta_x)sthl (delta_y)sthl (lastdata_x)sthl (lastdata_y)sthl (old_delta_x)sthl (old_delta_y)sthl (old_lastdata_x)sthl (old_lastdata_y)sthl (oldtheta_x)sthl (old_theta_y)sthl (old_control_x)sthl (old_controly)sthl (postdither_x)sthl (postdither_y)sthl (pre_dither_x)sthl (pre_dither_y)sthl (multl_x)sthl (multl_y)sthl (mult2_x)sthl (mult2_y)sthl (mult3_x)sthl (mult3_y)sthl (sigma_x)sthl (sigmay)sthl (loop_counter)sthl (oold_control_x)sthl (oold_control_y)sthl (oold_delta_x)sthl (oold_delta_y)
lri a, waitcountsta (wc)lri a, O0sta (TCx)sta (TCy)sta (direction_x)sta (directiony)sta (x_abort)sta (y_abort)sta (interruptcnt)sta (algorithm_x)sta (algorithm_y)
123
sta (sign_x)sta (sign_y)sta %(loop_counter+2)
;---Now that all is initialized & the motors;---for the start up code from the IBM PC.
lristaIdaandioutequ $Idacpijpc
a, 'W'(jc_status)(bits_2a)10111111Bpio2a_data
are OFF, sit and wait
;ready to go flag
;b6=0 --> not started
(comm_flag)'G' ;look for start flagnz, sit_and_wait
;---And we're off. Now we'll work on motor x first. Read the x;---position, and get a control_x based on the selected algorithm
equ $Ida (comm_flag)cpi 'S'jpc z, begin_routinelri a, 'C'sta (jc_status)
READ_THETA 0
;look for shutoff flag;reset;'controlling' flag
;O selects channel x
VMOV theta_x, templ6_0VNEG templ6_0VADD templ 6_0, reference_x, delta_x
;---Now check the algorithm type and dispatch accordingly
Idacpijpc
algorithm_x0nz, pd_algorithm_x
;---PROPORTIONAL CONTROL ALGORITHM
MULTIPLY gain_x, delta_x, control_xjp drain_x
;---PID CONTROL ALGORITHM
pd_algorithm_x equ $cpi 1jpc nz, SVC_algorithm_xMULTIPLY gain_x, delta_x, templ6_0VADD rate_x, templ6_0, control_x
jp drain_x
;---SVC CONTROL ALGORITHM
SVC_algorithm_xcpijpc
equ $2nz, OL_algorithm_x
MULTIPLY pos_gain_x, delta_x, control_xVMOV thetax, temp16_0
124
sit_and_wait
main_loop
VADD templ6_0, old_theta_x, templ6_0VADD control_x, templ6_0, controlxjp drain_x
;---OPEN LOOP CONTROLLER
OL_algorithm_x equ $MULTIPLY gainx, reference_x, controlx
;---Now filter the control value for saturation and direction
drain_x equ $VMOV control_x, calc_ctrl_x
filter x
; JOINT Y
READ_THETA 1
VMOV theta_y, templ6_0VNEG templ 6_0VADD templ6_0, reference_y, delta._y
;---Now check the algorithm type and dispatch accordingly
lda algorithm_ycpi 0jpc nz, pd_algorithmy
;--PROPORTIONAL CONTROL ALGORITHM
MULTIPLY gain.y, deltay, controlyjp drainy
;---PID CONTROL ALGORITHM
pd_algorithm_y equ $cpi 1jpc nz, SVC_algorithmyMULTIPLY gainy, delta_y, templ6_0VADD rate_y, templ6_0, control_y
jp drainy
;--SVC CONTROL ALGORITHM
SVC_algorithm_y equ $cpi 2jpc nz, OL_algorithm_y
MULTIPLY pos_gain_y, deltay, control_yVMOV theta_y, templ6_0VADD templ6_0, old_theta_y, templ6_0VADD control_y, templ6_0, control_yjp drain_y
;--OPEN LOOP CONTROLLER
OL_algorithm_y equ $MULTIPLY gain y, reference_y, controly
125
;---Now filter the control value for saturation and direction
drain._y equ $VMOV controly, calcctrl_yfilter y
;PRECALCULATE VALUES FOR NEXT LOOP if PID Controller used.
; this updates the state variables for the algorithms that; need them.
lda algorithm_xcpi 1jpc nz, try_y_l
; update x variablesVMOV old_delta_x, oold_delta_xVMOV delta_x, old_delta_xVMOV old_control_x, oold_control_xVMOV theta_x, old_theta_xVMOV controlx, old_control_x
; precalculate for PID controller for joint x
MULTIPLY multl_x, old_control_x, templ6_0MULTIPLY alpha_x, old_deltax, templ6_1VNEG templ6_1VADD templ6_0, templ6_1, templ6_1MULTIPLY beta_x, oold_deltax, templ6_0VADD templ6_0, templ6_1, rate_xMULTIPLY mult3_x, old._delta_x, templ6_0VADD templ6_0, sigma_x, sigma_x
; reset for the PID: mult2 is an on off switch
ldhl mult2_xbit 0,h ;if bit is set (z not set) then gojpc nz,xxxlri h,0lri 1,0sthl (sigma_x)
xxx equ $
; if the sign delta changes, reset sigma
ldhl old_delta_xbit 7, h ;check sign of errorjpc z, psign_x ;error is negativeIda sign_xbit 0, a ;if bit 0 not set, reset sigmajpc nz, norstxlri h, 0lri 1, 0sthl %(sigma_x)lri a, 0 ;delta now positive, change signsta (sign_x)jp norst_x
psign_x equ $Ida sign_x ;if bit 0 of a is set, reset sigmabit 0, ajpc z, norst_xlri h, 0
126
lri 1, 0sthl %(sigma_x)lri a, 1sta (sign_x)equ $norst_x
;clip sigma if necessaryIdrpidhlbitjpcldnegcpjpcldlriip
nbad_x equldlristrpldIriip
pos_x equldcpjpcldlriJP
pbad_x equldlristrpldri
good_x equstrpVADD
try_y_l
; update y variables
de, sigma_xmult2_x7, dz, posxa, 1
d ;if a>d, bad, carry not setnc, nbad_xe, dd, OFFhgood_x
d, ae, 0de, %(sigma_x)e, dd, OFFhgood_x$a, 1d ;if d> a, badcar, pbad_xe, dd, 0good_x$d, ae, 0de, %(sigma_x)e, dd, 0$de, %(templ6_0)templ6_0, rate_x, rate_x
equIdacpijpc
VMOVVMOVVMOVVMOVVMOV
carry set
$algorithm_y1nz, try_x_SVC
old_delta_y, oold_delta_ydelta_y, old_delta_yold_control_y, oold_control_ythetay, old_theta_ycontrol_y, old_control_y
; precalculate for PID controller for joint y
MULTIPLY multl_y, old_control y, templ6_0MULTIPLY alpha_y, old_delta_y, templ6_1VNEG templ6_1VADD templ6_0, templ6_1, templ6_lMULTIPLY beta_y, oold_deltay, templ 6_0VADD templ6_0, templ6_1, rate_yMULTIPLY mult3_y, old_delta_y, temp16_0VADD templ6_0, sigma_y, sigma_y
127
; reset for the PID: mult2
ldhl mult2_ybit O,hjpc nz,yyy
;if bit is set (z not set) then go
lri h,Olri 1,0sthl (sigmay)equ $
; if the sign delta changes, reset sigma
ldhlbitjpcIdabitjpclrilristhllristaJP
psign_yIdabitjpclrilristhllrista
norsty equ; clip sigma if necessary
ldrpldhlbitjpcldnegcpjpcldlriip
nbad_y equldlristrpldlriip
pos_y equldcpjpcldlriip
pbad_y equldlri
old_delta_y7, h ;check sign of errorz, psign_ysign_y0, anz, norst_yh, 01, 0%(sigma_y)a, 0(sign_y)norstyequ $sign_y ;if bit0, az, norstyh, 01, 0%(sigma_y)a, 1(sign_y)$
;error is negative
;if bit 0 not set, reset sigma
;delta now positive, change sign
0 of a is set, reset sigma
de, sigma_ymult2_y7, dz, pos ya, 1
d ;if a>d, bad, carry not setnc, nbad_ye, dd, OFFhgood_y$d, ae, 0de, %(sigma_y)e, dd, OFFhgood_y
a, 1d ;if d> a, badcar, pbad_ye, dd, 0good_y$d, ae, 0
carry set
128
YYY
is an on off switch
strpIdlriequstrpVADD
de, %(sigmay)e, dd, 0$de, %(templ6_0)temp160, ratey, ratey
; precalcualate for SFC controller
try_x_SVC equ $Ida algorithmxcpi 2jpc nz, tryySVC
equIdacpijpcnop
$algorithmy2nz, end_precalcs
endprecalcs equ $;-------------------------------------------------------; check for new info from PCcheck_new equ $
Ida (from8088)cpi 'N' ;new info flagjpc nz, dont readlri a, 'R' ;reading flagsta (from8088)irpi be, 28h ;setup for dirirpi hi, %(dualramo + 80h) ;from pc areairpi de, from_pcvarsidirlri a, 'O' ;info has been read flagsta (from8088)jp transfer
dont-read equ $cpi 'U' ;info being updated flag;do nothing, get it next time
; send data to PCtransfer
donetalking
equ $Idacpijpclristairpiirpiirpiidirlristaequ
(to8088)'R' ;currently beingz, done_talkinga, 'U' ;updating flag(to8088)bc, 13h ;setup for dirhi, to_pcvarsde, %(dualramo + 0)
read flag;next time..
;to pc area
a, 'N' ;new data available flag(to8088)$
;-------------------------------------------------------;now wait for interruptcount to get to wait_count. This will permit;a 10 ms calculation loop.
;--- set pio2-a7 zero while waitingIdares
(bits_2a)7, a ;b7=0 --> waiting
129
goody
;tryySVC
staout
;---here in wait loop, increase loopIrpilriaddmstrmlriincrpadcmstrmlriincrpadcmstrm
;---the looplri
wait_here equIdacpjpc
;---leaving loop, reset count and st;lristaIdasetstaJP
(bits_2a)pio2a_data
count:hl,(loop_counter)a, 1 ;increment value = 1
;first byteaa, 0 ;zero for carryhl
;second..aa, 0 ;zero for carryhl
;last bytea
b, wait_count
(interrupt_cnt)bnz, waithere
atus bit:a, 0(interrupt_cnt)(bits_2a)7, a(bits_2a)main_loop
;b7=1 --> done waiting
; This is the CTC interrupt service routine:
This routine is designed to have fast response between thepulse start signal and the timer start signals. The fastestthis can be done is in 34 cycles (@ 2 MHz = .017 ms). TheCTC counts every .004 ms, so the smallest count I can accuratelyrepresent is 5 (i.e. 4.25), hence if the tc_n is less than
; 5, it is ignored, & then it is decreased by 4.and if you understand that, congratulations!
equ $save_state
idaincsta
(interrupt_cnt)a(interrupt_cnt)
(tc_x)b, aa, 0bz, no_pulsetcO(x_abort)O, anz, no_pulse_tcOa, ctcland2_ctlctc 1(bits_2a)1, apio2a_data1, a
;check for small
;shut it down
;start pulse
130
ctc_service
daldlricpjpcIdabitjpclrioutIdasetoutres
·******%********************************
out pio2a_dataId a, bout ctcl
equ $ida (tc_y)Id b, alri a, O0cp bjpc z, no_pulse_tclIda (y_abort)bit 0, ajpc nz, no_pulse_tcllri a, ctcland2_ctlout ctc2Ida (bits_2a)set 2, aout pio2a_datares 2, aout pio2a_dataid a, bout ctc2
;shut 'em down
;start pulse
equ $
restore_stateeireti
; Multiply Subroutine (called by MULTIPLY macro)
multsub equ $Irpi hl, 0irpc x, <BC>irp numb, <7,6,5,4,3,2,1,0>
mugen x, numbendm
endmret
IF $ GT coderam_hi%OUT CODE EXCEEDS RAM LIMIT!ENDIF
end
131
no_pulse_tc0
no_pulse_tc 1
APPENDIX IV. Triad trajectories
Grabbeam.trd: 3/17/88Start at stow, extend beam carrier, grab the beamwith the right claw, retract beam carrier
28F4 5084 4F0 4BC0 DE8028F4 5084 432 4C76 DE3228F4 5084 374 4D2C DDE428F4 5084 2B6 4DE2 DD9628F4 5084 1F8 4E98 DD4828F4 5084 13A 4F4E DCFA28F4 5084 07C 5004 DCAC28F4 5084 FFBE 50BA DC5E28F4 5084 FF00 5170 DC1028F4 5084 FE42 5226 DBC228F4 5084 FD80 52E0 DB7428F4 5084 FC73 52E0 DB2628F4 5084 FB66 52E0 DAD828F4 5084 FA59 52E0 DA8A28F4 5084 F94C 52E0 DA3C28F4 5084 F83F 52E0 D9EE28F4 5084 F732 52E0 D9AO28F4 5084 F625 52E0 D95228F4 5084 F518 52E0 D90428F4 5084 F40B 52E0 D8B628F4 5084 F2FE 52E0 D86828F4 5084 FIF0 52E0 D8102A842C842E84308432843484368438843A843C843E84408442844484468448844A844C844E84508452845484568458845884588458845884
4E444C444A444844464444444244414441444144414441444144414441444144414441444144414441444144414441444144414441444144
FiFOFiFOFiF0F1F0FiFOF1F0F1F0F1F0FiFOFiFOF1F0FIF0F1F0FiF0F1F0F1F0F1F0F1F0FiFOFiF0F1F0F1F0FiF0FiFO
FiFOF1FOF1F0F1F0
50CD4EBA4CA74A9 4
4881466E445B424840353E223COF39FC37E935D633C33lB0
2F9D2D8A2B7729642751253E232B21181F051CF21ADF18CC
-- Open right claw-- Extend beam carrier
-- Right arm clear of stow handle
-- Right arm clear of left arm-- Load Triad2 gains
D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810
132
. E .
5884 4144 F1FO 16B9 D810 A -- Shy and wrist in position for grab5884 4144 F2F0 15CO D030 T -- Wait for beam carrier to settle5884 4144 F3B0 15CO D030 T5884 4144 F3BO 15CO D030 T5884 4144 F3B0 15C0 D030 N -- Load Triadl gains5884 4144 F46B 15C0 DOBC T5884 4144 F526 15CO D148 A5884 4144 F5E1 15CO D1D4 A5884 4144 F69C 15CO D260 A5884 4144 F757 15CO D2EC A5884 4144 F812 15C0 D378 A5884 4144 F8CD 15C0 D404 A5884 4144 F988 15C0 D490 A5884 4144 FA43 15CO D51C A5884 4144 FAFE 15C0 D5A8 A5884 4144 FBB9 15CO D634 A5884 4144 FC74 15CO D6C0 A5884 4144 FD2F 15C0 D74C A5884 4144 FDEA 15C0 D7D8 A5884 4144 FEA5 15CO D864 A5884 4144 FF60 15CO D8FO A5884 4144 1B 15CO D97C A5884 4144 D6 15CO DA08 A5884 4144 191 15C0 DA94 A5884 4144 24C 15C0 DB20 A5884 4144 307 15C0 DBAC A5884 4144 310 15C0 DBCO E -- Close right claw on beam5884 4144 310 15C0 DD40 F -- Open beam carrier claw5884 4144 310 15CO DD40 U -- Short pause while claw opens5884 4144 310 15CO DD40 L -- Retract beam carrier5884 4144 310 15C0 DD40 H -- End of File
133
Joint.trd: 3/17/88Start at grabbeam with beam.position beam for easy manualjoint assembly.
5584 4574 3B0 15C0 DD40 T -- Pause for beam to settle5584 4574 3D0 15C0 DD90 Q -- Load in heavy work gains5584 4574 3F0 15C0 DDEO A5584 4574 410 15C0 DE30 A5584 4574 430 15C0 DE80 A5584 4574 450 15C0 DEDO A5584 4574 470 15C0 DF20 A5584 4574 490 15C0 DF70 A5584 4574 4B0 15C0 DFCO A5584 4574 4D0 15C0 E010 A5584 4574 4F0 15C0 E060 A5584 4574 510 15C0 E100 A5584 4574 530 1620 E150 A5584 4574 550 16A0 E1AO A5584 4574 570 1720 ElFO A5584 4574 590 17A0 E240 A5584 4574 5BO 1820 E290 A5584 4574 5D0 18A0 E2EO A5584 4574 5F0 1920 E330 A5584 4574 610 19A0 E380 A5584 4574 638 1A20 E3D0 A5584 4574 660 1AAO E3EO T -- Pause for beam to settle5584 4574 660 1AAO E3EO H -- End of trajectory
134
Grabslv.trd: 3/17/88Start at just-made-joint, release beam,grab sleeve.
ACO 1AEO E430 DA16 1AEO E3A6 A96C 1AEO E31C A8C281876E6C461A5704C641C3722C821E174CA
1AE01AEO1AE01AE01AE01AE01AE01AEO1AE01AE01AEO1AE01AEO
--Open right claw
E292 AE208 AE17E AEOF4 AE06A ADFEO ADF56 ADECC ADE42 ADDB8 ADD2E ADCA4 ADC1A A
20 1AEO DB90 AFF76FECCFE22FD78FCCEFC24FB7AFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFACOFB5DFBFAFC97FD34FDD1FE6EFFOBFFA8
45
1AEO1AEO1AEO1AEO1AEO1AEO1AEO1AEO1BEOlC601CE01D601DEO1E601EEO1F601FEO206020E0216021EO0
226022E0236023EO0
246024E02500250025002500250025002500250025002500
DB06DA7CD9F2D968D8DED854D7CAD730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D730D7CED86CD90AD9A8DA46DAE4DB82DC20DCBE
--Claw clear of beam, load higher gains
--Claw on approach to sleeve, load low gains
135
5534 44545534 44545534 44545534553455345534553455345534553455345534553455345534
4454445444544454445444544454445444544454445444544454
5534 4454553455345534553455345534553455345484528450844E844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D844D84
4454445444544454445444544454445445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B445B4
4D84 45B4 E2 2500 DD5C A4D84 45B4 17F 2500 DDFA A4D84 45B4 21C 2500 DE98 A4D84 45B4 2B9 2500 DF36 A4D84 45B4 356 2500 DFD4 A4D84 45B4 3F3 2500 E072 A4D84 45B4 490 2500 Ell0 A4D84 45B4 52D 2500 E1AE A4D84 45B4 5CA 2500 E24C A4D84 45B4 667 2500 E2EA A4D84 45B4 704 2500 E388 A4D84 45B4 7A1 2500 E426 A4D84 45B4 83E 2500 E4C4 A4D84 45B4 8DB 2500 E562 A4D84 45B4 978 2500 E600 A4D84 45B4 A15 2500 E69E A4D84 45B4 AB2 2500 E73C A4D84 45B4 B4F 2500 E7DA A4D84 45B4 BEC 2500 E878 A4D84 45B4 C89 2500 E916 A4D84 45B4 D26 2500 E9B4 A4D84 45B4 DC3 2500 EA52 A4D84 45B4 E60 2500 EAFO A4D84 45B4 EFD 2500 EB8E A4D84 45B4 F9A 2500 EC2C A4D84 45B4 1050 2500 ECEO E --Close right claw4D84 45B4 1050 2500 ECEO H --End of file
136
Slideslv.trd: 3/17/88Start grabbing unslid sleeve. Slide it.
ECEO EECEO 7ECEO QED6C AEDF8 AEE84 AEF10 AEF9C AF028 AFOB4 AF140 AF1DO AF290 AF350 AF410 AF4DO AF590 AF650 AF710 AF7DO AF8FO AF8FO TF8FO NF8FO H
--Make sure claw is closed--Increase allowable position error--Load in heavy work gains
--Give Shy a kick and allow to settle--Reload normal gains--End of trajectory
137
4D844D844D844D044C844C044B844B044A844A0449844904481447144614451444144414441444144414441444144414
48144814481447D8479C4760472446E846AC4670463445F4467447744874497449744974497449744974497449744974
10501050105010A710FE115511AC1203125A12B11308136013FO1480151015A0163016C0175017E01850185018501850
250025002500256725CE2635269C2703276A27D1283828A02910298029FO2A602ADO2B402BBO2C202CCO32CO2CCO2CCO
-
Stow.trd: 3/17/88Start at slid sleeve and go to stow
1850 2CC0 F8FO D --Open right claw16EA 2CC0 F7AF A1584 2CC0 F66E A141E 2CC0 F52D A12B8 2CC0 F3EC A1152 2CC0 F2AB AFEC 2CC0 F16A AE86 2CC0 F029 AD20 2CC0 EEE8 ABBA 2CC0 EDA7 AA54 2CC0 EC66 A8EE 2CCO EB25 A788 2CC0 E9E4 A622 2CC0 E8A3 A4BC 2CC0 E762 A356 2CC0 E621 A1FO 2CC0 E4EO A8A 2CC0 E39F A
FF24 2CC0 E25E AFDBE 2CC0 EllD AFC58 2CC0 DFDC AFAF2 2CC0 DE9B AF98C 2CC0 DD5A AF826 2CC0 DC19 AF6C0 2CC0 DAD8 AF55A 2CC0 D997 A
4414 4974 F3F0 2CC0 D856 AF3FOF3FOF3FOF3FOF3FOF3F0F3FOF3FOF3F0F3FOF3FOF3FOF3FOF3FOF3FOF3F0F3FOF3FOF3F0F3FOF3FOF4A7F55EF615F6CCF783F83A
2CC0 D810
2F00 D8103100 D8103300 D8103500 D8103700 D8103900 D8103B00 D8103D00 D8103F00 D8104100 D8104300 D81044C4 D8104687 D810484A D8104AOD D8104BD0 D8104D93 D8104F56 D8105119 D81052E0 D81052E0 D81052E0 D81052E0 D81052E0 D81052E0 D81052E0 D810
25F4 5084 F8F1 52E0 D810 A
P --Claw is clear of beam, load higher gainsAAAAAAAAAAAAAAAAAAAN --On approach to stow handle, use low gainsAAAAAA
138
44144414441444144414441444144414441444144414441444144414441444144414441444144414441444144414441444144414
49744974497449744974497449744974497449744974497449744974497449744974497449744974497449744974497449744974
4414443C42A4410C3F743DDC3C443AAC3914377C35E4344C32B4311C2F842DEC2C542ABC292428FC27F426F425F425F425F425F425F4
49744A844B844C844D844E8C4F84508C5084508450845084508450845084508450845084508450845084508450845084508450845084
--Pause briefly on final approach to stow
--Call for slaverest at end of trajectory--Close right claw--End of trajectory
139
25F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F425F4
508450845084508450845084508450845084508450845084508450845084508450845084508450845084508450845084508450845084508450845084
F9A8FA5FFB16FBCDFC84FD3BFD80FDDAFE34FE8EFEE8FF42FF9CFFF6
50AA10415E1B821226C2C632037A3D442E4884F04F04F0
52E052E052E052E052E052E052E05280522051Co5160510050AO50404FE04F804F204EC04E604E004DAO4D404CEO4C804C204BCO4BCO4BC04BCO4BC0
D810 AD810 AD810 AD810 AD810 AD810 AD810 UD862 AD8B4 AD906 AD958 AD9AA AD9FC ADA4E ADA80 ADAF2 ADB44 ADB96 ADBE8 ADC3A ADC8C ADCDE ADD30 ADD82 ADDD4 ADE26 ADE80 ADE80 SDE80 EDE80 H
Cgrab.trd: 3/17/88Start at stow, grab cluster from rackand retract to running position, leave live.
4BC0 DE80 D --Open right claw4C76 DDB4 A4D2C DD4E A4DE2 DCE8 A4E98 DC82 A4F4E DC1C A5004 DBB6 A50BA DB50 A5170 DAEA A5226 DA80 A52E0 DAOO P --Clear of stow handle, load higher gains52E0 D966 A52E0 D8CC A52E0 D832 A52E0 D798 A52E0 D6FE A52E0 D664 A52E0 D5CA A52E0 D530 A52E0 D496 A52E0 D3FC A52E0 D360 A50CD D360 A4EBA D360 A4CA7 D360 A4A94 D360 A4881 D360 A466E D360 A445B D360 A4248 D360 A4035 D360 A3E22 D360 A3COF D360 A39FC D360 A37E9 D360 A35D6 D360 A33C3 D360 A31BO D360 A2F9D D360 A2D8A D360 A2B77 D360 A2964 D360 A2751 D360 A253E D360 A232B D360 A2118 D360 A1F05 D360 A1CF2 D360 A1ADF D360 A18CC D360 A16B9 D360 A14A6 D360 A1293 D360 A1080 D360 A
140
28F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F42AD42CD42ED430D432D434D436D438D43AD43CD43ED440D442D444D446D448D44AD44CD44ED450D452D454D456D458D45AD45CD45ED460D462D464D466D46894
50845084508450845084508450845084508450845084508450845084508450845084508450845084508450844E444C444A44484446444444425440543E543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C543C54
4F04323742B61F813A07C
FFBEFF00FE42FD80FC73FB66FA59F94CF83FF732F625F518F40BF2FEF1F0F1F0F1F0F1F0FiF0F1F0F1F0F1F0F1F0FiF0F1F0F1F0F1F0F1F0F1F0F1F0F1F0FiF0F1F0F1F0F1F0F1F0F1F0F1F0F1F0F1F0FiF0F1F0F1F0F1F0F1F0FiF0F1F0
3C54 F1FO3C54 FIFO3C54 F1FO3C54 FiFO3C54 F2A63C54 F35C3C54 F4123C54 F4C83C54 F57C3C54 F6343C54 F6EA3C54 F7AO3C54 F8563C54 F9103C54 F9103C54 F9633C54 FA563C54 FAF93C54 FB9C3C54 FC3F3C54 FCE23C54 FD853C54 FE283C54 FECB3C54 FF6E3C54 113C54 B43C54 1573C54 1FA3C54 29D3C54 3403C54 3E33C54 4863C54 5303C54 5303C54 5303800 1038A2 103944 1039E6 103A88 103B2A FFF43BCC FF6E3C6E FEE83D10 FE623DB2 FDDC3E54 FD563EF6 FCDO3F98 FC4A403A FBC440DC FB3E4184 FABO4184 FABO
E6D D360 AC5A D360 AA47 D360 A834 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 A740 D360 N --On approach to cluster, use lower gains740 D3D9 A740 D452 A740 D4CB A740 D544 A740 D5BD A740 D636 A740 D6AF A740 D728 A740 D7A1 A740 D81A A740 D893 A740 D90C A740 D985 A740 D9FE A740 DA77 A740 DAFO A740 DB69 A740 DBE2 A740 DC60 E --Close right claw740 DC60 Q --Increase gains to heavy740 DC60 7 --Increase allowable error6AO D170 A --Jerk the cluster off the rack6A0 D146 A6AO CFBO A6AO CE1A A6AO CC84 A717 CAEE A78E C958 A805 C7C2 A87C C62C A8F3 C496 A96A C300 A9E1 C16A AA58 BFD4 AACF BE3E AB46 BCAO AOBCO BCAO AOBCO BCAO H --End of file
141
68946894689468946894689468946894689468946894689468946894689468946894689468946894689468E46894689468946894689468946894689468946894689468946894689460005F3E5E7C5DBA5CF85C365B745AB259F0
592E586C57AA56E85626556454945494
Ctri.trd: 3/17/88Start at stow and move arm into the workspace
DE80 DDE32 ADDE4 ADD96 ADD48 ADCFA ADCAC ADC5E ADC10 ADBC2 ADB74 ADB26 ADAD8 ADA8A ADA32 AD9EE AD9AO AD952 AD904 AD8B6 AD868 AD810 PD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 AD810 A
--Open right claw
--Claw clear of stow, load higher gains
142
28F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F428F42AD42CD42ED430D432D434D436D438D43AD43CD43ED440D442D444D446D448D44AD44CD44ED450D452D4549454945494549454945494549454945494549454945494
50845084508450845084508450845084508450845084508450845084508450845084508450845084508450844E444C444A44484446444444425441844184418441844184418441844184418441844184418441844184418441844184418441844184418441844184418441844184
4F04323742B61F813A07C
FFBEFF00FE42FD80FC73FB66FA59F94CF83FF732F625F518F40BF2FEFIFOFIFOFiFOFIFOFIFOFiFOFiFOFIFOFiFOFiFOFiFOFIFOFIFOFIFOFiFOFIFOFiFOFiFOFIFOFiFOFiFOFIFOFIFOFIFOFiFOFIFOFiFOFIFOFiFOFIFOFiFOFIFOFIFOFIFO
4BCO4C764D2C4DE24E984F4E500450BA5170522652E052E052E052E052E052E052E052E052E052E052E052E050CD4EBA4CA74A944881466E445B424840353E223COF39FC37E935D633C331B02F9D2D8A2B7729642751253E232B21181F051CF21ADF18CC16B914A612931080E6D
Cjoint.trd: 3/17/88Start at running position for carryinga cluster, and move cluster for easymanual joint assembly.
BCO BCAO TBCO BCAO TC67 BE4D PDOE BFFA ADB5 C1A7 AE5C C354 AF03 C501 AFAA C6AE A1051 C85B A10F8 CA08 A119F CBB5 A1246 CD62 A12ED CFOF A1394 DOBC A143B D269 A14E2 D416 A1589 D5C3 A1630 D770 A16D7 D91D A177E DACA A1825 DC77 A18CC DE24 A1973 DFD1 A1A1A E17E AlADO E340 TlADO E340 TlADO E340 H
--Pause for cluster to settle
--Load higher gains
--Pause to allow cluster to settle
--End of trajectory
144
549454945494549454945494549454945494549454945494549454945494549454945494549454945494549454945494549454945494
418441844184418441844184418441844184418441844184418441844184418441844184418441844184418441844184418441844184
FABOFABOFB64FC18FCCCFD80FE34FEE8FF9C
501041B826C3203D448853C5FO6A475880C8CO974A28AFOAFOAFO
Rgrabslv.trd: 3/17/88With claw on cluster just attached toexisting beam, grab sleeve on beam end.
1B20 E2C0 D --Open right claw1B20 E232 A1B20 E1A4 A1B20 E116 A1B20 E088 A1B20 DFFA A1B20 DF6C A1B20 DEDE A1B20 DE50 A1B20 DDC2 A1B20 DD34 A1B20 DCA6 A1B20 DC18 A1B20 DB8A A1B20 DAFC A1B20 DA6E A1B20 D9EO A1B20 D952 A1B20 D8C4 A1B20 D836 A1B20 D7AO P --Claw clear of cluster, load higher gains1B80 D7AO AlC00 D7A0 A1C80 D7A0 A1D00 D7AO A1D80 D7AO A1E00 D7AO A1E80 D7AO A1F00 D7AO A1F80 D7AO A2000 D7AO A2080 D7AO A2100 D7AO A2180 D7AO A2200 D7AO A2280 D7AO A2300 D7AO A2380 D7AO A2400 D7AO A2480 D7AO A2500 D7AO A2580 D7AO A2600 D7AO A2680 D7AO A2700 D7AO A2780 D7AO A2800 D7AO A2880 D7A0 A2900 D7AO A2980 D7A0 N --On approach to sleeve, load lower gains2980 D872 A2980 D944 A2980 DA16 A2980 DAE8 A
145
557455745574557455745574557455745574557455745574557455745574557455745574557455745574548453845284518450844F844E844D844C844B844A844984498449844984498449844984498449844984498449844984498449844984498449844984498449844984
44A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A444A4452445244524452445244524452445244524452445244524452445244524452445244524452445244524452445244524452445244524452445244524452445244524
8407936E663958C4DF4323852D822B17ED124
FF77FECAFE1DFD70FCC3FC16FB69FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FB30FBE8FCAOFD58FE10
4984 4524 FEC8 2980 DBBA A4984 4524 FF80 2980 DC8C A4984 4524 38 2980 DD5E A4984 4524 FO 2980 DE30 A4984 4524 1A8 2980 DF02 A4984 4524 260 2980 DFD4 A4984 4524 318 2980 EOA6 A4984 4524 3D0 2980 E178 A4984 4524 488 2980 E24A A4984 4524 540 2980 E31C A4984 4524 5F8 2980 E3EE A4984 4524 6B0 2980 E4CO A4984 4524 768 2980 E592 A4984 4524 820 2980 E664 A4984 4524 8D8 2980 E736 A4984 4524 990 2980 E808 A4984 4524 A48 2980 E8DA A4984 4524 BOO 2980 E9AC A4984 4524 BB8 2980 EA7E A4984 4524 C70 2980 EB50 A4984 4524 D28 2980 EC22 A4984 4524 DEO 2980 ECF4 A4984 4524 E98 2980 EDC6 A4984 4524 F50 2980 EE98 A4984 4524 1008 2980 EF6A A4984 4524 10CO 2980 F03C A4984 4524 1178 2980 FlOE A4984 4524 1240 2980 F1EO E --Close right claw4984 4524 1240 2980 F1EO H --End of trajectory
146
Rsldslv.trd: 3/17/88Slide the sleeve from existing beamonto a cluster being attached.
F1EO EF144 QFOA8 7FOOC AEF70 AEED4 AEE38 AED9C AEDOO AECAO AEC40 AEBEO AEB80 AEB20 AEACO AEA60 AEAOO AE9AO AE940 AE906 AE8CC AE892 AE858 AE81E AE7EO TE7EO H
--Close right claw--Load heavy gains--Increase allowable error size
--Jolt Shy and allow to settle--End of trajectory
147
498449664948492A490C48EE48D0
48B2489448F8495C49C04A244A884AEC4B504BB44C184C844CC14CFE4D3B4D784DB54DF44DF4
4524451A4510450644FC44F244E844DE44D444C444B444A444944484447444644454444444444434442444144404440444044404
124011EE119C114A10F810A610541002FBOF75F3AEFFEC4E89E4EE13DD8D9DD60D36DOCCE2CB8C8EC60C60
2980292028C0
2860280027A0274026E02680263425E8259C2550250424B8246C242023D42380233A22F422AE226822201E202220
Rstow.trd: 3/17/88While attaching a cluster to existing beam,leave slide sleeve and go to stow handle.
--Open right claw
--Clear of sleeve, load higher gains
148
4DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44DF44BF449F447F445F443F441F43FF43DF43BF439F437F435F433F431F42FF42DF42BF429F427F425F425F425F425F4
440444044404440444044404440444044404440444044404440444044404440444044404440444044404440444044404440444044404440444044404440444A445AC46A447AC48A449AC4AA44BAC4CA44DA44EA44FA450A450A450A450A450A450A450A450A450A450A450A4
C60BEBB76B01A8CA179A292D8B88437CE7596E466F5FA58551049B4263B13301AA24
FE9EFD18FB92FAOCF886F700F57AF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FOF3FO
222022202220222022202220222022202220222022202220222022202220222022202220222022202220222022202220222022202220222022202220222023CO2560270028AO2A402BEO2D802F2030C0
3260340035A0
374038E03A803C203DCO3F60410042A0
444045E04780
E7EOE77BE716E6B1E64CE5E7E582E51DE4B8E453E3EEE389E324E2BFE25AE1F5E190E12BEOC6E061DFFODF27DE5EDD95DCCCDC03DB3ADA71D9A8D8DFD810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810D810
25F4 50A4 F3F0 4920 D810 A25F4 50A4 F3FO 4AC0 D810 A25F4 50A4 F3FO 4C60 D810 A25F4 50A4 F3FO 4E00 D810 A25F4 50A4 F3FO 4FAO D810 A25F4 50A4 F3FO 5140 D810 A25F4 50A4 F3FO 52E0 D810 A25F4 5084 F3FO 52E0 D810 A25F4 5084 F4A7 52E0 D810 A25F4 5084 F55E 52E0 D810 A25F4 5084 F615 52E0 D810 A25F4 5084 F6CC 52E0 D810 A25F4 5084 F783 52E0 D810 A25F4 5084 F83A 52E0 D810 A25F4 5084 F8F1 52E0 D810 A25F4 5084 F9A8 52E0 D810 A25F4 5084 FA5F 52E0 D810 A25F4 5084 FB16 52E0 D810 A25F4 5084 FBCD 52E0 D810 A25F4 5084 FC84 52E0 D810 A25F4 5084 FD3B 52E0 D810 A25F4 5084 FD80 52E0 D810 A25F4 5084 FD80 52E0 D810 A25F4 5084 FD80 52E0 D810 N --On approach to stow, load lower gains25F4 5084 FD80 5280 D862 A25F4 5084 FD80 5220 D8B4 A25F4 5084 FD80 51C0 D906 A25F4 5084 FD80 5160 D958 A25F4 5084 FD80 5100 D9AA A25F4 5084 FD80 50A0 D9FC A25F4 5084 FD80 5040 DA4E A25F4 5084 FD80 4FEO DA80 A25F4 5084 FE12 4F80 DAF2 A25F4 5084 FEA4 4F20 DB44 A25F4 5084 FF36 4EC0 DB96 A25F4 5084 FFC8 4E60 DBE8 A25F4 5084 5A 4E00 DC3A A25F4 5084 EC 4DAO DC8C A25F4 5084 17E 4D40 DCDE A25F4 5084 210 4CE0 DD30 A25F4 5084 2A2 4C80 DD82 A25F4 5084 334 4C20 DDD4 A25F4 5084 3C6 4BC0 DE26 A25F4 5084 458 4BCO DE80 A25F4 5084 4F0 4BC0 DE80 S --Call for slaverest() at end of trajectory25F4 5084 4F0 4BC0 DE80 E --Close right claw25F4 5084 4F0 4BC0 DE80 H --End of trajectory
149
APPENDIX V. EASE structure assembly scheduleBAT EASE assembly progression0. Startup
A. Set up right arm1). Call for control power on2). Run right arm through it's zeros3). Enable Left Claw.4). Enable Right Claw.5). Enable Beam Carrier.6). Have right arm placed on the stow handle.7). Close right claw8). Slaverest the arm
B. Tilt and Pan setup.1). Run tilt and pan through it's zeros.2). Center head controller3). Disconnect head.
C. Enable Puma1). Call for main power on.2). Enable Puma3). Power relay on.4). Video switch to Belly
1. Attach the First Top Cluster to the first racked upright beam (Cla - Blb).A. Dock to cluster Rack position 1.
1). Manuever thrusters to place left claw on the first cluster rack dock location.2). Close left claw.
B. Retreive cluster C11). Video switch to Tilt and Pan (op.)2). Connect head controller (op.)3). Manuever head to view stow handle (op.)4). operators arm to master arm.5). Press Button to initate Triad trajectory "Cgrab" to reteive cluster6). Verify the cluster is free of the rack (arm will remain live)7). Disconnect master arm.8). video switch to Belly (op.)9). Open left Claw
C. Dock to free end of beam Blb1). Manuever thrusters to place left claw on beam end Blb to the left side of the2). Close left Claw.
D. Attach cluster to Beam end (Cla - Blb)1). Video switch to Tilt and Pan2). Connect head controller3). Operators arm to master arm4). Verify "Cjoint" showing on next up reverse trajectory5). Push inner finger switch to initiate "cjoint" trajectory.6). Manuever right arm with master arm to make the joint7). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories8). Verify button pop9). Push inner finger switch to initate "Rstow" trajectory10). Verify Stow.11). disconnect head12). Video switch to Belly13). Open left Claw.
2. Attach the Second Top Cluster to the second racked upright beam (C2a - B2b).A. Dock to cluster Rack position 2.
1). Manuever thrusters to place left claw on the second cluster rack dock locatio2). Close left claw.
B. Retreive cluster C21). Video switch to Tilt and Pan (op.)2). Connect head controller (op.)3). Manuever head to view stow handle (op.)4). operators arm to master arm.5). Press Button to initate Triad trajectory "Cgrab" to reteive cluster6). Verify the cluster is free of the rack (arm will remain live)
150
e disk.
n.
7). Disconnect master arm.8). video switch to Belly (op.)9). Open left Claw
C. Dock to free end of beam B2b1). Manuever thrusters to place left claw on beam end B2b to the left side of the disk.2). Close left Claw.
D. Attach cluster to Beam end (C2a - B2b)1). Video switch to Tilt and Pan2). Connect head controller3). Operators arm to master arm4). Verify "Cjoint" showing on next up reverse trajectory5). Push inner finger switch to initiate "cjoint" trajectory.6). Manuever right arm with master arm to make the joint7). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories8). Verify button pop9). Push inner finger switch to initate "Rstow" trajectory10). Verify Stow.11). disconnect head12). Video switch to Belly13). Open left Claw.
3. Attach the Third Top Cluster to the fourth rack upright beam (C3a - B4b).A. Dock to cluster Rack position 3.
1). Manuever thrusters to place left claw on the third cluster rack dock location.2). Close left claw.
B. Retreive cluster C31). Video switch to Tilt and Pan (op.)2). Connect head controller (op.)3). Manuever head to view stow handle (op.)4). operators arm to master arm.5). Press Button to initate Triad trajectory "Cgrab" to reteive cluster6). Verify the cluster is free of the rack (arm will remain live)7). Disconnect master arm.8). video switch to Belly (op.)
C. Dock to free end of beam B4b1). Manuever thrusters to place left claw on beam end B4b to the left side of the disk.2). Close left Claw.
D. Attach cluster to Beam end (C3a - B4b)1). Video switch to Tilt and Pan2). Connect head controller3). Operators arm to master arm4). Verify "Cjoint" showing on next up reverse trajectory5). Push inner finger switch to initiate "cjoint" trajectory.6). Manuever right arm with master arm to make the joint7). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories8). Verify button pop9). Push inner finger switch to initate "Rstow" trajectory10). Verify Stow.11). disconnect head12). Video switch to Belly13). Open left Claw.14). Open left Claw.
4. Attach the first upright beam to the base cluster (Bla - CBa).A. Dock to Beam Rack position 1.
1). Manuever thrusters to place left claw on the first beam rack dock location.2). Close left claw.
B. Retreive Beam B11). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to Base Cluster CBa.1). Manuever thrusters to place left claw on Base Cluster CBa next to black tape.2). Close left Claw.
D. Attach beam to base cluster (Bla - CBa)
151
1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory11). Verify Stow.12). disconnect head13). Video switch to Belly14). Open left Claw.
5. Attach the second upright beam to the base cluster (B2a - CBb).A. Dock to Beam Rack position 2.
1). Manuever thrusters to place left claw on the second beam rack dock location.2). Close left claw.
B. Retreive Beam B21). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to Base Cluster CBb.1). Manuever thrusters to place left claw on Base Cluster CBb next to black tape.2). Close left Claw.
D. Attach beam to base cluster (B2a - CBb)1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory11). Verify Stow.12). disconnect head13). Video switch to Belly14). Open left Claw.
6. Attach the first cross beam to the first top cluster (B3a - Clb).A. Dock to Beam Rack position 3.
1). Manuever thrusters to place left claw on the 3rd beam rack dock location.2). Close left claw.
B. Retreive Beam B31). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to top Cluster Clb.1). Manuever thrusters to place left claw on top Cluster Clb on the edge of the silver tubing.2). Close left Claw.
D. Attach beam to top cluster (B3a - Clb)1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory
152
11). Verify Stow.12). disconnect head13). Video switch to Belly14). Open left Claw.
7. Complete the triangle involving the first cross beam and the second top cluster (B3b - C2c).A. Dock to the free end of beam B3b.
1). Manuever thrusters to place left claw on the beam end B3b next to the disk.2). Close left Claw.
B. Fly the beam end up to cluster C2cC. Attach beam to top cluster ( B3b - C2c)
1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Cjoint" showing on next up reverse trajectory6). Push inner finger switch to initiate "ctri" trajectory.7). manuever right arm with master arm to position right claw over beam end next to the disk8). Close right claw9). Manuever right arm with master arm to make the joint10). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories11). Verify button pop12). Push inner finger switch to initate "Rstow" trajectory13). Verify Stow.14). disconnect head15). Video switch to Belly16). Open left Claw.
8. Attach the third upright beam to the base cluster (B4a - CBc).A. Dock to Beam Rack position 4.
1). Manuever thrusters to place left claw on the 4th beam rack dock location.2). Close left claw.
B. Retreive Beam B41). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to Base Cluster CBc.1). Manuever thrusters to place left claw on Base Cluster CBc next to black tape.2). Close left Claw.
D. Attach beam to base cluster (B4a - CBc)1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory11). Verify Stow.12). disconnect head13). Video switch to Belly14). Open left Claw.
9. Attach the second cross beam to the second top cluster (BSa - C2b).A. Dock to Beam Rack position 5.
1). Manuever thrusters to place left claw on the 5th beam rack dock location.2). Close left claw.
B. Retreive Beam B51). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to top Cluster C2b.1). Manuever thrusters to place left claw on top Cluster C2b on the edge of the silver tubing.
153
2). Close left Claw.D. Attach beam to top cluster (B5a - C2b)
1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory11). Verify Stow.12). disconnect head13). Video switch to Belly14). Open left Claw.
10. Complete the triangle involving the second cross beam and the third top cluster (B5b - C3c).A. Dock to the free end of beam B5b.
1). Manuever thrusters to place left claw on the beam end B5b next to the disk.2). Close left Claw.
B. Fly the beam end up to cluster C3cC. Attach beam to top cluster ( B5b - C3c)
1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Cjoint" showing on next up reverse trajectory6). Push inner finger switch to initiate "ctri" trajectory.7). manuever right arm with master arm to position right claw over beam end next to the disk8). Close right claw9). Manuever right arm with master arm to make the joint10). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories11). Verify button pop12). Push inner finger switch to initate "Rstow" trajectory13). Verify Stow.14). disconnect head15). Video switch to Belly16). Open left Claw.
11. Attach the third cross beam to the third top cluster (B6a - C3b).A. Dock to Beam Rack position 6.
1). Manuever thrusters to place left claw on the 6th beam rack dock location.2). Close left claw.
B. Retreive Beam B61). Extend Beam carrier2). Close Beam Carrier claw.3). Retract Beam Carrier4). Open left claw.
C. Dock to top Cluster C3b.1). Manuever thrusters to place left claw on top Cluster C3b on the edge of the silver tubing.2). Close left Claw.
D. Attach beam to top cluster (B6a - C3b)1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Grabbeam" showing on next up forward trajectory6). Push outer finger switch to initiate "Grabbeam" and "joint" trajectory.7). Manuever right arm with master arm to make the joint8). Push outer finger switch to initiate "grabslv" and "slidslv" trajectories9). Verify button pop10). Push inner finger switch to initate "stow" trajectory11). Verify Stow.12). disconnect head13). Video switch to Belly
154
14). Open left Claw.12. Complete the triangle involving the third cross beam and the second top cluster (B6b - Clc).
A. Dock to the free end of beam B6b.1). Manuever thrusters to place left claw on the beam end B6b next to the disk.2). Close left Claw.
B. Fly the beam end up to cluster ClcC. Attach beam to top cluster ( B6b - Clc)
1). Video switch to Tilt and Pan2). Connect head controller3). Manuever head to view stow handle (op.)4). Operators arm to master arm5). Verify "Cjoint" showing on next up reverse trajectory6). Push inner finger switch to initiate "ctri" trajectory.7). manuever right arm with master arm to position right claw over beam end next to the disk8). Close right claw9). Manuever right arm with master arm to make the joint10). Push inner finger switch to initiate "Rgrabslv" and "Rsldslv" trajectories11). Verify button pop12). Push inner finger switch to initate "Rstow" trajectory13). Verify Stow.14). disconnect head15). Video switch to Belly16). Open left Claw.
13. Shut DownA. Power relay offB. Call for main power offC. Call for Control power offD. Disable PumaE. Disable beam carrierF. Disable left clawG. Disable right claw
155