home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
-
- FILE
- rtsim1.c - d.c. speed control, simulation module 1
-
- ENTRY ROUTINES
- tstep - advance one time step
- SetTimer - set count-down timer
- TimeUp - has count down completed?
-
- ad_init - simulates A/D initialization
- ad_start - simulates starting an A/D read
- ad_read - simulates reading A/D value
- ad_wread - simulates read from A/D
-
- da_init - simulates D/A initialization
- da_limits - returns simulation D/A output limits
- da_write - simulates write to D/A
-
- PRIVATE ROUTINE
- simul - motor plant simulation
-
- INITIALIZATION ROUTINE
- sim_init - initialize simulation
-
- REMARKS
- This module simulates the interface and motor hardware and the
- passage of "real" time. This module must thus provide the same
- interface functions as the modules controlling the hardware.
-
- To use "real" time, compile this module with the /DFTIME switch;
- this will cause tstep() to use ftime() calls to tell time.
-
-
- 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 specifications */
-
- #ifdef FTIME /* include stuff to run simulation in */
- /* real time using ftime() calls. */
- #include <sys\types.h>
- #include <sys\timeb.h>
-
- #endif
-
-
- /***********************************************************************
- F O R W A R D D E C L A R A T I O N S
- ***********************************************************************/
-
- #ifdef ANSI
-
- void simul(void);
-
- #ifndef FTIME
- void runtimer(void);
- #endif
-
- #else
-
- void simul();
-
- #ifndef FTIME
- void runtimer();
- #endif
-
- #endif
-
-
- /**********************************************************************
- P R I V A T E D A T A
- **********************************************************************/
-
- #define ADSCALE 512.0 /* scale speed to A/D units */
- #define ADMAX 2047 /* max A/D input value */
- #define ADMIN -2048 /* min A/D input value */
-
- #define DASCALE 2047.0 /* scale D/A value to torque */
- #define DAMIN -2048 /* min. output value accepted */
- #define DAMAX 2047 /* max. output value accepted */
-
- static double inertia = 1.0; /* motor system inertia */
- static double speed; /* simulated motor velocity */
- static double t; /* time */
- static double dt; /* step size in time */
- static double torque = 0.0; /* motor torque */
-
- #ifndef FTIME
-
- static long freq = 1000L; /* timer frequency (ticks/sec) */
- static long ticks; /* how many ticks to timeout */
- static int tflag; /* set to 1 if timer runs out */
-
- #endif
-
- static long millidt; /* step size dt in milliseconds */
-
-
- /***********************************************************************
- T I M E S I M U L A T I O N
- ***********************************************************************/
-
- #ifndef FTIME /* simulate timer hardware */
-
- /*---------------------------------------------------------------------
- PROCEDURE
- TSTEP - advance time forward one step
-
- SYNOPSIS
- void tstep()
-
- LAST UPDATE
- 10 October 1984
- ---------------------------------------------------------------------*/
-
- void tstep()
- {
-
- simul(); /* compute one time step in the differential */
- /* equation for the motor system. */
-
- t += dt; /* increment time by dt */
-
- runtimer(); /* simulate timer run */
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SETTIMER - set countdown timer
-
- SYNOPSIS
- void SetTimer(ms)
- long ms;
-
- PARAMETER
- period - count down period in milliseconds
-
- LAST UPDATE
- 15 January 1988
- ----------------------------------------------------------------------*/
-
- void SetTimer(ms)
- long ms;
- {
-
- ticks = ((ms * freq) + 500L) / 1000L; /* 500 is for rounding */
-
- tflag = 0; /* timeout flag to false */
-
- }
-
-
-
- /*---------------------------------------------------------------------
- FUNCTION
- TIMEUP - has timer timed out?
-
- SYNOPSIS
- int TimeUp()
-
- RETURNS
- 1 if timer runs out, 0 otherwise
-
- LAST UPDATE
- 1 March 1985
- ----------------------------------------------------------------------*/
-
- int TimeUp()
- {
-
- return(tflag);
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- RUNTIMER - simulates timer run
-
- SYNOPSIS
- static void runtimer()
-
- LAST UPDATE
- 19 March 1985
- ----------------------------------------------------------------------*/
-
- static void runtimer()
- {
-
- if (!tflag) /* if timeout, just return, otherwise... */
- {
- /* decrement tick count by # of ticks corresponding to dt sec */
-
- ticks -= (long)(dt * freq + 0.5); /* 0.5 is for rounding */
-
- if (ticks <= 0L) /* time has run out */
- tflag = 1;
- }
-
- }
-
-
- #else /* else use "real" time */
-
-
- /*---------------------------------------------------------------------
- PROCEDURE
- TSTEP - advance time forward one step
-
- SYNOPSIS
- void tstep(void)
-
- REMARKS
- This routine runs the simulation and then waits dt seconds (millidt
- is dt converted to milliseconds) using ftime() library calls.
-
- Thus, dt determines how often the simulation is run and is more or
- less independent of the sampling time.
-
- LAST UPDATE
- 18 January 1988
- ---------------------------------------------------------------------*/
-
- void tstep()
- {
- struct timeb start; /* starting time */
- struct timeb now; /* current time */
-
-
- simul();
-
- ftime(&start);
-
- do
- {
- ftime(&now);
- }
- while (((now.time - start.time) * 1000)
- + now.millitm - start.millitm < millidt);
-
- }
-
-
- #endif /* else ifndef FTIME */
-
-
- /***********************************************************************
- A / D S I M U L A T I O N
-
- These routines dummies the routines in dash8.c which drives the
- Metrabyte DASH8 A/D board. The channel parameter is ignored.
-
- ***********************************************************************/
-
- void ad_init()
- {
-
- speed = 0.0;
-
- }
-
-
- void ad_start(channel)
- int channel;
- {
- /* nothing */
- }
-
-
- int ad_read(channel)
- int channel;
- {
- int rval; /* return value */
-
-
- rval = ADSCALE * speed; /* scale and convert to int type */
-
- if (rval > ADMAX) /* apply converter limits */
- rval = ADMAX;
- else if (rval < ADMIN)
- rval = ADMIN;
-
- return(rval);
- }
-
-
- int ad_wread(channel)
- int channel;
- {
-
- return(ad_read(channel));
- }
-
-
-
- /***********************************************************************
- D / A S I M U L A T I O N
-
- These routines dummies the routines in dac2.c which drives the
- Metrabyte DAC02 D/A board. The channel parameter is ignored.
-
- The DAC2 is a 12-bit digital-to-analog converter configured for
- bipolar output. Thus, the output parameter values range from
- -2048 to 2047. Only lower 12 bits will be used, treating those
- 12 bits as a 2's complement signed number. Thus if the output
- value is negative, the lower 12 bits will be preserved and all
- higher order bits will be converted to 1's.
-
- Note the use of ~0xfff instead of 0xf000, this makes the program
- more portable across machines with different integer sizes.
-
- ***********************************************************************/
-
- void da_init()
- {
-
- torque = 0.0;
-
- }
-
-
- void da_limits(lo, hi)
- int *lo, *hi;
- {
-
- *lo = DAMIN;
- *hi = DAMAX;
-
- }
-
-
- void da_write(channel, value)
- int channel, value;
- {
-
- if (value < 0) /* OR with a binary number having 0's for */
- value |= ~0xfff; /* the lower 12 bits and 1's elsewhere */
- else
- value &= 0xfff; /* for positive values, just save the */
- /* lower 12 bits. */
-
- torque = value / DASCALE; /* rescale for motor drive torque. */
-
- }
-
-
-
- /**********************************************************************
- P R I V A T E R O U T I N E S
-
- The following routines are declared "static". These routines
- can be directly accessed only by routines inside this file; they
- are not "visible" to routines outside this file. Hence they are
- private to this file. Private routines enhances data security
- and helps avoid unexpected name conflicts in large programming
- projects.
-
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SIMUL - simulates motor plant
-
- SYNOPSIS
- static void simul()
-
- REMARKS
- Solve the motor system differential equation. This version uses
- the Euler method for integration; it isn't very efficient, but its
- easy to program!
-
- LAST UPDATE
- 12 January 1988
- add friction term to make it more interesting
- ----------------------------------------------------------------------*/
-
- static void simul()
- {
- double friction;
-
-
- friction = speed / 10.0; /* this is quite arbitrary */
-
- speed += (torque - friction) * dt / inertia;
-
- }
-
-
-
- /***********************************************************************
- I N I T I A L I Z A T I O N R O U T I N E
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- INIT - system initialization
-
- SYNOPSIS
- sim_init(cline)
- char *cline;
-
- PARAMETER
- cline - user's input command line
-
- REMARKS
- In a "real" real-time program, this function would be used to set
- up interrupts, set clock modes, etc. In this simulation version,
- it sets time to zero and sets the motor simulation initial conditions.
-
- LAST UPDATE
- 18 October 1984
- ----------------------------------------------------------------------*/
-
- sim_init(cline)
- char *cline;
- {
-
- sscanf(cline, "%lf", &dt); /* get the step size. */
-
- #if DEBUG
- printf("<init> dt = %lf\n", dt);
- #endif
-
- t = 0.0; /* reset time */
- millidt = (long)(dt * 1000 + 0.5);
-
- speed = 0.0; /* motor is initially at rest */
- torque = 0.0;
-
- }
-
-
-