Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/tool-frame/skip
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
# This test compiles kins_util.c from the source tree, which is only
# available in run-in-place builds. Skip when testing installed packages.
# Builds a realtime component with halcompile, which needs the build
# tools present. Skip when testing installed packages.
[ -z "$SYSTEM_BUILD" ]
21 changes: 8 additions & 13 deletions tests/tool-frame/test.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
#!/bin/bash
set -e

# RIP layout: $HEADERS is $TOPDIR/include
TOPDIR=$(dirname "$HEADERS")
halcompile --install toolframecheck.c >/dev/null

# kins_util.c holds the shared kinematics helpers. Only the tool frame ones
# are exercised here, so build with function sections and let the linker drop
# the rest rather than dragging in the HAL pin setup the others need.
gcc -O2 -Wall -ffunction-sections -fdata-sections -DULAPI \
-I"$HEADERS" -I"$TOPDIR/src" -I"$TOPDIR/src/emc" \
-o test_tool_frame test_tool_frame.c "$TOPDIR/src/emc/kinematics/kins_util.c" \
-L"$LIBDIR" -Wl,-rpath,"$LIBDIR" -Wl,--gc-sections \
-lposemath -llinuxcnchal -lm

./test_tool_frame
rm -f test_tool_frame
# switchkins_core exports the kins_util.c helpers and provides no
# kinematics of its own, so the checker reaches them as motion's
# kinematics module would
hal=$(mktemp --suffix=.hal)
printf 'loadrt switchkins_core\nloadrt toolframecheck\n' > "$hal"
halrun -f "$hal"
rm -f "$hal"
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
/* Unit tests for the tool frame helpers in kins_util.c.
*
* Loaded after switchkins_core, which exports the helpers, so they are
* checked as built for realtime. A failed check fails the load, and a
* failed load fails the test.
*
* The property worth pinning down is that relating one tool axis convention
* to the other is a rotation and not a change of sign: negating the third
* column on its own leaves a reflection, which is not a frame any machine can
* hold, and it silently loses tool x as well.
*
* Author: LinuxCNC
* License: GPL Version 2
* System: Linux
*
* Copyright (c) 2026 All rights reserved.
*/
#include <stdio.h>
#include <math.h>
#include <string.h>

#include "emcpos.h"
#include "kinematics.h"
#include <rtapi.h>
#include <rtapi_app.h>
#include <rtapi_errno.h>
#include <rtapi_math.h>
#include <rtapi_string.h>
#include <hal.h>
#include <emcpos.h>
#include <kinematics.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("tool frame helper checker");

#define DEG (M_PI/180.0)
#define NUTATION 45.0

static int comp_id = -1;
static int failures;

static void check(int ok, const char *what)
{
if (!ok) { printf("FAIL: %s\n", what); failures++; }
if (!ok) {
rtapi_print_msg(RTAPI_MSG_ERR, "toolframecheck: FAIL %s\n", what);
failures++;
}
}

static PmRotationMatrix mat(double xx, double yx, double zx,
Expand Down Expand Up @@ -217,7 +237,7 @@ static int holds(const double *sols, int count, int njoints,
return 0;
}

int main(void)
static void run_checks(void)
{
PmRotationMatrix m, r;

Expand Down Expand Up @@ -650,7 +670,25 @@ int main(void)
"a missing target is refused");
}

if (failures) { printf("%d failure(s)\n", failures); return 1; }
printf("all tool frame checks passed\n");
}

int rtapi_app_main(void)
{
comp_id = hal_init("toolframecheck");
if (comp_id < 0) { return comp_id; }

run_checks();

if (failures) {
rtapi_print_msg(RTAPI_MSG_ERR, "toolframecheck: %d check(s) failed\n",
failures);
hal_exit(comp_id);
return -ERANGE;
}

rtapi_print("toolframecheck: all tool frame checks passed\n");
hal_ready(comp_id);
return 0;
}

void rtapi_app_exit(void) { hal_exit(comp_id); }
Loading