home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
-
- FILE
- cascade0.c - cascade PID position and velocity control
-
- ROUTINES
- control - the cascade controller
- pgain - get position gains
- vgain - get velocity gains
- smpset - set sampling interval
- getv - get velocity
- getp - get position
-
- REMARKS
- This implements the cascade control configuration of figure 3.7
- in the book. There are two control loops, an inner velocity
- loop and an outer position loop. The input to the velocity loop
- is the output of the position loop.
-
- This example demonstrates the use of time2.c, quad1.c and a
- modified pwm.c for timing and i/o interface. You need to modify
- pwm.c in order to use it with quad1.c (refer to remarks for
- the mact() routine).
-
- This file contains only the control implementation. You have
- to implement the user interface and perhaps the simulation
- module. For examples of user interface and simulation modules,
- you can refer to cntrl1.c and rtsim1.c.
-
- LAST UPDATE
- 27 January 1988
- use quad1.c and pwm.c
-
- ***********************************************************************/
-
- /***********************************************************************
- I M P O R T S
- ***********************************************************************/
-
- #include <stdio.h>
-
- #include "envir.h" /* environment definitions */
-
- #include "time2.h"
- #include "quad1.h"
- #include "pwm.h"
-
-
- /***********************************************************************
- F O R W A R D D E C L A R A T I O N S
- ***********************************************************************/
-
- #ifdef ANSI
-
- double getv(void);
- double getp(void);
- void mact(double);
-
- #else
-
- double getv();
- double getp();
- void mact();
-
- #endif
-
- /**********************************************************************
- P R I V A T E D A T A
- **********************************************************************/
-
- #define SCALE 1000.0 /* quadrature states per unit displacement */
- #define PWMFREQ 50.0 /* pwm frequency */
- #define TMRFREQ 50L /* timer "tick" frequency in milliseconds */
-
- #define LOOPTIMER 0 /* timer number for control loop */
- #define PWMTIMER 1 /* timer number for pwm pulse timing */
-
- static double mvmax = 2047.0; /* max velocity actuator output */
- static double mvmin = -2048.0; /* min velocity actuator output */
-
- static double tsamp = 0.5; /* sampling interval */
-
- static double Kpp, Kpi, Kpd; /* position P, I and D gains */
- static double Kvp, Kvi, Kvd; /* velocity P, I and D gains */
- static double pref; /* position set point */
- static double perr0; /* position error at current time k */
- static double perr1; /* position error at time (k - 1) */
- static double perr2; /* position error at time (k - 2) */
- static double verr0; /* velocity error at current time k */
- static double verr1; /* velocity error at time (k - 1) */
- static double verr2; /* velocity error at time (k - 2) */
-
-
- /**********************************************************************
- E N T R Y R O U T I N E S
- **********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- CONTROL - implements cascade position-velocity control
-
- SYNOPSIS
- void control(cline)
- char *cline;
-
- PARAMETER
- cline - pointer to input line.
-
- REMARKS
- The error terms are initialized to zero. When this routine starts,
- it is equivalent to applying a step position reference input.
- Note also that mp and mv, the position and velocity outputs, must
- be initialized too.
-
- LAST UPDATE
- 1 April 1985
- ----------------------------------------------------------------------*/
-
- void control(cline)
- char *cline;
- {
- double p; /* position */
- double v; /* velocity */
- double mp; /* postion controller output */
- double delta_mp; /* change in mp */
- double mv; /* velocity controller output */
- double delta_mv; /* change in mv */
- long i; /* iteration counter */
- long nitr; /* # of iterations */
- int prnt; /* 1 - print control output, 0 - do not print */
-
-
- /* get user specified iteration limit and print switch */
-
- sscanf(cline, "%ld %d", &nitr, &prnt);
-
- #ifdef DEBUG
- printf("number of iterations = %ld\n", nitr);
- #endif
-
- /* initialize position and velocity error variables */
-
- perr0 = perr1 = perr2 = 0.0;
- verr0 = verr1 = verr2 = 0.0;
- mp = 0.0;
- mv = 0.0;
-
-
- for (i = 0L; i < nitr; i++)
- {
- SetDTimer(LOOPTIMER, (long)(tsamp * 1000));
-
- /* calculate position control parameters */
-
- perr2 = perr1; /* update position errors */
- perr1 = perr0;
-
- p = getp(); /* read position */
-
- perr0 = pref - p; /* calculate new position error */
-
- delta_mp = Kpp * (perr0 - perr1) + Kpi * perr0
- + Kpd * (perr0 - 2.0 * perr1 + perr2);
-
- mp += delta_mp;
-
-
- /* calculate velocity control parameters */
-
- verr2 = verr1; /* update velocity errors */
- verr1 = verr0;
-
- v = getv(); /* read velocity */
-
- verr0 = mp - v; /* calculate new velocity error */
-
- delta_mv = Kvp * (verr0 - verr1) + Kvi * verr0
- + Kvd * (verr0 - 2.0 * verr1 + verr2);
-
- mv += delta_mv;
-
- /* Check for actuator limits and apply "reset windup" control. */
- /* Limit value of m to allowable D/A and actuator range and */
- /* set integral term to zero if system is outside linear zone. */
-
- if (mv > mvmax) /* output exceeds actuator limit */
- mv = mvmax; /* set output to actuator maximum */
- else if (mv < mvmin)
- mv = mvmin;
-
- mact(mv); /* send controller output to the actuator. */
-
- if (prnt)
- printf("p = %f, v = %f, mp = %f, mv = %f\n", p, v, mp, mv);
-
- if (TimeUp(LOOPTIMER))
- {
- printf("sample time too short\n");
- exit(1);
- }
-
- while (!TimeUp(LOOPTIMER))
- {
- #ifdef SIMRT
- tstep(); /* advance time */
- #endif
- }
- } /* end of iteration loop. */
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURES
- PGAIN - interpret the input line specifying position gains
- VGAIN - interpret the input line specifying velocity gains
-
- SYNOPSIS
- void pgain(cline)
- char *cline;
-
- void vgain(cline)
- char *cline;
-
- PARAMETERS
- cline - input command line
-
- LAST UPDATE
- 26 January 1988
- change to void return
- ----------------------------------------------------------------------*/
-
- void pgain(cline)
- char *cline;
- {
-
- sscanf(cline, "%lf %lf %lf", &Kpp, &Kpi, &Kpd);
-
- #ifdef DEBUG
- printf("<pgain> Kpp = %lf, Kpi = %lf, Kpd = %lf\n", Kpp, Kpi, Kpd);
- #endif
-
- }
-
-
- void vgain(cline)
- char *cline;
- {
-
- sscanf(cline, "%lf %lf %lf", &Kvp, &Kvi, &Kvd);
-
- #ifdef DEBUG
- printf("<vgain> Kvp = %lf, Kvi = %lf, Kvd = %lf\n", Kvp, Kvi, Kvd);
- #endif
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SETP - get position setpoint from the command line
-
- SYNOPSIS
- void setp(cline)
- char *cline;
-
- PARAMETERS
- cline - user's command line
-
- LAST UPDATE
- 26 January 1988
- change to void return type
- ----------------------------------------------------------------------*/
-
- void setp(cline)
- char *cline;
- {
-
- sscanf(cline,"%lf", &pref);
-
- #ifdef DEBUG
- printf("<setv> pref = %lf\n", pref);
- #endif
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SMPSET - set sample time
-
- SYNOPSIS
- void smpset(cline)
- char *cline;
-
- PARAMETER
- cline - user's command line
-
- REMARKS
- Extract sample time from user's command line and use it to set the
- sample time on the timer.
-
- LAST UPDATE
- 26 January 1988
- change to void return type
- ----------------------------------------------------------------------*/
-
- void smpset(cline)
- char *cline;
- {
-
- sscanf(cline,"%lf", &tsamp);
-
- #ifdef DEBUG
- printf("<smpset> tsamp = %lf\n", tsamp);
- #endif
-
- }
-
-
- /***********************************************************************
- P R I V A T E R O U T I N E S
- ***********************************************************************/
-
- /*---------------------------------------------------------------------
- FUNCTIONS
- GETV - returns motor velocity
- GETP - returns motor position
-
- SYNOPSIS
- static double getv()
- static double getv()
-
- RETURNS
- current motor velocity and position (units unspecified)
-
- REMARKS
- This example shows how easy it is to use quad1.c (or any other
- method) for position and velocity. You can plug in other methods
- just as easily.
-
- LAST UPDATE
- 27 January 1988
- show use of quad1.c instead of ADC and DAC.
- ---------------------------------------------------------------------*/
-
- static double getv()
- {
-
- return(quad_getv());
- }
-
-
- static double getp()
- {
-
- return(quad_getp());
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- MACT - send out controller output
-
- SYNOPSIS
- static void mact(output)
- double output;
-
- PARAMETERS
- output - controller output
-
- REMARKS
- This example shows the use of PWM output using pwm.c
-
- Note that the control algorithm has already limited the output to
- between mvmax and mvmin and that mvmin is negative.
-
- LAST UPDATE
- 26 January 1988
- substitute pwm for DAC
- ----------------------------------------------------------------------*/
-
- static void mact(output)
- double output;
- {
- double dutycycle;
-
-
- if (output >= 0.0)
- {
- dutycycle = output / mvmax;
- }
- else
- {
- dutycycle = -(output / mvmin);
- }
-
- setdcycle(dutycycle);
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- INIT - system initialization
-
- SYNOPSIS
- void init()
-
- REMARKS
- Initialize the time2.c, quad1.c and the yet to be written pwm1.c.
-
- LAST UPDATE
- 27 January 1988
- initialize quad1 and a modified pwm.
- ----------------------------------------------------------------------*/
-
- void init(cline)
- char *cline;
- {
-
- InitTime(TMRFREQ); /* init time.c module */
-
- quad_init(SCALE, tsamp);
-
- pwm_init(PWMTIMER);
- setpfreq(PWMFREQ);
-
- }
-
-
-
-