home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
-
- FILE
- cntrl1.c - control code
-
- ROUTINES
- control - execute control algorithm
- gain - interpret command line for P gain
- setv - interpret command line for setpoint
- getv - get velocity reading
- mact - send controller output to actuator
-
- REMARKS
- Implements PI control and uses a timer to determine sample
- intervals.
-
- LAST UPDATE
- 1 December 1987
- restructure and modify for MSC 4.00 and 5.00
-
- Copyright(C) 1984-1987, D.M.Auslander and C.H. Tham
-
- ***********************************************************************/
-
- /***********************************************************************
- I M P O R T S
- ***********************************************************************/
-
- #include <stdio.h>
-
- #include "envir.h" /* environment definitions */
- #include "dash8.h" /* declarations for dash8.c */
- #include "dac2.h" /* declarations for dac2.c */
- #include "time0.h" /* declarations for time0.c */
- #include "cntrl1.h" /* exported declarations for this module */
-
-
- /***********************************************************************
- F O R W A R D D E C L A R A T I O N S
- ***********************************************************************/
-
- #ifdef ANSI
-
- double getv(void);
- void mact(double);
-
- #else
-
- double getv();
- void mact();
-
- #endif
-
-
- /***********************************************************************
- P R I V A T E D A T A V A R I A B L E S
- ***********************************************************************/
-
- #define ADCHANNEL 0 /* A/D channel that we will use */
- #define DACHANNEL 0 /* D/A channel used by this module */
-
- static double vref = 1000.0; /* velocity setpoint */
- static double kp = 1.0; /* proportional gain */
- static double ki = 0.2; /* integral gain. */
- static double vcon = 0.0; /* constant term in the controller */
- static double mmin; /* lower limit for controller output */
- static double mmax; /* upper limit for controller output */
- static double tsamp = 0.5; /* controller sample interval (sec). */
- static double isum; /* integrator accumulated value. */
-
-
- /***********************************************************************
- E N T R Y R O U T I N E S
- /***********************************************************************
-
- /*----------------------------------------------------------------------
- PROCEDURE
- control - this function does the control
-
- SYNOPSIS
- void control(cline)
- char *cline;
-
- PARAMETER
- cline - user's input line
-
- REMARKS
- Implements PI control.
-
- The control output is calculated in two parts - first with only
- P action and add I action. The output is limited to what the
- actuator can put out, with provisions against reset windup.
-
- Note that the timer is set in milliseconds.
-
- LAST UPDATE
- 1 December 1987
- ----------------------------------------------------------------------*/
-
- void control(cline)
- char *cline;
- {
- long nitr; /* number of iterations */
- long i; /* iteration counter */
- double v; /* the motor velocity */
- double m1; /* intermediate result in control calculation. */
- double m; /* controller output */
- int damin, damax; /* output argument range of D/A */
- int prnt; /* 1 = print control output, 0 = no print */
-
-
- /*---------------------------------------------------------------
- Get number of iterations and print flag from the command
- line, cline. Sscanf() is just like scanf() except that the
- input is a string instead of the standard input (keyboard).
- -----------------------------------------------------------------*/
-
- sscanf(cline, "%ld %d", &nitr, &prnt);
-
- printf("number of iterations = %ld\n", nitr); /* verify */
-
- da_limits(&damin, &damax); /* find D/A output limits */
-
- mmin = (double)damin;
- mmax = (double)damax;
-
- isum = 0.0; /* initialize integrator. */
-
-
- for (i = 0; i < nitr; i++)
- {
- SetTimer((long)(tsamp * 1000L)); /* set countdown timer in ms */
-
- v = getv(); /* get motor velocity */
-
- isum += vref - v; /* integrate error term */
-
- /*----------------------------------------------------------
- First calculate control output without integral term.
- -----------------------------------------------------------*/
-
- m1 = kp * (vref - v) + vcon;
-
- /*----------------------------------------------------------
- Check for actuator limits and apply "reset windup".
- Limit value of m to allowable D/A and actuator range
- and set integral term to zero if system is outside
- linear zone.
- ------------------------------------------------------------*/
-
- if (m1 > mmax) /* output exceeds actuator limit */
- {
- m1 = mmax; /* set output to actuator maximum */
- isum = 0.0; /* set integral term to zero */
- }
- else if (m1 < mmin)
- {
- m1 = mmin;
- isum = 0.0;
- }
-
- m = m1 + ki * isum; /* now add in integral term. */
-
- mact(m); /* send control output to actuator */
-
- if (prnt)
- printf("v = %lf, m = %lf\n", v, m);
-
- if (TimeUp()) /* timer has run out */
- {
- printf("sample time too short\n");
- exit(1);
- }
-
- while (!TimeUp())
- {
- #if SIMRT
- tstep(); /* advance time */
- #endif
- }
- } /* end of control loop */
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- GAIN - interpret the input line specifying controller gain(s)
-
- SYNOPSIS
- void gain(cline)
- char *cline;
-
- PARAMETERS
- cline - input line
-
- LAST UPDATE
- 15 October 1984
- ----------------------------------------------------------------------*/
-
- void gain(cline)
- char *cline;
- {
-
- sscanf(cline, "%lf %lf %lf", &kp, &ki, &vcon); /* decode input line */
-
- #if DEBUG
- printf("<gain> kp = %lf, ki = %lf, vcon = %lf\n", kp, kp, vcon);
- #endif
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SETV - get velocity setpoint from the command line
-
- SYNOPSIS
- void setv(cline)
- char *cline;
-
- PARAMETERS
- cline - user's command line
-
- LAST UPDATE
- 15 October 1984
- ----------------------------------------------------------------------*/
-
- void setv(cline)
- char *cline;
- {
-
- sscanf(cline,"%lf", &vref);
-
- #if DEBUG
- printf("<setv> vref = %lf\n", vref);
- #endif
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SMPSET - set sample time
-
- SYNOPSIS
- smpset(cline)
- char *cline;
-
- PARAMETER
- cline - user's command line
-
- DESCRIPTION
- Extract sample time from user's command line and use it to set the
- sample time on the timer.
-
- LAST UPDATE
- 1 December 1987
- ----------------------------------------------------------------------*/
-
- void smpset(cline)
- char *cline;
- {
-
- sscanf(cline, "%lf", &tsamp);
-
- #if DEBUG
- printf("<smpset> tsamp = %lf\n", tsamp);
- #endif
-
- }
-
-
-
- /***********************************************************************
-
- The following section contains routines which interface between
- high level control code and functions which perform the hardware
- dependent functions of operating the A/D and D/A. As such, they
- are necessarily dependent on the device driver interface.
-
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- INIT - system initialization
-
- SYNOPSIS
- void init()
-
- REMARKS
- Performs any initializations required.
-
- LAST UPDATE
- 1 December 1987
- ----------------------------------------------------------------------*/
-
- void init(cline)
- char *cline;
- {
-
- ad_init(); /* initialize A/D */
- da_init(); /* initialize D/A */
-
- #ifdef SIMRT
- sim_init(cline); /* initialize simulation module */
- #endif
-
- }
-
-
-
- /*---------------------------------------------------------------------
- FUNCTION
- GETV - returns motor velocity
-
- SYNOPSIS
- static double getv()
-
- RETURNS
- current motor velocity (units unspecified)
-
- REMARKS
- Reads channel 0 of the A/D converter, convert the value to a
- double type and return this converted value.
-
- LAST UPDATE
- 1 December 1987
- ---------------------------------------------------------------------*/
-
- static double getv()
- {
-
- return((double)ad_wread(ADCHANNEL));
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- MACT - send controller output to actuator
-
- SYNOPSIS
- static void mact(value)
- double value;
-
- PARAMETER
- value - controller output
-
- REMARKS
- Convert output to integer and send it to D/A converter
-
- LAST UPDATE
- 1 December 1987
- ----------------------------------------------------------------------*/
-
- static void mact(value)
- double value;
- {
-
- da_write(DACHANNEL, (int)value);
- }
-
-
-