/*
* Copyright (c) 2009-2010 Hypertriton, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
extern char *__progname;
char mpg_device[FILENAME_MAX];
int verbose = 1;
int simulate = 0;
struct cnc_velocity vel;
struct cnc_vector pos;
static void
printusage(void)
{
printf("Usage: %s [-nq] [-t seconds] [-d mpgdevice] [-M multiplier] "
"[-S startvel] [-F feedrate] [-A accellim] "
"[-J jerklim]\n", __progname);
}
static void
process_timeout(int signo)
{
int save_errno = errno;
if (!simulate &&
cncmove(&vel, &pos) != 0)
err(1, "cncmove");
errno = save_errno;
}
int
main(int argc, char *argv[])
{
char pb[128];
struct cnc_mpg_event me;
int i, ch, mpgfd = -1, cncfd;
int mult = 4000;
struct itimerval timeout;
ssize_t rv;
if (cnc_init() == -1) {
errx(1, "%s", cnc_get_error());
}
atexit(cnc_destroy);
vel = cnc_vel_default;
mpg_device[0] = '\0';
memset(&timeout, 0, sizeof(timeout));
timeout.it_value.tv_sec = 0;
timeout.it_value.tv_usec = 500000;
while ((ch = getopt(argc, argv, "nqt:d:M:S:F:A:J:?hv")) != -1) {
switch (ch) {
case 'n':
simulate = 1;
break;
case 'q':
verbose = 0;
break;
case 't':
timeout.it_value.tv_sec = (long)atoi(optarg);
break;
case 'd':
strlcpy(mpg_device, optarg, sizeof(mpg_device));
break;
case 'M':
mult = atoi(optarg);
break;
case 'S':
cnc_vel_parse(&vel.v0, optarg);
break;
case 'F':
cnc_vel_parse(&vel.F, optarg);
break;
case 'A':
cnc_vel_parse(&vel.Amax, optarg);
break;
case 'J':
cnc_vel_parse(&vel.Jmax, optarg);
break;
default:
printusage();
return (1);
}
}
/* Retrieve the current machine position. */
if ((cncfd = open("/dev/cnc", O_RDONLY)) == -1) {
err(1, "/dev/cnc");
}
if (ioctl(cncfd, CNC_GETPOS, &pos) == -1) {
errx(1, "CNC_GETPOS");
}
if (verbose) {
cnc_vec_print(&pos, pb, sizeof(pb));
printf("Starting at %s\n", pb);
}
close(cncfd);
/* Open the MPG device for reading. */
if (mpg_device[0] != '\0') {
mpgfd = open(mpg_device, O_RDONLY);
} else {
for (i = 0; i < 10; i++) {
snprintf(mpg_device, sizeof(mpg_device), "/dev/mpg%d", i);
if ((mpgfd = open(mpg_device, O_RDONLY)) != -1)
break;
}
}
if (mpgfd == -1)
err(1, mpg_device);
signal(SIGALRM, process_timeout);
/* Loop reading MPG events. */
for (;;) {
rv = read(mpgfd, &me, sizeof(struct cnc_mpg_event));
if (rv == -1) {
if (errno == EINTR) {
continue;
}
err(1, "read");
} else if (rv < sizeof(struct cnc_mpg_event)) {
break;
}
if (me.delta == 0) {
continue;
}
if (me.axis < 0 || me.axis > CNC_MAX_AXES) {
errx(1, "invalid axis");
}
if (me.delta < 0) {
pos.v[me.axis] -= mult;
} else {
pos.v[me.axis] += mult;
}
if (verbose) {
cnc_vec_print(&pos, pb, sizeof(pb));
printf("Moving axis%d (target %s)\n", me.axis, pb);
}
setitimer(ITIMER_REAL, &timeout, NULL);
}
close(mpgfd);
return (0);
}