Discussion:
[Emc-users] Controlling LinuxCNC externally with C++ program
Walter Cigana
2013-10-21 06:22:11 UTC
Permalink
Hi all,

I am still Learning LinuxCNC and I again have a few questions.

I am trying to figure out the best way to "drive" LinuxCNC from a C++
program.

This program would receive general commands from the user, something
like: "execute procedure 1" and translate this into telling LinuxCNC to
open a specific file and run the G-code therein.

I saw that there is a Python interface:
http://www.linuxcnc.org/docs/html/common/python-interface.html#_the_linuxcnc_python_module

The doc states that "Programmatic access to NML is through a C++ API;
however, the most important parts of the NML interface to Linuxcnc are also
available to Python programs through the linxuxcnc module."

I do not really feel like learning Python, but I cannot find the C++ way to
do this. I have seen some documentation, but nothing specific and I cannot
find any examples.

Ideally, I could just use an API from my program. Can someone point me in
the right direction???

thanks,
Walter
Schooner
2013-10-21 13:21:23 UTC
Permalink
Post by Walter Cigana
I am trying to figure out the best way to "drive" LinuxCNC from a C++
program.
This program would receive general commands from the user, something
like: "execute procedure 1" and translate this into telling LinuxCNC to
open a specific file and run the G-code therein.
If you are using Linuxcnc to control a CNC machine in the normal manner,
but just want to be able to make it run a program from another
application, axis-remote could be the simplest method from a system() call

There is even an Axis hack and modified axis-remote here
http://www.linuxcnc.org/index.php/english/forum/38-general-linuxcnc-questions/26061-automated-change-nc-program-possible#28920

which I wrote to allow a program to be loaded and then run remotely.

This was for someone who wanted to be able to script the generation of G
Code to engrave incrementing serial numbers and then output it to Axis
and automatically run the program.

You can write programs in C++ which directly control everything, I wrote
Qt libraries which do that, but it is non trivial and depending upon
what you wish to achieve, perhaps not necessary

If you want to dig into it, look at the sources for xemc, halui &
halcmd. They will uncover most of the calls and show how they are used

regards
Jeff Epler
2013-10-21 14:05:37 UTC
Permalink
xemc.cc is a C++ program that uses the relevant APIs. It is far from
being tutorial documentation, but at present we don't *have* any
tutorial documentation about using these APIs.

(such documentation would be a great contribution to LinuxCNC. You
could start with a new page on the wiki and later work with someone like
John Thornton to get it integrated into the offical documentation. if
you are so inclined)

Anyway, here's a complete program that uses the C++ interface to log the
position at about 10Hz:

#include "emc.hh"
#include "emc_nml.hh"
#include <unistd.h>
#include <iostream>
#include <cstdlib>

int main(int argc, char **argv) {
if(argc < 2) { std::cerr << "Usage: " << argv[0] << " NMLFILE\n"; abort(); }
const char *nmlfile = argv[1];
RCS_STAT_CHANNEL *stat = new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "xemc", nmlfile);
while(1) {
usleep(100*1000);
if(!stat->valid()) continue;
if(stat->peek() != EMC_STAT_TYPE) continue;
EMC_STAT *emcStatus = static_cast<EMC_STAT*>(stat->get_address());
std::cout << emcStatus->motion.traj.position.tran.x << " "
<< emcStatus->motion.traj.position.tran.y << " "
<< emcStatus->motion.traj.position.tran.z << "\n";
}
return 0;
}

In a run-in-place version of v2.5_branch it builds with this commandline:
g++ -o nml-position-logger nml-position-logger.cc -Iinclude -Llib -lnml -llinuxcnc
(and probably it will build from the package version if you have the -dev
package installed, but I didn't test this)

in master branch it looks like we have a regression so the commandline required is:
g++ -o nml-position-logger nml-position-logger.cc -Iinclude -Isrc/emc/rs274ngc -Llib -lnml -llinuxcnc
and a -dev package will not include at least one of the required headers.

To use this program you would start linuxcnc with a traditional UI and
then execute the program with the path to linuxcnc.nml. For example
if you're at the top dirctory of a run-in-place linuxcnc:
./nml-position-logger configs/common/linuxcnc.nml
.. press ctrl-c to exit.

To send commands you will use an RCS_CMD_CHANNEL:
// command channel
RCS_CMD_CHANNEL *cmd =
new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "xemc", file);
int emcCommandSerialNumber = 0;
and sending a command consists of something like
EMC_TASK_ABORT m;
m.serial_number = ++emcCommandSerialNumber;
// most commands have other fields that must be initialized
// such as EMC_TASK_SET_MODE::mode
cmd->write(m);
// at this point, many UIs have logic to "wait for task to receive
// the command", though xemc does not

To recieve error notices create an error connection
// error channel
NML *error = new NML(emcFormat, "emcError", "xemc", file);
and poll it like yo usee in xemc.cc:updateError(). Note that when
multiple UIs exist which poll for errors, only one of them will receive
the error.

The string "xemc" which occurs in several places is a magic string; you
will just want to leave it unchanged.

Jeff
Frank Tkalcevic
2013-10-21 21:45:47 UTC
Permalink
As has been mentioned before, using linuxcncrsh may do all that you need.
It can open files, start/stop runs, return status etc.

It is a simple telnet interface, so you just need a socket connection and
then send text commands down the line. There is a Java example in the forum


http://www.linuxcnc.org/index.php/english/forum/21-axis/21678-controlling-li
nuxcncrsh-from-a-java-program

Or, you can look at the linuxcncrsh source to see an example of remote
control.

Be careful though, the linuxcncrsh code has been changed so that it must be
the only GUI. If you try to run it with axis at the same time, linuxcnc
will eventually fail. The documentation still says that you can run it with
axis.


-----Original Message-----
From: Walter Cigana [mailto:***@gmail.com]
Sent: Monday, 21 October 2013 5:22 PM
To: Enhanced Machine Controller (EMC)
Subject: [Emc-users] Controlling LinuxCNC externally with C++ program

Hi all,

I am still Learning LinuxCNC and I again have a few questions.

I am trying to figure out the best way to "drive" LinuxCNC from a C++
program.

This program would receive general commands from the user, something
like: "execute procedure 1" and translate this into telling LinuxCNC to open
a specific file and run the G-code therein.

I saw that there is a Python interface:
http://www.linuxcnc.org/docs/html/common/python-interface.html#_the_linuxcnc
_python_module

The doc states that "Programmatic access to NML is through a C++ API;
however, the most important parts of the NML interface to Linuxcnc are also
available to Python programs through the linxuxcnc module."

I do not really feel like learning Python, but I cannot find the C++ way to
do this. I have seen some documentation, but nothing specific and I cannot
find any examples.

Ideally, I could just use an API from my program. Can someone point me in
the right direction???

thanks,
Walter
----------------------------------------------------------------------------
--
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most
from the latest Intel processors and coprocessors. See abstracts and
register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk
Walter Cigana
2013-11-03 15:04:05 UTC
Permalink
Hi again,

So, I have played with the xemc.cc code to uncover some C++ interfaces and
I have also played with using linuxcncrsh to control remotely, which is
obviously simpler.

In my situation, I also need to monitor an analog input which will return a
voltage.

I have an example of doing something similar in Axis, with signals defined
in the HAL file and the appropriate overlay file definition.

Is there a way of accessing this same type of data through linuxcncrsh, or
will I need to code this specific access myself?

thanks again,
Walter


On Mon, Oct 21, 2013 at 5:45 PM, Frank Tkalcevic <
Post by Frank Tkalcevic
As has been mentioned before, using linuxcncrsh may do all that you need.
It can open files, start/stop runs, return status etc.
It is a simple telnet interface, so you just need a socket connection and
then send text commands down the line. There is a Java example in the forum
http://www.linuxcnc.org/index.php/english/forum/21-axis/21678-controlling-li
nuxcncrsh-from-a-java-program
Or, you can look at the linuxcncrsh source to see an example of remote
control.
Be careful though, the linuxcncrsh code has been changed so that it must be
the only GUI. If you try to run it with axis at the same time, linuxcnc
will eventually fail. The documentation still says that you can run it with
axis.
-----Original Message-----
Sent: Monday, 21 October 2013 5:22 PM
To: Enhanced Machine Controller (EMC)
Subject: [Emc-users] Controlling LinuxCNC externally with C++ program
Hi all,
I am still Learning LinuxCNC and I again have a few questions.
I am trying to figure out the best way to "drive" LinuxCNC from a C++
program.
This program would receive general commands from the user, something
like: "execute procedure 1" and translate this into telling LinuxCNC to open
a specific file and run the G-code therein.
http://www.linuxcnc.org/docs/html/common/python-interface.html#_the_linuxcnc
_python_module
The doc states that "Programmatic access to NML is through a C++ API;
however, the most important parts of the NML interface to Linuxcnc are also
available to Python programs through the linxuxcnc module."
I do not really feel like learning Python, but I cannot find the C++ way to
do this. I have seen some documentation, but nothing specific and I cannot
find any examples.
Ideally, I could just use an API from my program. Can someone point me in
the right direction???
thanks,
Walter
----------------------------------------------------------------------------
--
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most
from the latest Intel processors and coprocessors. See abstracts and
register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk
_______________________________________________
Emc-users mailing list
https://lists.sourceforge.net/lists/listinfo/emc-users
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most
from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135991&iu=/4140/ostg.clktrk
_______________________________________________
Emc-users mailing list
https://lists.sourceforge.net/lists/listinfo/emc-users
Sebastian Kuzminsky
2013-11-03 16:12:06 UTC
Permalink
Post by Walter Cigana
So, I have played with the xemc.cc code to uncover some C++ interfaces and
I have also played with using linuxcncrsh to control remotely, which is
obviously simpler.
In my situation, I also need to monitor an analog input which will return a
voltage.
I have an example of doing something similar in Axis, with signals defined
in the HAL file and the appropriate overlay file definition.
Is there a way of accessing this same type of data through linuxcncrsh, or
will I need to code this specific access myself?
If you're on the master branch (not 2.5) you can do this.

In you .ini file, add this:
[RS274NGC]
FEATURES=8

Then in linuxcncrsh you can read HAL pins & signals like this:

set mdi (debug, #<_hal[axis.1.f-error-lim]>)
get operator_display
OPERATOR_DISPLAY 0.010000

Partial docs for this feature are here:

http://www.linuxcnc.org/docs/devel/html/remap/structure.html#_named_parameters_and_hal_items_a_id_remap_referto_hal_items_a
--
Sebastian Kuzminsky
Jeff Epler
2013-11-04 13:33:25 UTC
Permalink
Post by Sebastian Kuzminsky
set mdi (debug, #<_hal[axis.1.f-error-lim]>)
get operator_display
OPERATOR_DISPLAY 0.010000
Personally, I discourage use of this feature, because it ignores one of
the main points of linuxcnc's hal: the relationship between pins is
created not by hardcoding the name of the pin whose value you are
interested in in your program, but by allowing the user/integrator to
connect pins to other pins via signals.

As a concrete example: suppose you have some kind of signal you want to
wait on from gcode. If you have a O-while loop on
#<_hal[parport.0.pin-10-in> then your part programs are not portable to
a machine which uses mesa hardware instead.

gcode provides proper access to digital and analog inputs and outputs
via M62 through M67. These correspond to pins on the motion controller
that you can properly connect via hal 'net' commands.

Jeff
andy pugh
2013-11-04 13:47:36 UTC
Permalink
Post by Jeff Epler
Post by Sebastian Kuzminsky
set mdi (debug, #<_hal[axis.1.f-error-lim]>)
get operator_display
OPERATOR_DISPLAY 0.010000
Personally, I discourage use of this feature, because it ignores one of
...
Post by Jeff Epler
As a concrete example: suppose you have some kind of signal you want to
wait on from gcode. If you have a O-while loop on
#<_hal[parport.0.pin-10-in> then your part programs are not portable to
a machine which uses mesa hardware instead.
I am not sure if the feature can read signals as well as pins.
Using a signal would address the portability problem.

I see your point, but also suspect that any setup using this system
with this degree G-code-to-HAL linkage is likely to be rather
importable anyway.

I used this for my lathe macros as an easy way to get values from a
GladeVCP GUI into G-code. Reading the spinbox values into G-code
without any hal-coding being needed suited my laziness, while
admittedly undermining the whole point of HAL being the mediator of
data transactions. I guess I should at the very least have had the
G-code reading signal values so that there was the option of
re-directing them.
--
atp
If you can't fix it, you don't own it.
http://www.ifixit.com/Manifesto
Loading...