Discussion:
[Emc-users] Reading config values with a realtime HAL module.
Les Newell
2017-06-30 21:46:48 UTC
Permalink
Is it possible for a real time HAL module to read config values from
disk? I guess I could do it the ugly way and have two modules, one in
user space to read the disk and pass values to the mealtime module.

My lathe is pretty worn near the headstock so it tends to turn tapers
when working near the chuck. I want to write a kinematics module to
compensate for this taper, basically adding an offset to X depending on
the Z position. To do this I need to pass values to the kinematics
module in a similar way to leadscrew compensation.

In the previous setup I had a simple kinematics-ish module just before X
PID but it was a hack and didn't work very well, with all of the values
hard coded. It also did ugly things when homing.

Les
Sebastian Kuzminsky
2017-06-30 22:02:12 UTC
Permalink
Post by Les Newell
Is it possible for a real time HAL module to read config values from
disk? I guess I could do it the ugly way and have two modules, one in
user space to read the disk and pass values to the mealtime module.
Realtime modules can not do file I/O.

If you have only a few (up to maybe a few dozen?) values to pass in,
consider using HAL pins set from INI variables at load time.
--
Sebastian Kuzminsky
Chris Albertson
2017-06-30 22:05:17 UTC
Permalink
Is it possible for a real time HAL module to read config values from disk?
I guess I could do it the ugly way and have two modules, one in user space
to read the disk and pass values to the mealtime module.
That is not "ugly" is the common why things are done in real-time systems.
You try as hard as you can to push everything you can into user space.

What you describe is actually "best practice".

Look even at the normal Linux kernel. Typically an interrupt handler might
read data off the interface then flip a bit and that's it. Processing the
data happens in a user space task. Very common design pattern used over
and over.

I'm doing other work right now in a different area (not MK) and I'm using a
full on actual RTOS (Not Linux based) and a common structure I use is the
"work queue" I'll do minimum processing in the real time task then place a
task on the queue. Then background non-real time tasks pull work requests
off the queue. This is the "Computer Science 101" text book design that
was like used back in the 1950's
--
Chris Albertson
Redondo Beach, California
Les Newell
2017-07-01 10:28:41 UTC
Permalink
Post by Chris Albertson
That is not "ugly" is the common why things are done in real-time systems.
You try as hard as you can to push everything you can into user space.
What you describe is actually "best practice".
Look even at the normal Linux kernel. Typically an interrupt handler might
read data off the interface then flip a bit and that's it. Processing the
data happens in a user space task. Very common design pattern used over
and over.
I'm not talking about file I/O while running in real time. The task is
started from user space so at startup you have access to user space.
That is how command line config values are passed to the real-time task.
I was hoping there would be some way to make use of that to load config
values from a file instead of the command line.

By ugly I was talking about setting up shared memory communications
simply to pass config values once at startup. It is also untidy from the
user's viewpoint. They need to load two modules even though one is going
to simply read from a file, squirt those values to the HAL module then exit.
Post by Chris Albertson
I'm doing other work right now in a different area (not MK) and I'm using a
full on actual RTOS (Not Linux based) and a common structure I use is the
"work queue" I'll do minimum processing in the real time task then place a
task on the queue. Then background non-real time tasks pull work requests
off the queue. This is the "Computer Science 101" text book design that
was like used back in the 1950's
Of course you keep the real-time task as lean as possible. I'm fully
aware of that and have also done plenty of RTOS stuff. I've even written
my own cooperative + preemptive real-time multi-tasking OS for one
project where space and cpu were so constrained no off-the-shelf RTOS
would work. That one raised a few eyebrows when I wrote it in C++. A lot
of people think C++ is more bloated and slower than C but it all comes
down to how you use it.

Les
Les Newell
2017-07-02 13:16:14 UTC
Permalink
Post by Les Newell
By ugly I was talking about setting up shared memory communications
simply to pass config values once at startup. It is also untidy from
the user's viewpoint. They need to load two modules even though one is
going to simply read from a file, squirt those values to the HAL
module then exit.
After looking though the docs I found this in comp:
/option userinit yes/ - (default: no) This option is ignored if the
option /userspace/ (see above) is set to /no/. If /userinit/ is
specified, the function /userinit(argc,argv)/ is called before
/rtapi_app_main()/ (and thus before the call to /hal_init()/ ). This
function may process the commandline arguments or take other actions.
Its return type is /void/; it may call /exit()/ if it wishes to
terminate rather than create a HAL component (for instance, because the
commandline arguments were invalid).

This is exactly what I am after. It runs in user space so I can grab the
table from a file before the module starts running in HAL space. I was
sure something like that had to exist internally but it is nice to know
it is easily available.

Les
John Kasunich
2017-07-02 00:47:12 UTC
Permalink
Post by Les Newell
Is it possible for a real time HAL module to read config values from
disk? I guess I could do it the ugly way and have two modules, one in
user space to read the disk and pass values to the mealtime module.
My lathe is pretty worn near the headstock so it tends to turn tapers
when working near the chuck. I want to write a kinematics module to
compensate for this taper, basically adding an offset to X depending on
the Z position. To do this I need to pass values to the kinematics
module in a similar way to leadscrew compensation.
In the previous setup I had a simple kinematics-ish module just before X
PID but it was a hack and didn't work very well, with all of the values
hard coded. It also did ugly things when homing.
Les
How many points do you need? If 16 or less, check out the lincurve component
http://linuxcnc.org/docs/html/man/man9/lincurve.9.html
--
John Kasunich
***@fastmail.fm
Les Newell
2017-07-02 08:07:56 UTC
Permalink
Hi John,

The problem is that bed wear or spindle misalignment causes
cross-coupling between the X and Z axes, which is why it needs to be
done in kinematics.

Les
How many points do you need? If 16 or less, check out the lincurve
component
http://linuxcnc.org/docs/html/man/man9/lincurve.9.html
andy pugh
2017-07-02 19:23:13 UTC
Permalink
The problem is that bed wear or spindle misalignment causes cross-coupling
between the X and Z axes, which is why it needs to be done in kinematics.
Putting the Z axis position into the input of "lincurve" could give
you an output to apply as an offset to the X position command.
--
atp
"A motorcycle is a bicycle with a pandemonium attachment and is
designed for the especial use of mechanical geniuses, daredevils and
lunatics."
— George Fitch, Atlanta Constitution Newspaper, 1916
Les Newell
2017-07-03 10:16:29 UTC
Permalink
Hi Andy,
Post by andy pugh
Putting the Z axis position into the input of "lincurve" could give
you an output to apply as an offset to the X position command.
You need to go both ways. You need to offset the command and do a
reverse offset on the feedback. Yes, I could use the generated offset
then add extra modules to do the addition and subtraction but it all
gets a bit messy. That is pretty much how I used to do it, though I
stuck everything in one module. However this is exactly what kinematics
are made for so it makes sense to use them.

Les
andy pugh
2017-07-03 12:15:36 UTC
Permalink
You need to go both ways. You need to offset the command and do a reverse
offset on the feedback.
There is a HAL module for that:
http://linuxcnc.org/docs/devel/html/man/man9/offset.9.html

Or there is an exerimental branch with the option built-in
https://github.com/LinuxCNC/linuxcnc/commit/08ca67aa0efb5c32b2f17032810d406face2b7c3
--
atp
"A motorcycle is a bicycle with a pandemonium attachment and is
designed for the especial use of mechanical geniuses, daredevils and
lunatics."
— George Fitch, Atlanta Constitution Newspaper, 1916
Les Newell
2017-07-03 12:59:40 UTC
Permalink
Post by andy pugh
http://linuxcnc.org/docs/devel/html/man/man9/offset.9.html
So I see. I missed John's original link to the offset module. Doing
something similar to that worked on my lathe but I did have some homing
issues. That was on a very old version of LinuxCNC so homing may handle
it better now.

On my lathe I will probably keep with using kinematics as it is then
before backlash compensation rather than after.

Les
andy pugh
2017-07-03 17:58:33 UTC
Permalink
On my lathe I will probably keep with using kinematics as it is then before
backlash compensation rather than after.
It seems likely to be a very simple kinematics module, and so will
probably compile easily with halcompile.
At that point it might be pragmatic to simply store the offset data
hard-coded into the kins module.
--
atp
"A motorcycle is a bicycle with a pandemonium attachment and is
designed for the especial use of mechanical geniuses, daredevils and
lunatics."
— George Fitch, Atlanta Constitution Newspaper, 1916
Dave Caroline
2017-07-04 05:28:43 UTC
Permalink
For probe compensation batch reading would be far more useful than compiled in,
then it becomes simple to read the compensation file for any stylus
you change too.

Dave Caroline
John Kasunich
2017-07-05 01:43:26 UTC
Permalink
Kind of a kludge, but the streamer/ halstreamer system could do what you are describing.
The component that wants to use the data would export a clock pin and one or more input pins.
Each edge of the clock pin delivers a value (or set of values) from an external file.

In this application, it would only be clocked during startup. Once the necessary data is transferred the streamer part (realtime) would sit idle, and the halstreamer part (user space) would terminate.

http://linuxcnc.org/docs/html/man/man9/streamer.9.html
http://linuxcnc.org/docs/html/man/man1/halstreamer.1.html
Post by Dave Caroline
For probe compensation batch reading would be far more useful than compiled in,
then it becomes simple to read the compensation file for any stylus
you change too.
Dave Caroline
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Emc-users mailing list
https://lists.sourceforge.net/lists/listinfo/emc-users
--
John Kasunich
***@fastmail.fm
andy pugh
2017-07-05 10:42:25 UTC
Permalink
Post by John Kasunich
Kind of a kludge, but the streamer/ halstreamer system could do what you are describing.
Another way:

INI files can use #INCLUDE
http://linuxcnc.org/docs/2.7/html/config/ini-config.html#_include_files

{.ini file}
[KINS]
#INCLUDE corrections.inc
...

{.inc file}
ZVALS = 0,10,20,30,40,50,60,70
XVALS = 0,0.1,-0.3,0.7.......

{.hal file}
loadrt mykins zvals=[KINS]ZVALS xvals=[KINS]XVALS
--
atp
"A motorcycle is a bicycle with a pandemonium attachment and is
designed for the especial use of mechanical geniuses, daredevils and
lunatics."
— George Fitch, Atlanta Constitution Newspaper, 1916
Les Newell
2017-07-05 11:14:43 UTC
Permalink
Thanks Andy, I was going to ask if there was an include function for ini
files. My lathe runs two configs, one with the tool turret installed and
one without. My turret is tiny and only suitable for a few jobs. It is
so small it can be mounted on one of the QC tool holders. Currently I
run two separate ini files but it would be much better to stick all of
config values that are common into an inc file.

The next question, is it possible to repeat sections? For instance in
[RS274NGC] I have different parameter files for each config. All other
values are the same. It would be nice to have a [RS274NGC] section in my
main config to specify the parameter file and another [RS274NGC] section
in my inc file to specify everything else that is common between the two
configs. To be honest this is purely icing on the cake. Just having
#INCLUDE makes a big difference. Repeating a few sections is not a real
problem.

As far as the original question goes, I probably won't bother with the
kinematics module. I spent a day on the machine, realigning the spindle
and generally going through the machine and readjusting everything. The
error is a lot smaller now and realistically within the limits of
anything I normally want to make. I'm surprised how good it is
considering this machine spent most of it's life with a non-functional
lube pump. As far as I can tell someone forgot to fit the foot valve
ball when they originally assembled it!

Les
Post by John Kasunich
of a kludge, but the streamer/ halstreamer system could do what you are describing.
INI files can use #INCLUDE
http://linuxcnc.org/docs/2.7/html/config/ini-config.html#_include_files
{.ini file}
[KINS]
#INCLUDE corrections.inc
...
{.inc file}
ZVALS = 0,10,20,30,40,50,60,70
XVALS = 0,0.1,-0.3,0.7.......
{.hal file}
loadrt mykins zvals=[KINS]ZVALS xvals=[KINS]XVALS
andy pugh
2017-07-05 11:24:57 UTC
Permalink
Post by Les Newell
The next question, is it possible to repeat sections? For instance in
[RS274NGC] I have different parameter files for each config. All other
values are the same. It would be nice to have a [RS274NGC] section in my
main config to specify the parameter file and another [RS274NGC] section in
my inc file to specify everything else that is common between the two
configs
I don't think so, but it's an easy experiment.
--
atp
"A motorcycle is a bicycle with a pandemonium attachment and is
designed for the especial use of mechanical geniuses, daredevils and
lunatics."
— George Fitch, Atlanta Constitution Newspaper, 1916
Loading...