17
Halcompile Developing realtime components for LinuxCNC

Halcompile Developing realtime components for LinuxCNC

Embed Size (px)

Citation preview

Page 1: Halcompile Developing realtime components for LinuxCNC

Halcompile

Developingrealtime components

for LinuxCNC

Page 2: Halcompile Developing realtime components for LinuxCNC

Halcompile

Simplifies task of writing realtime component Declaration section followed by a section of

"mostly C" Complex components better coded in "C" "comp" in LinuxCNC 2.6, "halcompile" in

master/2.7 ~70% of components in LinuxCNC are written

with comp

Page 3: Halcompile Developing realtime components for LinuxCNC

Building and installing a component

Ensure filename (foo.comp) is the same as component declaration (component foo)

LinuxCNC installed as package make sure linuxcnc-dev is installed sudo halcompile --install foo.comp

LinuxCNC built from source . scripts/rip-environment halcompile --install foo.comp

Page 4: Halcompile Developing realtime components for LinuxCNC

Simplest component

component constant;pin out float out;function _;license "GPL";;;FUNCTION(_) { out = 1.0; }

Page 5: Halcompile Developing realtime components for LinuxCNC

Generated code (do not read) /* Autogenerated by /home/jepler/local/src/linuxcnc/bin/comp on Mon Oct 13 13:16:11 2014 -- do not edit */#include "rtapi.h"#ifdef RTAPI#include "rtapi_app.h"#endif#include "rtapi_string.h"#include "rtapi_errno.h"#include "hal.h"

static int comp_id;

#ifdef MODULE_INFOMODULE_INFO(linuxcnc, "component:ddt:Compute the derivative of the input function");MODULE_INFO(linuxcnc, "pin:in:float:0:in::None:None");MODULE_INFO(linuxcnc, "pin:out:float:0:out::None:None");MODULE_INFO(linuxcnc, "funct:_:1:");MODULE_INFO(linuxcnc, "license:GPL");MODULE_LICENSE("GPL");#endif // MODULE_INFO

struct __comp_state { struct __comp_state *_next; hal_float_t *in; hal_float_t *out; double old;

};struct __comp_state *__comp_first_inst=0, *__comp_last_inst=0;

static void _(struct __comp_state *__comp_inst, long period);static int __comp_get_data_size(void);#undef TRUE#define TRUE (1)#undef FALSE…

static int export(char *prefix, long extra_arg) { char buf[HAL_NAME_LEN + 1]; int r = 0; int sz = sizeof(struct __comp_state) + __comp_get_data_size(); struct __comp_state *inst = hal_malloc(sz); memset(inst, 0, sz); r = hal_pin_float_newf(HAL_IN, &(inst->in), comp_id, "%s.in", prefix); if(r != 0) return r; r = hal_pin_float_newf(HAL_OUT, &(inst->out), comp_id, "%s.out", prefix); if(r != 0) return r; rtapi_snprintf(buf, sizeof(buf), "%s", prefix); r = hal_export_funct(buf, (void(*)(void *inst, long))_, inst, 1, 0, comp_id); if(r != 0) return r; if(__comp_last_inst) __comp_last_inst->_next = inst; __comp_last_inst = inst; if(!__comp_first_inst) __comp_first_inst = inst; return 0;}static int default_count=1, count=0;char *names[16] = {0,};RTAPI_MP_INT(count, "number of ddt");RTAPI_MP_ARRAY_STRING(names, 16, "names of ddt");int rtapi_app_main(void) { int r = 0; int i; comp_id = hal_init("ddt"); if(comp_id < 0) return comp_id; if(count && names[0]) { rtapi_print_msg(RTAPI_MSG_ERR,"count= and names= are mutually exclusive\n"); return -EINVAL; } if(!count && !names[0]) count = default_count; if(count) { for(i=0; i<count; i++) {…

Page 6: Halcompile Developing realtime components for LinuxCNC

Pins

pin direction type name; direction: in, out, (rare) io type: signed, unsigned, float, bit (old: s32, u32) name: internal _ becomes -; trailing _ is

removed Examples:

pin in float position-fb; pin out bit position-ok;

Page 7: Halcompile Developing realtime components for LinuxCNC

Parameters

param direction type name; direction: r, rw type, name: as for pins Examples:

param r float position-scale; param rw float max-error-seen;

Page 8: Halcompile Developing realtime components for LinuxCNC

Components can have state

component push2toggle"Convert a (debounced) pushbutton to a toggle";

pin in bit in;pin out bit out;variable bool last_in;license "GPL";function _;;;bool new_in = in;if(new_in && !last_in) out = !out;last_in = new_in;

Page 9: Halcompile Developing realtime components for LinuxCNC

Variables

variable ctype name; ctype: int, double, rtapi_s32, etc

common pitfall: using 'variable float'. value assigned to variable is remembered

from period to period

Page 10: Halcompile Developing realtime components for LinuxCNC

Self-documentation

Can attach documentation to most items component ddt "Compute discrete derivative of input"; pin out float temperature-cmd "Target temperature (centigrade)"; function _ "Check for fires and update outputs"; Additional documentation sections: description, notes, see_also

View documentation: halcompile --view-doc Install documentation: halcompile --install-doc

then you can view it with 'man 9 ddt' When you try writing documentation, you'll discover that it's

hard.

Page 11: Halcompile Developing realtime components for LinuxCNC

Other requirements

Code has to be "quick" typical servo period, 1ms typical base period, 25µs

Only certain APIs can be used If you must loop, have a strict limit Look at .time, .tmax hal parameters

these are in CPU cycles on x86, nanoseconds on ARM

Page 12: Halcompile Developing realtime components for LinuxCNC

Hardware access

It can be done with comp But often hardware drivers are complicated and

better written in pure "C" ISA, PCI UDP Ethernet (for 2.7/master with uspace) A realtime hardware driver might not be needed

Bed temperature: OK if delayed by 1s Stepper motor position: critical to know within 1ms≪

Page 13: Halcompile Developing realtime components for LinuxCNC

Documentation

Introduction to HAL http://linuxcnc.org/docs/html/hal/intro.html

Syntax of comp itself, with examples: http://linuxcnc.org/docs/html/hal/comp.html I omitted a lot of comp features in this short talk

HAL and RTAPI APIs: http://linuxcnc.org/docs/html/#man3hal

Source code for other components https://github.com/jepler/linuxcnc-mirror/tree/master/src/hal/

components

Page 14: Halcompile Developing realtime components for LinuxCNC

Let's live code something

cubic bezier interpolation A smooth curve with two end points and two

points giving direction u=1-t

f(t) = u³P₀ + tu²P₁ + t²uP₂ + t³P₃

http://en.wikipedia.org/wiki/Bezier_curve

Page 15: Halcompile Developing realtime components for LinuxCNC

Code

component cubic; license "GPL";pin in float in;pin out float out;param rw float p#[4];function _;;;double t = in, u=1-t;out = u*u*u*p(0) + u*u*t*p(1) + u*t*t*p(2) + t*t*t*p(3);

Page 16: Halcompile Developing realtime components for LinuxCNC

Hal harness

loadrt threadsloadrt siggenloadrt cubic

setp cubic.0.p0 0setp cubic.0.p1 .2setp cubic.0.p2 .8setp cubic.0.p3 1setp siggen.0.offset .5setp siggen.0.amplitude .5

net t siggen.0.sawtooth => cubic.0.innet c <= cubic.0.out

addf siggen.0.update thread1addf cubic.0 thread1

start

Page 17: Halcompile Developing realtime components for LinuxCNC

Scope it$ halrun -I harness.halhalcmd: loadusr halscope