00001 #ifndef _SATCTL_H 00002 #define _SATCTL_H 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 #include <unistd.h> 00006 #include <termios.h> 00007 #include <string.h> 00008 #include <math.h> 00009 #include <sys/time.h> 00010 #include <sys/types.h> 00011 #include <sys/stat.h> 00012 #include <sys/fcntl.h> 00013 #include <sys/ioctl.h> 00014 #include <asm/ioctls.h> 00015 #include <bits/types.h> 00016 00017 /* Data structure definitions: */ 00018 00019 /* A single momentum wheel: */ 00020 typedef struct { 00021 int wnum; /* Wheel number */ 00022 char *portfn; /* Port filename */ 00023 speed_t brate; /* Baudrate as a speed_t */ 00024 int portfd; /* Open port fdes */ 00025 float cvel; /* Current velocity (rps) */ 00026 float pvel; /* Previous velocity (rps) */ 00027 int status; /* Current status */ 00028 int type; /* Motor type */ 00029 float maxaccel; /* Maximum acceleration (rps^2) */ 00030 float maxvel; /* Maximum velocity (rps) */ 00031 float maxcur; /* Maximum motor current */ 00032 /* Add position info */ 00033 /* Add moment info */ 00034 } wheel_t; 00035 00036 typedef struct { 00037 int lades; /* LA number */ 00038 char *serno; /* LA serial number */ 00039 char *portfn; /* Port filename */ 00040 int portfd; /* Open port fdes */ 00041 int hi_l; /* Hi limit (on LA's step counter) */ 00042 int lo_l; /* Low limit (on LA's step counter) */ 00043 int travel; /* Total travel in steps (hi_l - lo_l)*/ 00044 int mtt; /* Estimated max end-to-end travel time (usec) */ 00045 int curpos; /* Current commanded abs position (0 @ neg end) 00046 * Note that this is in a shifted range, whereas hi_l 00047 * and lo_l are in the LA's real range. So at the 00048 * lower limit, curpos = 0, and at the high end, 00049 * curpos = hi_l - lo_l. In general, curpos is 00050 * realpos - lo_l (where realpos is the position 00051 * according to the LA's step counter as reported 00052 * by SP and IP. This means that hi_l and lo_l 00053 * MUST be calculated before the LA is practically 00054 * usable. The shifted range limits then become 00055 * 0 at the low end, and 'travel' at the high end. 00056 */ 00057 int posvel; /* Positioning velocity ( x20,000 steps/sec) */ 00058 int posacc; /* Positioning acceleration (max 20 recommended) */ 00059 int posdec; /* Positioning deceleration (max 20 recommended) */ 00060 int jogvel; /* Jog velocity */ 00061 int jogacc; /* Jog accel/decel */ 00062 } la_t; 00063 00064 00065 /* wheel_t.status - 0 - Not initialized 00066 * 1 - Initialized 00067 * 2 - Initialized but did not reach tvel (but did move) 00068 * 3 - Initialized but stuck (did not move at all) 00069 */ 00070 00071 00072 /* A single delta-V command action: */ 00073 typedef struct { 00074 float vtarget; /* Target velocity */ 00075 float atarget; /* Target acceleration */ 00076 float actime; /* Action time (depends on flags) */ 00077 int flags; /* Bit-mapped flags: See below*/ 00078 } dva_t; 00079 00080 00081 /* A single set of attitude data: */ 00082 typedef struct { 00083 float xrate; 00084 float yrate; 00085 float zrate; 00086 float xaccel; 00087 float yaccel; 00088 float zaccel; 00089 float temp; 00090 int deltat; 00091 long serial; 00092 } adat_t; 00093 00094 /* The master configuration structure */ 00095 typedef struct { 00096 char *mwPort; /* MW port filename */ 00097 speed_t mwSpeed; /* MW port speeds */ 00098 /* This is not the most compact way to do this, but it's less work, and 00099 * we're not so short on memory that we need to scrounge for the space 00100 * of two and half int's. This way it's more straightforward, which is 00101 * probably more important, since this could potentially be confusing. 00102 * The motors will be assigned addresses serially based on their cabling 00103 * order. Then, the first element of this array will contain the 00104 * address of the X motor, the second of the Y, and the third of the Z. 00105 */ 00106 int mwOrder[3]; /* MW motor cabling order */ 00107 char **laPort; /* LA port filenames */ 00108 speed_t *laSpeed; /* LA port speeds */ 00109 char *dmuPort; /* DMU port filename */ 00110 speed_t dmuSpeed; /* DMU port speed */ 00111 int regChan; /* Thruster regulator channel (out)*/ 00112 int thlChan; /* Thruster Hi/Lo relay (out)*/ 00113 int thAChan; /* Thruster A (out)*/ 00114 int thBChan; /* Thruster B (out)*/ 00115 int batChan[8]; /* Battery volt channels (in)*/ 00116 int dmuRate[3]; /* DMU xyz turn rates */ 00117 int dmuAccel[3]; /* DMU xyz accelerations */ 00118 int taChan; 00119 int tbChan; 00120 int batchan[8]; 00121 } mcfg_t; 00122 00123 00124 00125 /* End of data structure definitions */ 00126 00127 00128 /* Global constants (and vars ;-> ) */ 00129 00130 #define CMD_STRLEN 80 /* A default buffer length for serial comm */ 00131 #define MICROMO 1 /* Motor type for MicroMo (MVP2001A01 w/ 3863H024C) */ 00132 #define SMARTMOTOR 2 /* Motor type for SmartMotor (SM3420) */ 00133 00134 #define DFLT_TVAL 1000000 /* Default timerval in seconds */ 00135 #define SS_TVEL 30.0 /* Spinup target velocity */ 00136 #define SS_TACC 30.0 /* Spinup target acceleration */ 00137 #define SU_TVTOL 2.0 /* Spinup target velocity error tolerance */ 00138 00139 00140 #ifdef INMAIN 00141 const char cfgWords[11][9] = { 00142 "mwport", 00143 "mwspeed", 00144 "mworder", 00145 "laport", 00146 "laspeed", 00147 "dmuport", 00148 "dmuspeed", 00149 "dmudata", 00150 "thchan", 00151 "batchan", 00152 ""}; 00153 struct itimerval mtmr1; /* Timers for use in measuring acceleration */ 00154 struct itimerval mtmr2; 00155 struct timeval dflt_tv; /* The default settings for mtmr1 and mtmr2 */ 00156 const float MM_SR = 2000.0; /* 1/(500usec) = 1/(5e-4) = 2e+3 */ 00157 /* const float MM_SR = 2000.0; 1/(1000usec) = 1/(1e-3) = 1e+3 */ 00158 const float MM_ENC_RES = 15.15576; /* Effective CPR to calibrate w/ SM */ 00159 const float SM_VELSF = 64424.5; /* cts / rev/sec */ 00160 const float SM_ACCSF = 15.84; /* cts/sec^2 / rev/sec^2 */ 00161 const int LA_ACC = 20; /* LA accel */ 00162 const int LA_VEL = 5; /* LA velocity */ 00163 const char *hex_charset = "0123456789ABCDEF"; 00164 int debug = 0; 00165 #else 00166 extern struct itimerval mtmr1; 00167 extern struct itimerval mtmr2; 00168 extern struct timeval dflt_tv; 00169 extern const float MM_ENC_RES; 00170 extern const float MM_SR; 00171 /* extern const float MM_RPM_COUNT; 00172 extern const float MM_RPS_COUNT;*/ 00173 extern const float SM_VELSF; 00174 extern const float SM_ACCSF; 00175 extern const int LA_ACC; 00176 extern const int LA_VEL; 00177 extern const char *hex_charset; 00178 extern const int debug; 00179 #endif 00180 00181 extern const char cfgWords[11][9]; 00182 00183 #define MM_RPS_COUNT 2000/MM_SR*2000/MM_ENC_RES 00184 /* 2000/MM_SR * 4 * (2000 / (4 * MM_ENC_RES)) */ 00185 #define MM_RPM_COUNT MM_RPS_COUNT/60.0 00186 /* End of global constants */ 00187 00188 00189 00190 /* Function prototypes and options defines: */ 00191 00192 /********************************************************************** 00193 * Function: mwInit() 00194 * Description: Initialize a momentum wheel. Open the serial port, 00195 * verify presence of configured motor type, and perform a variety 00196 * of spinup tests. 00197 * Arguments: 00198 * wheel - Wheel to initialize 00199 * action - Bit-mapped flag of startup tests to run 00200 * Return Values: 00201 * -1 - Failed to open port 00202 * 0 - Initialized OK 00203 * 1 - Failed init tests 00204 * 2 - Motor not responding 00205 * Bugs: none known 00206 * Notes: Stable through several program revisions. 00207 * Last Update: 6/15/02 00208 * Last Updated By: Cengiz Akinli 00209 **********************************************************************/ 00210 00211 int mwInit(wheel_t *wheel, int actions); 00212 00213 /* Spinup testing will proceed in order down this list. Simple spinup should 00214 * be more than adequate most of the time. Because of potential for motor 00215 * damage, shaking modes will not be immediately coded. 00216 */ 00217 #define MWIT_SSPINUP 0x0001 /* Simple spinup to a preset +RPM and check */ 00218 #define MWIT_BDSSPINUP 0x0002 /* Bidirectional simple spinup */ 00219 00220 /* The below should ONLY be used in failure modes- i.e. to free a stuck motor */ 00221 #define MWIT_RSPINUP_3 0x0004 /* 3-stage ramped current spinup (to 60% max) */ 00222 #define MWIT_BDRSPINUP_3 0x0008 /* Bidirectional 3-stage ramped current */ 00223 #define MWIT_RSPINUP_5 0x0010 /* 5-stage ramped current (to max current) */ 00224 #define MWIT_BDRSPINUP_5 0x0020 /* Bidirectional 5-stage ramped current */ 00225 00226 /* Last resort only- not implemented as of 11/25/02 */ 00227 #define MWIT_SHAKE_25 0x0040 /* 2 Hz shaking at 25% max current */ 00228 #define MWIT_SHAKE_50 0x0080 /* 2 Hz shaking at 50% max current */ 00229 #define MWIT_SHAKE_75 0x0100 /* 2 Hz shaking at 75% max current */ 00230 #define MWIT_SHAKE_100 0x0200 /* 2 Hz shaking at max current */ 00231 00232 00233 00234 /********************************************************************** 00235 * Function: mwStop() 00236 * Description: Shut down a momentum wheel (must be at v=0 to shutdown) 00237 * Arguments: 00238 * wheel - Wheel to initialize 00239 * status - Failure status 00240 * Returns: 00241 * 0 - Shut down OK 00242 * 1 - Motor not at 0 velocity - no action taken 00243 * 2 - Motor not responding 00244 * Bugs: none known 00245 * Notes: Stable through several program revisions. 00246 * Last Update: 6/15/02 00247 * Last Updated By: Cengiz Akinli 00248 **********************************************************************/ 00249 00250 int mwStop(wheel_t *wheel); 00251 00252 00253 00254 /********************************************************************** 00255 * Function: mwChangeVel() 00256 * Description: Change a wheel's target velocity 00257 * Arguments: 00258 * wheel - Designated wheel 00259 * params - Delta-v action parameter structure 00260 * status - Failure status 00261 * Returns: 00262 * -1 - Some failure occured (see status) 00263 * 0 - Initialized OK 00264 * Bugs: none known 00265 * Notes: Transience allows a new velocity to be set for a fixed period 00266 * of time, after which the wheel is returned to the previous 00267 * velocity. Flagging an action as transient affects how blocking 00268 * is implemented. When you set the blocking flag for a transient 00269 * action, the function blocks until the wheel returns to the 00270 * previous velocity. For a non-transient motion, the function 00271 * blocks only for the number of microseconds in the actime 00272 * parameter, which is then counted starting from the beginning of 00273 * the action OR from the time the wheel reaches the target 00274 * velocity, depending on whether the MWCV_TTA or MWCV_TAV flags 00275 * are set respectively. 00276 * Last Update: 6/15/02 00277 * Last Updated By: Cengiz Akinli 00278 **********************************************************************/ 00279 00280 int mwChangeVel(wheel_t *wheel, dva_t *params, int *status); 00281 00282 /* dva_t flags: */ 00283 #define MWCV_TTA 0x01 /* actime is total time for action (includes accel) */ 00284 #define MWCV_TAV 0x02 /* actime is only time at target vel (excludes accel) */ 00285 #define MWCV_FAOR 0x04 /* Fail on acceleration out of range (and do nothing) */ 00286 #define MWCV_FVOR 0x08 /* Fail on velocity out of range (and do nothing) */ 00287 #define MWCV_BLOCK 0x10 /* Block until end of action. If non-transient, this 00288 * will end up being the acceleration time. */ 00289 #define MWCV_TRANS 0x20 /* Motion is transient. Return to previous velocity 00290 * along same acceleration after actime seconds. 00291 * MWCV_BLOCK is implied. MWCV_TTA and MWCV_TAV 00292 * control behavior in this case. 00293 */ 00294 /* mwChangeVel() status bitmap: */ 00295 #define MWCV_AOR_S 0x01 /* Acceleration overrange failure */ 00296 #define MWCV_VOR_S 0x02 /* Velocity overrange failure */ 00297 00298 00299 /* Motion Pak data acquisition 00300 * This will be a standalone process forked by the dmuInit call and killed 00301 * by the dmuStop call. It will poll the MP at the selected rate, calculate 00302 * the calibrated data and write it to a shared memory segment for pickup by 00303 * dmuReadData(). Currently, there is no overflow checking. Thus, care 00304 * should be taken to ensure that the read interval is sufficiently short, 00305 * and that the shared mem segment large enough such that the chance of 00306 * overwriting unread data is minimized. Overflow checking, and perhaps 00307 * dynamic reallocation, cacheing, and other more sophisticated handling 00308 * of data would be a more robust solution, but also could be involved and, 00309 * if the existing system is well implemented, it would also be unnecessary. 00310 */ 00311 00312 /* Motion pak data read: */ 00313 00314 /********************************************************************** 00315 * Function: dmuInit() 00316 * Description: Initialize the DMU 00317 * Arguments: 00318 * maxBufSz - Maximum number of data sets to buffer (Note: bytesize 00319 * per set will be 7*sizeof(float)). 00320 * rate - Read rate in reads per second (0 for max allowed by baudrate) 00321 * rpid - Read process PID - out 00322 * flags - Bit-mapped flags 00323 * 00324 * Returns: 00325 * -1 - Could not create FIFO 00326 * 0 - Initialized OK 00327 * 1 - rate exceeds max 00328 * 2 - open() failed on port 00329 * 3 - open() failed on data pipe 00330 * 4 - open() failed on control pipe 00331 * 5 - fork() failed 00332 * Bugs: 00333 * Notes: See notes above regarding shared mem segment size vs read rates. 00334 * Last Update: 7/8/02 00335 * Last Updated By: Cengiz Akinli 00336 **********************************************************************/ 00337 00338 int dmuInit(long maxBufferSize, int rate, int flags); 00339 00340 #define DMUI_FBA 0x01 /* On full data buffer, begin averaging data */ 00341 #define DMUI_FBD 0x02 /* On full data buffer, begin dropping data */ 00342 #define DMU_PORT "/dev/mopak" 00343 00344 00345 /********************************************************************** 00346 * Function: dmuStop() 00347 * Description: Shutdown the DMU read process. 00348 * Arguments: 00349 * rpid - Read process PID 00350 * 00351 * Returns: 00352 * 0 - OK 00353 * 1 - Error on close() 00354 * Bugs: 00355 * Notes: 00356 * Last Update: 7/8/02 00357 * Last Updated By: Cengiz Akinli 00358 **********************************************************************/ 00359 00360 int dmuStop(pid_t rpid); 00361 00362 00363 00364 /********************************************************************** 00365 * Function: dmuReadData() 00366 * Description: Read data from the DMU. This will read ALL buffered 00367 * data with each call. accData AND ALL of its members 00368 * must be statically allocated in advance. 00369 * Arguments: 00370 * accData - Acceleration data struct 00371 * fp - File pointer to data pipe 00372 * maxsets - Maximum number of sets to read (accData should be 00373 * pre-allocated for this many sets 00374 * 00375 * Returns: 00376 * Data sets read 00377 * -2 - Buffer filled 00378 * -1 - Pipe closed 00379 * Bugs: 00380 * Notes: 00381 * Last Update: 7/8/02 00382 * Last Updated By: Cengiz Akinli 00383 **********************************************************************/ 00384 00385 int dmuReadData(adat_t **accData, int maxsets); 00386 00387 00388 __uint16_t mbcrc_16(__uint8_t *ptr, int len); 00389 00390 00391 /********************************************************************** 00392 * Function: laInit() 00393 * Description: Initialize a linear actuator 00394 * Arguments: 00395 * lades - actuator descriptor 00396 * action - Bit-mapped flag of startup tests to run 00397 * Return Values: 00398 * -1 - Failed to open port 00399 * 0 - Initialized OK 00400 * 1 - Move/Wait in progress (sleep and try back later) 00401 * 2 - Servo fault requiring power cycle of controller 00402 * 3 - Controller not responding 00403 * 4 - SP cmd fail during LAIT_CTRA 00404 * 5 - Failed to reach limit in la->mtt 00405 * Bugs: none known 00406 * Notes: 00407 * Last Update: 11/25/02 00408 * Last Updated By: Cengiz Akinli 00409 **********************************************************************/ 00410 00411 int laInit(la_t *lades, int action); 00412 00413 /********************************************************************** 00414 * Function: laMove() 00415 * Description: Move a linear actuator relative to it current position 00416 * Arguments: 00417 * lades - actuator descriptor 00418 * steps - distance to move in counts 00419 * Return Values: 00420 * -1 - Failed to open port 00421 * 0 - Initialized OK 00422 * 1 - Move/Wait in progress (sleep and try back later) 00423 * 2 - Servo fault requiring power cycle of controller 00424 * 3 - Controller not responding 00425 * 4 - SP cmd fail during LAIT_CTRA 00426 * 5 - Failed to reach limit in la->mtt 00427 * Bugs: none known 00428 * Notes: 00429 * Last Update: 11/25/02 00430 * Last Updated By: Cengiz Akinli 00431 **********************************************************************/ 00432 00433 int laMove(la_t *lades, int steps); 00434 00435 #define LAIT_COMM 0x01 /* Test comm */ 00436 #define LAIT_PRGP 0x02 /* Program presets */ 00437 #define LAIT_JPOS 0x04 /* Jog to positive end */ 00438 #define LAIT_JNEG 0x08 /* Jog to negative end */ 00439 #define LAIT_CTRA 0x10 /* Calc total travel */ 00440 #define LAIT_MOLD 0x20 /* Move to old position (after CTRA) */ 00441 #define LAIT_MPOS 0x40 /* Move to positive end (after CTRA) */ 00442 #define LAIT_MNEG 0x80 /* Move to negative end (after CTRA) */ 00443 #define LAIT_SLIM 5000 /* Soft limit cushion. This is the closest 00444 * to the limit switches that the software will 00445 * allow the actuators to move (except during 00446 * init, where the switches are set). Counter 00447 * resolution is ~ 20,000/inch.*/ 00448 00449 #endif