- From: Dr. Chuck Hall <chall_at_skyraider.mae.ncsu.edu>
- Date: Mon, 9 Sep 2002 07:37:20 -0400
sounds interesting and would like to see it. any thoughts about making it more
general, such as discrete xfer functions for matlab?
chuck
On Sun, 08 Sep 2002, Dominic wrote:
> I am working on a code generator for control systems.
>
> -----------------------------------------------------
> If there's enough interest in the rtai/rtlinux/comedi
> community I would create a small homepage, upload the
> source etc. and distribute it under GPL or BSD license.
> ----------------------------------------------------
>
> It boils down to a python script which reads in a
> directory containing templates for operators e.g.
> DAC/ADC (comedi templates), Digital transfers function,
> PID controller, RT-Linux main program template and/or
> a user space main program template.
> These templates contain c-code which embedds python code
> for glue code generation.
> (similar to perl/python apache-web-server modules)
>
> The templates are then used to create operators
> which override some/all default values.
>
> The operators are then connected so that they
> represent e.g. a closed-loop system.
>
> Finally c-code is generated which can be used to
> simulate the system in user-space or control
> a real system with rtlinux&comedi.
>
>
> Ciao,
> Dominic
>
> P.S. I am tired, so here is an early example:
>
>
>
> ###########################################################
>
> Example model & generated c-code:
>
> An example-model would be:
>
> ---------------------------------------------------------------
>
> # Create Step function
> # _M(0) makes the parameter tuneable, otherwise it would be
> # hardcoded
> # tuneable parameters can be changed by a kernel-memory-patch script
>
> in1=t_step.Create(trigger=_M(0),amplitude=_M(1))
>
> # Simple user-space printf output
> out1=t_dump.Create()
>
> # Digital transfer function
> plant1=t_plant.Create(order=3,osize=3,a=[1,-0.3,0.5],b=[0,0,1])
>
> # Start a tree
> tree=TreeNode(in1)
>
> # The user-space main program template, get's control function tree as
> # parameter
> rt1=t_main.Create(t=tree)
>
> # Connect step-function with digital transfer function to output
> tree.Link([in1],[plant1])
> tree.Link([plant1],[out1])
>
> # Setup various data structures
> tree.WalkTree()
>
> # Generate user-space main program
> source=rt1.Gen('main')
>
> # Print Code
> PrettyPrint(source)
> -------------------------------------------------------------------------
>
> The generated c-source:
>
> /* rt1 section main */
> /* in1 has no section include */
> /* plant1 has no section include */
> /* out1 has no section include */
> #include <stdio.h>
> #include <stdlib.h>
> /* in1 section data */
> double in1[3];
> double in1_trigger = 0;
> double in1_amplitude = 1;
> /* plant1 section data */
> double plant1_a[3];
> double plant1_b[3];
> double plant1[3];
> /* out1 section data */
> void
> init ()
> {
> /* in1 section init */
> memset (in1, 0, sizeof (double) * 3);
> /* plant1 section init */
> plant1_a[0] = 1;
> plant1_a[1] = -0.3;
> plant1_a[2] = 0.5;
> plant1_b[0] = 0;
> plant1_b[1] = 0;
> plant1_b[2] = 1;
> memset (plant1, 0, sizeof (double) * 3);
> /* out1 section init */
> }
> struct arg_register_t
> {
> char name[20];
> double *value;
> };
> double z = 123;
> struct arg_register_t arg_register[] = {
> {"1979", (double *) 0},
> {"index", ((double *) &arg_register)},
> /* in1 section register */
> {"in1_trigger", &in1_trigger},
> {"in1_amplitude", &in1_amplitude},
> /* plant1 section register */
> /* out1 section register */
> {"", NULL}
> };
> struct arg_register_t *
> arg_register_find (char *name)
> {
> struct arg_register_t *reg = arg_register;
> while ((*reg++).value != NULL)
> {
> if (strcmp (name, (*reg).name) == 0)
> {
> return reg;
> }
> }
> return NULL;
> }
>
> int
> arg_register_get (char *name, double *value)
> {
> struct arg_register_t *reg;
> reg = arg_register_find (name);
> if (reg)
> {
> *value = *((*reg).value);
> return 1;
> }
> else
> {
> return -1;
> }
> }
> int
> arg_register_set (char *name, double value)
> {
> struct arg_register_t *reg;
> reg = arg_register_find (name);
> if (reg)
> {
> *((*reg).value) = value;
> return 1;
> }
> else
> {
> return -1;
> }
> }
> int
> main ()
> {
> double t;
> init ();
> arg_register[0].value = (double *) 0x7766;
> for (t = 0; t <= 2.5; t += 0.05)
> {
> {
> /* in1 section update */
> memmove (in1 + 1, in1, sizeof (double) * (2));
> {
> static int in1_counter = 0;
> in1_counter++;
> if (in1_counter >= in1_trigger)
> {
> in1[0] = in1_amplitude;
> }
> else
> {
> in1[0] = 0;
> }
> }
> }
> {
> /* plant1 section update */
> memmove (plant1 + 1, plant1, sizeof (double) * (2));
> {
> int i;
> double sum = 0.0;
> for (i = 0; i < 3; i++)
> {
> sum += in1[i] * plant1_b[i];
> }
> for (i = 1; i < 3; i++)
> {
> sum -= plant1[i] * plant1_a[i];
>
> }
> plant1[0] = sum / plant1_a[0];
> }
> }
> {
> /* out1 section update */
> printf ("%g %g\n", t, plant1[0]);
> }
> /* in1 has no section updateState */
> /* plant1 has no section updateState */
> /* out1 has no section updateState */
> }
>
> printf ("You might want to try patch.py :-)\n");
> getchar ();
>
> arg_register[0].value = (double *) 0x0;
> return EXIT_SUCCESS;
> }
>
> ------------------------------------------
>
>
>
>
>
>
>
> _______________________________________________
> Rtl mailing list
> Rtl_at_rtlinux.org
> http://www2.fsmlabs.com/mailman/listinfo.cgi/rtl
Received on 2002-09-09Z10:37:20