home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s300 / 1.ddi / CHAP2 / RTSIM1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-02  |  11.0 KB  |  447 lines

  1. /**********************************************************************
  2.  
  3. FILE
  4.     rtsim1.c  -  d.c. speed control, simulation module 1
  5.  
  6. ENTRY ROUTINES
  7.     tstep      -  advance one time step
  8.     SetTimer   -  set count-down timer
  9.     TimeUp     -  has count down completed?
  10.  
  11.     ad_init    -  simulates A/D initialization
  12.     ad_start   -  simulates starting an A/D read
  13.     ad_read    -  simulates reading A/D value
  14.     ad_wread   -  simulates read from A/D
  15.  
  16.     da_init    -  simulates D/A initialization
  17.     da_limits  -  returns simulation D/A output limits
  18.     da_write   -  simulates write to D/A
  19.  
  20. PRIVATE ROUTINE
  21.     simul   -  motor plant simulation
  22.  
  23. INITIALIZATION ROUTINE
  24.     sim_init   -  initialize simulation
  25.  
  26. REMARKS
  27.     This module simulates the interface and motor hardware and the
  28.     passage of "real" time.  This module must thus provide the same
  29.     interface functions as the modules controlling the hardware.
  30.  
  31.     To use "real" time, compile this module with the /DFTIME switch;
  32.     this will cause tstep() to use ftime() calls to tell time.
  33.  
  34.  
  35. LAST UPDATE
  36.     1 December 1987
  37.         restructure and modify for MSC 4.00 and 5.00
  38.  
  39.     Copyright(C) 1984-1987  D.M. Auslander and C.H. Tham
  40.  
  41. **********************************************************************/
  42.  
  43. /***********************************************************************
  44.                             I M P O R T S
  45. ***********************************************************************/
  46.  
  47. #include <stdio.h>
  48.  
  49. #include "envir.h"          /* environment specifications */
  50.  
  51. #ifdef FTIME                /* include stuff to run simulation in */
  52.                             /*  real time using ftime() calls.    */
  53. #include <sys\types.h>
  54. #include <sys\timeb.h>
  55.  
  56. #endif
  57.  
  58.  
  59. /***********************************************************************
  60.              F O R W A R D    D E C L A R A T I O N S
  61. ***********************************************************************/
  62.  
  63. #ifdef ANSI
  64.  
  65. void simul(void);
  66.  
  67. #ifndef FTIME
  68. void runtimer(void);
  69. #endif
  70.  
  71. #else
  72.  
  73. void simul();
  74.  
  75. #ifndef FTIME
  76. void runtimer();
  77. #endif
  78.  
  79. #endif
  80.  
  81.  
  82. /**********************************************************************
  83.                  P R I V A T E    D A T A
  84. **********************************************************************/
  85.  
  86. #define ADSCALE       512.0     /* scale speed to A/D units */
  87. #define ADMAX        2047       /* max A/D input value */
  88. #define ADMIN       -2048       /* min A/D input value */
  89.  
  90. #define DASCALE      2047.0     /* scale D/A value to torque */
  91. #define DAMIN       -2048       /* min. output value accepted */
  92. #define DAMAX        2047       /* max. output value accepted */
  93.  
  94. static double inertia = 1.0;        /* motor system inertia */
  95. static double speed;                /* simulated motor velocity */
  96. static double t;                    /* time */
  97. static double dt;                   /* step size in time */
  98. static double torque = 0.0;         /* motor torque */
  99.  
  100. #ifndef FTIME
  101.  
  102. static long freq = 1000L;       /* timer frequency (ticks/sec) */
  103. static long ticks;              /* how many ticks to timeout */
  104. static int tflag;               /* set to 1 if timer runs out */
  105.  
  106. #endif
  107.  
  108. static long millidt;            /* step size dt in milliseconds */
  109.  
  110.  
  111. /***********************************************************************
  112.                      T I M E    S I M U L A T I O N
  113. ***********************************************************************/
  114.  
  115. #ifndef FTIME                   /* simulate timer hardware */
  116.  
  117. /*---------------------------------------------------------------------
  118. PROCEDURE
  119.     TSTEP  -  advance time forward one step
  120.  
  121. SYNOPSIS
  122.     void tstep()
  123.  
  124. LAST UPDATE
  125.     10 October 1984
  126. ---------------------------------------------------------------------*/
  127.  
  128. void tstep()
  129. {
  130.  
  131.     simul();        /* compute one time step in the differential */
  132.                     /*   equation for the motor system.      */
  133.  
  134.     t += dt;        /* increment time by dt */
  135.  
  136.     runtimer();     /* simulate timer run */
  137. }
  138.  
  139.  
  140.  
  141. /*----------------------------------------------------------------------
  142. PROCEDURE
  143.     SETTIMER  -  set countdown timer
  144.  
  145. SYNOPSIS
  146.     void SetTimer(ms)
  147.     long ms;
  148.  
  149. PARAMETER
  150.     period -  count down period in milliseconds
  151.  
  152. LAST UPDATE
  153.     15 January 1988
  154. ----------------------------------------------------------------------*/
  155.  
  156. void SetTimer(ms)
  157. long ms;
  158. {
  159.  
  160.     ticks = ((ms * freq) + 500L) / 1000L;   /* 500 is for rounding */
  161.  
  162.     tflag = 0;                              /* timeout flag to false */
  163.     
  164. }
  165.  
  166.  
  167.  
  168. /*---------------------------------------------------------------------
  169. FUNCTION
  170.     TIMEUP  -  has timer timed out?
  171.  
  172. SYNOPSIS
  173.     int TimeUp()
  174.  
  175. RETURNS
  176.     1 if timer runs out, 0 otherwise
  177.  
  178. LAST UPDATE
  179.     1 March 1985
  180. ----------------------------------------------------------------------*/
  181.  
  182. int TimeUp()
  183. {
  184.  
  185.     return(tflag);
  186. }
  187.  
  188.  
  189.  
  190. /*----------------------------------------------------------------------
  191. PROCEDURE
  192.     RUNTIMER  -  simulates timer run
  193.  
  194. SYNOPSIS
  195.     static void runtimer()
  196.  
  197. LAST UPDATE
  198.     19 March 1985
  199. ----------------------------------------------------------------------*/
  200.  
  201. static void runtimer()
  202. {
  203.  
  204.     if (!tflag)             /* if timeout, just return, otherwise... */
  205.     {
  206.         /* decrement tick count by # of ticks corresponding to dt sec */
  207.  
  208.         ticks -= (long)(dt * freq + 0.5);   /* 0.5 is for rounding */
  209.  
  210.         if (ticks <= 0L)    /* time has run out */
  211.             tflag = 1;
  212.     }
  213.  
  214. }
  215.  
  216.  
  217. #else   /* else use "real" time */
  218.  
  219.  
  220. /*---------------------------------------------------------------------
  221. PROCEDURE
  222.     TSTEP  -  advance time forward one step
  223.  
  224. SYNOPSIS
  225.     void tstep(void)
  226.  
  227. REMARKS
  228.     This routine runs the simulation and then waits dt seconds (millidt
  229.     is dt converted to milliseconds) using ftime() library calls.
  230.  
  231.     Thus, dt determines how often the simulation is run and is more or
  232.     less independent of the sampling time.
  233.  
  234. LAST UPDATE
  235.     18 January 1988
  236. ---------------------------------------------------------------------*/
  237.  
  238. void tstep()
  239. {
  240.     struct timeb start;         /* starting time */
  241.     struct timeb now;           /* current time */
  242.  
  243.  
  244.     simul();
  245.  
  246.     ftime(&start);
  247.  
  248.     do
  249.     {
  250.         ftime(&now);
  251.     }
  252.     while (((now.time - start.time) * 1000)
  253.         + now.millitm - start.millitm < millidt);
  254.     
  255. }
  256.  
  257.  
  258. #endif  /* else ifndef FTIME */
  259.  
  260.  
  261. /***********************************************************************
  262.                         A / D    S I M U L A T I O N
  263.  
  264.     These routines dummies the routines in dash8.c which drives the
  265.     Metrabyte DASH8 A/D board.  The channel parameter is ignored.
  266.  
  267. ***********************************************************************/
  268.  
  269. void ad_init()
  270. {
  271.  
  272.     speed = 0.0;
  273.  
  274. }
  275.  
  276.  
  277. void ad_start(channel)
  278. int channel;
  279. {
  280.     /* nothing */
  281. }
  282.  
  283.  
  284. int ad_read(channel)
  285. int channel;
  286. {
  287.     int rval;                   /* return value */
  288.  
  289.  
  290.     rval = ADSCALE * speed;     /* scale and convert to int type */
  291.  
  292.     if (rval > ADMAX)           /* apply converter limits */
  293.         rval = ADMAX;
  294.     else if (rval < ADMIN)
  295.         rval = ADMIN;
  296.  
  297.     return(rval);
  298. }
  299.  
  300.  
  301. int ad_wread(channel)
  302. int channel;
  303. {
  304.  
  305.     return(ad_read(channel));
  306. }
  307.  
  308.  
  309.  
  310. /***********************************************************************
  311.                      D / A    S I M U L A T I O N
  312.  
  313.     These routines dummies the routines in dac2.c which drives the
  314.     Metrabyte DAC02 D/A board.  The channel parameter is ignored.
  315.  
  316.     The DAC2 is a 12-bit digital-to-analog converter configured for
  317.     bipolar output.  Thus, the output parameter values range from
  318.     -2048 to 2047.  Only lower 12 bits will be used, treating those
  319.     12 bits as a 2's complement signed number.  Thus if the output
  320.     value is negative, the lower 12 bits will be preserved and all
  321.     higher order bits will be converted to 1's.
  322.  
  323.     Note the use of ~0xfff instead of 0xf000, this makes the program
  324.     more portable across machines with different integer sizes.
  325.  
  326. ***********************************************************************/
  327.  
  328. void da_init()
  329. {
  330.  
  331.     torque = 0.0;
  332.  
  333. }
  334.  
  335.  
  336. void da_limits(lo, hi)
  337. int *lo, *hi;
  338. {
  339.  
  340.     *lo = DAMIN;
  341.     *hi = DAMAX;
  342.  
  343. }
  344.  
  345.  
  346. void da_write(channel, value)
  347. int channel, value;
  348. {
  349.  
  350.     if (value < 0)          /* OR with a binary number having 0's for */
  351.         value |= ~0xfff;    /*   the lower 12 bits and 1's elsewhere  */
  352.     else 
  353.         value &= 0xfff;     /* for positive values, just save the     */
  354.                             /*   lower 12 bits.                       */
  355.  
  356.     torque = value / DASCALE;   /* rescale for motor drive torque. */
  357.  
  358. }
  359.  
  360.  
  361.  
  362. /**********************************************************************
  363.                    P R I V A T E    R O U T I N E S
  364.  
  365.     The following routines are declared "static".  These routines
  366.     can be directly accessed only by routines inside this file; they
  367.     are not "visible" to routines outside this file.  Hence they are
  368.     private to this file.  Private routines enhances data security
  369.     and helps avoid unexpected name conflicts in large programming
  370.     projects.
  371.  
  372. ***********************************************************************/
  373.  
  374. /*----------------------------------------------------------------------
  375. PROCEDURE
  376.     SIMUL  -  simulates motor plant
  377.  
  378. SYNOPSIS
  379.     static void simul()
  380.  
  381. REMARKS
  382.     Solve the motor system differential equation.  This version uses 
  383.     the Euler method for integration; it isn't very efficient, but its 
  384.     easy to program!
  385.  
  386. LAST UPDATE
  387.     12 January 1988
  388.         add friction term to make it more interesting
  389. ----------------------------------------------------------------------*/
  390.  
  391. static void simul()
  392. {
  393.     double friction;
  394.  
  395.  
  396.     friction = speed / 10.0;    /* this is quite arbitrary */
  397.  
  398.     speed += (torque - friction) * dt / inertia;
  399.  
  400. }
  401.  
  402.  
  403.  
  404. /***********************************************************************
  405.           I N I T I A L I Z A T I O N    R O U T I N E
  406. ***********************************************************************/
  407.  
  408. /*----------------------------------------------------------------------
  409. PROCEDURE
  410.     INIT  -  system initialization
  411.  
  412. SYNOPSIS
  413.     sim_init(cline)
  414.     char *cline;
  415.  
  416. PARAMETER
  417.     cline  -  user's input command line
  418.  
  419. REMARKS
  420.     In a "real" real-time program, this function would be used to set 
  421.     up interrupts, set clock modes, etc.  In this simulation version,
  422.     it sets time to zero and sets the motor simulation initial conditions.
  423.  
  424. LAST UPDATE
  425.     18 October 1984
  426. ----------------------------------------------------------------------*/
  427.  
  428. sim_init(cline)
  429. char *cline;
  430. {
  431.  
  432.     sscanf(cline, "%lf", &dt);  /* get the step size. */
  433.  
  434. #if DEBUG
  435.     printf("<init> dt = %lf\n", dt);
  436. #endif
  437.  
  438.     t = 0.0;                    /* reset time */
  439.     millidt = (long)(dt * 1000  +  0.5);
  440.  
  441.     speed = 0.0;                /* motor is initially at rest */
  442.     torque = 0.0;
  443.  
  444. }
  445.  
  446.  
  447.