diff --git a/tests/tool-frame/skip b/tests/tool-frame/skip index ee99160224a..a12f31a77c2 100755 --- a/tests/tool-frame/skip +++ b/tests/tool-frame/skip @@ -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" ] diff --git a/tests/tool-frame/test.sh b/tests/tool-frame/test.sh index 2dae535797b..1697d5f4a27 100755 --- a/tests/tool-frame/test.sh +++ b/tests/tool-frame/test.sh @@ -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" diff --git a/tests/tool-frame/test_tool_frame.c b/tests/tool-frame/toolframecheck.c similarity index 96% rename from tests/tool-frame/test_tool_frame.c rename to tests/tool-frame/toolframecheck.c index 00103cb4678..ceab3acee12 100644 --- a/tests/tool-frame/test_tool_frame.c +++ b/tests/tool-frame/toolframecheck.c @@ -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 -#include -#include -#include "emcpos.h" -#include "kinematics.h" +#include +#include +#include +#include +#include +#include +#include +#include + +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, @@ -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; @@ -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); }