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