- From: Dominic <I-C-H_at_gmx.de>
- Date: Sun, 08 Sep 2002 22:38:22 +0200
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;
}
------------------------------------------
Received on 2002-09-08Z19:38:22