From d936e9f10cc175cdd80948f48176e081a3e29753 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Sun, 7 Jun 2026 19:44:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E6=8E=A8=E8=8D=90=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=EF=BC=8C=E7=BB=A7=E7=BB=AD=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:继续按 LinuxCNC 源码直接复用路线推进,新增 corexy、rotate、rose、max 四个运动学源码的 vendored 同步、native 探针、source probe 覆盖和复用文档,并通过 native 验证。 --- wasm-port/docs/source-reuse-map.md | 4 +- .../linuxcnc_corexy_kinematics_probe.cpp | 91 +++++++++++ .../linuxcnc_max_kinematics_probe.cpp | 91 +++++++++++ .../linuxcnc_rose_kinematics_probe.cpp | 72 +++++++++ .../linuxcnc_rotate_kinematics_probe.cpp | 91 +++++++++++ .../tests/native/verify_native_probes.sh | 44 ++++++ wasm-port/tools/build_native_probes.sh | 136 ++++++++++++++++ wasm-port/tools/source-manifest.txt | 4 + .../linuxcnc/src/emc/kinematics/corexykins.c | 89 +++++++++++ .../linuxcnc/src/emc/kinematics/maxkins.c | 148 ++++++++++++++++++ .../linuxcnc/src/emc/kinematics/rosekins.c | 143 +++++++++++++++++ .../linuxcnc/src/emc/kinematics/rotatekins.c | 96 ++++++++++++ 12 files changed, 1008 insertions(+), 1 deletion(-) create mode 100644 wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_corexy_kinematics_probe.cpp create mode 100644 wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_max_kinematics_probe.cpp create mode 100644 wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rose_kinematics_probe.cpp create mode 100644 wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rotate_kinematics_probe.cpp create mode 100644 wasm-port/vendor/linuxcnc/src/emc/kinematics/corexykins.c create mode 100644 wasm-port/vendor/linuxcnc/src/emc/kinematics/maxkins.c create mode 100644 wasm-port/vendor/linuxcnc/src/emc/kinematics/rosekins.c create mode 100644 wasm-port/vendor/linuxcnc/src/emc/kinematics/rotatekins.c diff --git a/wasm-port/docs/source-reuse-map.md b/wasm-port/docs/source-reuse-map.md index 5f4e2f9..5a73827 100644 --- a/wasm-port/docs/source-reuse-map.md +++ b/wasm-port/docs/source-reuse-map.md @@ -38,6 +38,7 @@ Current validation is intentionally mechanical: | Identity/trivial kinematics | `src/emc/kinematics/kinematics.h`, `cubic.h`, `kins_util.c`, `trivkins.c` | Copy unchanged | HAL component lifecycle and RTAPI module metadata are replaced by standalone shims; forward/inverse mapping behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_kinematics_probe` | | Switchable 5-axis bridge kinematics | `src/emc/kinematics/5axiskins.c`, `switchkins.c`, `switchkins.h`, `userkfuncs.c`, plus `src/rtapi/rtapi_ctype.h` | Copy unchanged | HAL pin allocation, HAL component lifecycle, and RTAPI module metadata are standalone runtime edges; switchable 5-axis forward/inverse behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_5axis_kinematics_probe` | | TRT table-rotary kinematics | `src/emc/kinematics/trtfuncs.c`, `xyzac-trt-kins.c`, `xyzbc-trt-kins.c` | Copy unchanged | HAL pin allocation and switchkins lifecycle stay runtime boundaries; XYZAC/XYZBC TRT forward/inverse behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_xyzac_trt_kinematics_probe`, `linuxcnc_xyzbc_trt_kinematics_probe` | +| Additional non-switchable kinematics | `src/emc/kinematics/corexykins.c`, `rotatekins.c`, `rosekins.c`, `maxkins.c` | Copy unchanged | HAL pin allocation, HAL component lifecycle, and RTAPI module metadata are standalone runtime edges; forward/inverse behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_corexy_kinematics_probe`, `linuxcnc_rotate_kinematics_probe`, `linuxcnc_rose_kinematics_probe`, `linuxcnc_max_kinematics_probe` | | Trajectory planner | `src/emc/tp/tp.c`, `tc.c`, `tcq.c`, `spherical_arc.c`, `blendmath.c`, `sp_scurve.c`, `ruckig_wrapper.c`, plus matching `*.h` files | Copy unchanged | Native realtime scheduling and motion process state are replaced by standalone probe setup | Vendor byte sync, per-file source probes, `linuxcnc_tp_api_probe` | | Ruckig C planner support | Selected `src/emc/tp/cruckig/*.c` and `*.h` files in the manifest | Copy unchanged | Used as LinuxCNC planner support code through vendored TP sources | Vendor byte sync, per-file source probes | | Posemath | `src/libnml/posemath/posemath.cc`, `_posemath.c`, `gomath.c`, `sincos.c`, and matching headers | Copy unchanged | `gomath.c` is compiled as C; `rtapi.h` shim is C/C++ compatible for this boundary | Vendor byte sync, per-file source probes, TP probe | @@ -62,7 +63,8 @@ Current validation is intentionally mechanical: ## Known Gaps - Additional non-trivial kinematics implementation files, including serial, - delta, SCARA, and other machine-specific modules, are not yet extracted. + delta, SCARA, hexapod, tripod, and other machine-specific modules, are not + yet extracted. - Browser/WASM C ABI and JS SDK layers are not yet built for the full interpreter/planner core. - OPFS persistence is not yet connected to INI, tool table, parameter file, or diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_corexy_kinematics_probe.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_corexy_kinematics_probe.cpp new file mode 100644 index 0000000..583cfc7 --- /dev/null +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_corexy_kinematics_probe.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include "emc/kinematics/kinematics.h" +#include "emc/motion/emcmotcfg.h" + +int rtapi_app_main(void); +void rtapi_app_exit(void); + +namespace { + +int near(double actual, double expected) +{ + return std::fabs(actual - expected) < 1e-9; +} + +int near_joints(const double *actual, const double *expected) +{ + for (int index = 0; index < 9; ++index) { + if (!near(actual[index], expected[index])) { + return 0; + } + } + return 1; +} + +void print_pose(const char *prefix, const EmcPose &pose) +{ + std::cout << prefix << "_xyz=" + << pose.tran.x << "," + << pose.tran.y << "," + << pose.tran.z << "\n"; + std::cout << prefix << "_abcuvw=" + << pose.a << "," + << pose.b << "," + << pose.c << "," + << pose.u << "," + << pose.v << "," + << pose.w << "\n"; +} + +void print_joints(const char *prefix, const double *joints) +{ + std::cout << prefix << "_xyzabcuvw=" + << joints[0] << "," + << joints[1] << "," + << joints[2] << "," + << joints[3] << "," + << joints[4] << "," + << joints[5] << "," + << joints[6] << "," + << joints[7] << "," + << joints[8] << "\n"; +} + +} // namespace + +int main() +{ + const int init_rc = rtapi_app_main(); + std::cout << "corexy_init=" << init_rc << "\n"; + std::cout << "corexy_type=" << kinematicsType() << "\n"; + std::cout << "corexy_switchable=" << kinematicsSwitchable() << "\n"; + + double joints[EMCMOT_MAX_JOINTS]{}; + joints[0] = 12.0; + joints[1] = 4.0; + joints[2] = 3.0; + joints[3] = 4.0; + joints[4] = 5.0; + joints[5] = 6.0; + joints[6] = 7.0; + joints[7] = 8.0; + joints[8] = 9.0; + + KINEMATICS_FORWARD_FLAGS fflags = 0; + KINEMATICS_INVERSE_FLAGS iflags = 0; + EmcPose forward_pose{}; + const int forward_rc = kinematicsForward(joints, &forward_pose, &fflags, &iflags); + std::cout << "corexy_forward=" << forward_rc << "\n"; + print_pose("corexy_forward", forward_pose); + + double inverse_joints[EMCMOT_MAX_JOINTS]{}; + const int inverse_rc = kinematicsInverse(&forward_pose, inverse_joints, &iflags, &fflags); + std::cout << "corexy_inverse=" << inverse_rc << "\n"; + print_joints("corexy_inverse", inverse_joints); + std::cout << "corexy_roundtrip_joints=" << near_joints(inverse_joints, joints) << "\n"; + + rtapi_app_exit(); + return 0; +} diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_max_kinematics_probe.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_max_kinematics_probe.cpp new file mode 100644 index 0000000..9df3e50 --- /dev/null +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_max_kinematics_probe.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include "emc/kinematics/kinematics.h" +#include "emc/motion/emcmotcfg.h" + +int rtapi_app_main(void); +void rtapi_app_exit(void); + +namespace { + +int near(double actual, double expected) +{ + return std::fabs(actual - expected) < 1e-9; +} + +int near_joints(const double *actual, const double *expected) +{ + for (int index = 0; index < 9; ++index) { + if (!near(actual[index], expected[index])) { + return 0; + } + } + return 1; +} + +void print_pose(const char *prefix, const EmcPose &pose) +{ + std::cout << prefix << "_xyz=" + << pose.tran.x << "," + << pose.tran.y << "," + << pose.tran.z << "\n"; + std::cout << prefix << "_abcuvw=" + << pose.a << "," + << pose.b << "," + << pose.c << "," + << pose.u << "," + << pose.v << "," + << pose.w << "\n"; +} + +void print_joints(const char *prefix, const double *joints) +{ + std::cout << prefix << "_xyzabcuvw=" + << joints[0] << "," + << joints[1] << "," + << joints[2] << "," + << joints[3] << "," + << joints[4] << "," + << joints[5] << "," + << joints[6] << "," + << joints[7] << "," + << joints[8] << "\n"; +} + +} // namespace + +int main() +{ + const int init_rc = rtapi_app_main(); + std::cout << "max_init=" << init_rc << "\n"; + std::cout << "max_type=" << kinematicsType() << "\n"; + std::cout << "max_switchable=" << kinematicsSwitchable() << "\n"; + + double joints[EMCMOT_MAX_JOINTS]{}; + joints[0] = 10.0; + joints[1] = 20.0; + joints[2] = 30.0; + joints[3] = 4.0; + joints[4] = 0.0; + joints[5] = 25.0; + joints[6] = 0.0; + joints[7] = 0.0; + joints[8] = 3.5; + + KINEMATICS_FORWARD_FLAGS fflags = 0; + KINEMATICS_INVERSE_FLAGS iflags = 0; + EmcPose forward_pose{}; + const int forward_rc = kinematicsForward(joints, &forward_pose, &fflags, &iflags); + std::cout << "max_forward=" << forward_rc << "\n"; + print_pose("max_forward", forward_pose); + + double inverse_joints[EMCMOT_MAX_JOINTS]{}; + const int inverse_rc = kinematicsInverse(&forward_pose, inverse_joints, &iflags, &fflags); + std::cout << "max_inverse=" << inverse_rc << "\n"; + print_joints("max_inverse", inverse_joints); + std::cout << "max_roundtrip_joints=" << near_joints(inverse_joints, joints) << "\n"; + + rtapi_app_exit(); + return 0; +} diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rose_kinematics_probe.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rose_kinematics_probe.cpp new file mode 100644 index 0000000..a85601c --- /dev/null +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rose_kinematics_probe.cpp @@ -0,0 +1,72 @@ +#include +#include + +#include "emc/kinematics/kinematics.h" +#include "emc/motion/emcmotcfg.h" + +int rtapi_app_main(void); +void rtapi_app_exit(void); + +namespace { + +int near(double actual, double expected) +{ + return std::fabs(actual - expected) < 1e-9; +} + +int near_joints(const double *actual, const double *expected) +{ + for (int index = 0; index < 3; ++index) { + if (!near(actual[index], expected[index])) { + return 0; + } + } + return 1; +} + +void print_pose(const char *prefix, const EmcPose &pose) +{ + std::cout << prefix << "_xyz=" + << pose.tran.x << "," + << pose.tran.y << "," + << pose.tran.z << "\n"; +} + +void print_joints(const char *prefix, const double *joints) +{ + std::cout << prefix << "_rzt=" + << joints[0] << "," + << joints[1] << "," + << joints[2] << "\n"; +} + +} // namespace + +int main() +{ + const int init_rc = rtapi_app_main(); + std::cout << "rose_init=" << init_rc << "\n"; + std::cout << "rose_type=" << kinematicsType() << "\n"; + std::cout << "rose_switchable=" << kinematicsSwitchable() << "\n"; + + double joints[EMCMOT_MAX_JOINTS]{}; + joints[0] = 12.0; + joints[1] = 5.0; + joints[2] = 30.0; + + KINEMATICS_FORWARD_FLAGS fflags = 0; + KINEMATICS_INVERSE_FLAGS iflags = 0; + EmcPose forward_pose{}; + const int forward_rc = kinematicsForward(joints, &forward_pose, &fflags, &iflags); + std::cout << "rose_forward=" << forward_rc << "\n"; + print_pose("rose_forward", forward_pose); + + double inverse_joints[EMCMOT_MAX_JOINTS]{}; + const int inverse_rc = kinematicsInverse(&forward_pose, inverse_joints, &iflags, &fflags); + std::cout << "rose_inverse=" << inverse_rc << "\n"; + print_joints("rose_inverse", inverse_joints); + std::cout << "rose_roundtrip_joints=" << near_joints(inverse_joints, joints) << "\n"; + + rtapi_app_exit(); + return 0; +} diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rotate_kinematics_probe.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rotate_kinematics_probe.cpp new file mode 100644 index 0000000..c08e77b --- /dev/null +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_rotate_kinematics_probe.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include "emc/kinematics/kinematics.h" +#include "emc/motion/emcmotcfg.h" + +int rtapi_app_main(void); +void rtapi_app_exit(void); + +namespace { + +int near(double actual, double expected) +{ + return std::fabs(actual - expected) < 1e-9; +} + +int near_joints(const double *actual, const double *expected) +{ + for (int index = 0; index < 9; ++index) { + if (!near(actual[index], expected[index])) { + return 0; + } + } + return 1; +} + +void print_pose(const char *prefix, const EmcPose &pose) +{ + std::cout << prefix << "_xyz=" + << pose.tran.x << "," + << pose.tran.y << "," + << pose.tran.z << "\n"; + std::cout << prefix << "_abcuvw=" + << pose.a << "," + << pose.b << "," + << pose.c << "," + << pose.u << "," + << pose.v << "," + << pose.w << "\n"; +} + +void print_joints(const char *prefix, const double *joints) +{ + std::cout << prefix << "_xyzabcuvw=" + << joints[0] << "," + << joints[1] << "," + << joints[2] << "," + << joints[3] << "," + << joints[4] << "," + << joints[5] << "," + << joints[6] << "," + << joints[7] << "," + << joints[8] << "\n"; +} + +} // namespace + +int main() +{ + const int init_rc = rtapi_app_main(); + std::cout << "rotate_init=" << init_rc << "\n"; + std::cout << "rotate_type=" << kinematicsType() << "\n"; + std::cout << "rotate_switchable=" << kinematicsSwitchable() << "\n"; + + double joints[EMCMOT_MAX_JOINTS]{}; + joints[0] = 10.0; + joints[1] = 20.0; + joints[2] = 30.0; + joints[3] = 4.0; + joints[4] = 5.0; + joints[5] = 30.0; + joints[6] = 7.0; + joints[7] = 8.0; + joints[8] = 9.0; + + KINEMATICS_FORWARD_FLAGS fflags = 0; + KINEMATICS_INVERSE_FLAGS iflags = 0; + EmcPose forward_pose{}; + const int forward_rc = kinematicsForward(joints, &forward_pose, &fflags, &iflags); + std::cout << "rotate_forward=" << forward_rc << "\n"; + print_pose("rotate_forward", forward_pose); + + double inverse_joints[EMCMOT_MAX_JOINTS]{}; + const int inverse_rc = kinematicsInverse(&forward_pose, inverse_joints, &iflags, &fflags); + std::cout << "rotate_inverse=" << inverse_rc << "\n"; + print_joints("rotate_inverse", inverse_joints); + std::cout << "rotate_roundtrip_joints=" << near_joints(inverse_joints, joints) << "\n"; + + rtapi_app_exit(); + return 0; +} diff --git a/wasm-port/tests/native/verify_native_probes.sh b/wasm-port/tests/native/verify_native_probes.sh index a9ec6d2..f8eee75 100755 --- a/wasm-port/tests/native/verify_native_probes.sh +++ b/wasm-port/tests/native/verify_native_probes.sh @@ -87,6 +87,14 @@ check_exitcode linuxcnc_xyzac_trt_kinematics_probe check_exitcode linuxcnc_xyzac_trt_kinematics_probe.run check_exitcode linuxcnc_xyzbc_trt_kinematics_probe check_exitcode linuxcnc_xyzbc_trt_kinematics_probe.run +check_exitcode linuxcnc_corexy_kinematics_probe +check_exitcode linuxcnc_corexy_kinematics_probe.run +check_exitcode linuxcnc_rotate_kinematics_probe +check_exitcode linuxcnc_rotate_kinematics_probe.run +check_exitcode linuxcnc_rose_kinematics_probe +check_exitcode linuxcnc_rose_kinematics_probe.run +check_exitcode linuxcnc_max_kinematics_probe +check_exitcode linuxcnc_max_kinematics_probe.run for name in \ linuxcnc_tp_tp_source_probe \ linuxcnc_tp_tc_source_probe \ @@ -135,6 +143,10 @@ check_exitcode linuxcnc_5axiskins_source_probe check_exitcode linuxcnc_trtfuncs_source_probe check_exitcode linuxcnc_xyzac_trt_kins_source_probe check_exitcode linuxcnc_xyzbc_trt_kins_source_probe +check_exitcode linuxcnc_corexykins_source_probe +check_exitcode linuxcnc_rotatekins_source_probe +check_exitcode linuxcnc_rosekins_source_probe +check_exitcode linuxcnc_maxkins_source_probe check_exitcode linuxcnc_interp_convert_source_probe check_exitcode linuxcnc_interp_read_source_probe check_exitcode linuxcnc_interp_check_source_probe @@ -263,6 +275,38 @@ grep -Fq "xyzbc_trt_switch_identity=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_identity_forward=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_identity_near=1" "$XYZBC_TRT_KINEMATICS_STDOUT" +COREXY_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" +grep -Fq "corexy_init=0" "$COREXY_KINEMATICS_STDOUT" +grep -Fq "corexy_type=4" "$COREXY_KINEMATICS_STDOUT" +grep -Fq "corexy_switchable=0" "$COREXY_KINEMATICS_STDOUT" +grep -Fq "corexy_forward=0" "$COREXY_KINEMATICS_STDOUT" +grep -Fq "corexy_inverse=0" "$COREXY_KINEMATICS_STDOUT" +grep -Fq "corexy_roundtrip_joints=1" "$COREXY_KINEMATICS_STDOUT" + +ROTATE_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" +grep -Fq "rotate_init=0" "$ROTATE_KINEMATICS_STDOUT" +grep -Fq "rotate_type=4" "$ROTATE_KINEMATICS_STDOUT" +grep -Fq "rotate_switchable=0" "$ROTATE_KINEMATICS_STDOUT" +grep -Fq "rotate_forward=0" "$ROTATE_KINEMATICS_STDOUT" +grep -Fq "rotate_inverse=0" "$ROTATE_KINEMATICS_STDOUT" +grep -Fq "rotate_roundtrip_joints=1" "$ROTATE_KINEMATICS_STDOUT" + +ROSE_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" +grep -Fq "rose_init=0" "$ROSE_KINEMATICS_STDOUT" +grep -Fq "rose_type=4" "$ROSE_KINEMATICS_STDOUT" +grep -Fq "rose_switchable=0" "$ROSE_KINEMATICS_STDOUT" +grep -Fq "rose_forward=0" "$ROSE_KINEMATICS_STDOUT" +grep -Fq "rose_inverse=0" "$ROSE_KINEMATICS_STDOUT" +grep -Fq "rose_roundtrip_joints=1" "$ROSE_KINEMATICS_STDOUT" + +MAX_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" +grep -Fq "max_init=0" "$MAX_KINEMATICS_STDOUT" +grep -Fq "max_type=4" "$MAX_KINEMATICS_STDOUT" +grep -Fq "max_switchable=0" "$MAX_KINEMATICS_STDOUT" +grep -Fq "max_forward=0" "$MAX_KINEMATICS_STDOUT" +grep -Fq "max_inverse=0" "$MAX_KINEMATICS_STDOUT" +grep -Fq "max_roundtrip_joints=1" "$MAX_KINEMATICS_STDOUT" + check_fixture_output() { local fixture="$1" local expected="$2" diff --git a/wasm-port/tools/build_native_probes.sh b/wasm-port/tools/build_native_probes.sh index 84c0503..795bd45 100755 --- a/wasm-port/tools/build_native_probes.sh +++ b/wasm-port/tools/build_native_probes.sh @@ -382,6 +382,30 @@ XYZBC_TRT_KINEMATICS_PROBE_SOURCES=( "$WRAP_DIR/linuxcnc_xyzbc_trt_kinematics_probe.cpp" ) +COREXY_KINEMATICS_PROBE_SOURCES=( + "$VENDOR_DIR/src/emc/kinematics/corexykins.c" + "$WRAP_DIR/linuxcnc_hal_adapter.cpp" + "$WRAP_DIR/linuxcnc_corexy_kinematics_probe.cpp" +) + +ROTATE_KINEMATICS_PROBE_SOURCES=( + "$VENDOR_DIR/src/emc/kinematics/rotatekins.c" + "$WRAP_DIR/linuxcnc_hal_adapter.cpp" + "$WRAP_DIR/linuxcnc_rotate_kinematics_probe.cpp" +) + +ROSE_KINEMATICS_PROBE_SOURCES=( + "$VENDOR_DIR/src/emc/kinematics/rosekins.c" + "$WRAP_DIR/linuxcnc_hal_adapter.cpp" + "$WRAP_DIR/linuxcnc_rose_kinematics_probe.cpp" +) + +MAX_KINEMATICS_PROBE_SOURCES=( + "$VENDOR_DIR/src/emc/kinematics/maxkins.c" + "$WRAP_DIR/linuxcnc_hal_adapter.cpp" + "$WRAP_DIR/linuxcnc_max_kinematics_probe.cpp" +) + TP_CORE_SOURCES=( "$VENDOR_DIR/src/emc/tp/tp.c" "$VENDOR_DIR/src/emc/tp/tc.c" @@ -583,6 +607,34 @@ build_binary_target \ XYZBC_TRT_KINEMATICS_PROBE_SOURCES \ NO_LINK_FLAGS +build_binary_target \ + linuxcnc_corexy_kinematics_probe \ + "$BUILD_DIR/linuxcnc_corexy_kinematics_probe" \ + TP_FLAGS \ + COREXY_KINEMATICS_PROBE_SOURCES \ + NO_LINK_FLAGS + +build_binary_target \ + linuxcnc_rotate_kinematics_probe \ + "$BUILD_DIR/linuxcnc_rotate_kinematics_probe" \ + TP_FLAGS \ + ROTATE_KINEMATICS_PROBE_SOURCES \ + NO_LINK_FLAGS + +build_binary_target \ + linuxcnc_rose_kinematics_probe \ + "$BUILD_DIR/linuxcnc_rose_kinematics_probe" \ + TP_FLAGS \ + ROSE_KINEMATICS_PROBE_SOURCES \ + NO_LINK_FLAGS + +build_binary_target \ + linuxcnc_max_kinematics_probe \ + "$BUILD_DIR/linuxcnc_max_kinematics_probe" \ + TP_FLAGS \ + MAX_KINEMATICS_PROBE_SOURCES \ + NO_LINK_FLAGS + if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_kinematics_probe.exitcode")" == "0" ]]; then set +e "$BUILD_DIR/linuxcnc_kinematics_probe" \ @@ -643,6 +695,66 @@ else "$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stderr.log" fi +if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.exitcode")" == "0" ]]; then + set +e + "$BUILD_DIR/linuxcnc_corexy_kinematics_probe" \ + >"$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" \ + 2>"$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stderr.log" + COREXY_KINEMATICS_RUN_RC=$? + set -e + echo "$COREXY_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.exitcode" +else + rm -f \ + "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.exitcode" \ + "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" \ + "$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stderr.log" +fi + +if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.exitcode")" == "0" ]]; then + set +e + "$BUILD_DIR/linuxcnc_rotate_kinematics_probe" \ + >"$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" \ + 2>"$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stderr.log" + ROTATE_KINEMATICS_RUN_RC=$? + set -e + echo "$ROTATE_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.exitcode" +else + rm -f \ + "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.exitcode" \ + "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" \ + "$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stderr.log" +fi + +if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_rose_kinematics_probe.exitcode")" == "0" ]]; then + set +e + "$BUILD_DIR/linuxcnc_rose_kinematics_probe" \ + >"$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" \ + 2>"$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stderr.log" + ROSE_KINEMATICS_RUN_RC=$? + set -e + echo "$ROSE_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.exitcode" +else + rm -f \ + "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.exitcode" \ + "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" \ + "$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stderr.log" +fi + +if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_max_kinematics_probe.exitcode")" == "0" ]]; then + set +e + "$BUILD_DIR/linuxcnc_max_kinematics_probe" \ + >"$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" \ + 2>"$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stderr.log" + MAX_KINEMATICS_RUN_RC=$? + set -e + echo "$MAX_KINEMATICS_RUN_RC" > "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.exitcode" +else + rm -f \ + "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.exitcode" \ + "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" \ + "$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stderr.log" +fi + if [[ "$(tr -d '[:space:]' < "$BUILD_DIR/linuxcnc_tp_api_probe.exitcode")" == "0" ]]; then set +e "$BUILD_DIR/linuxcnc_tp_api_probe" \ @@ -789,6 +901,30 @@ build_object_target \ "$VENDOR_DIR/src/emc/kinematics/xyzbc-trt-kins.c" \ TP_FLAGS +build_object_target \ + linuxcnc_corexykins_source_probe \ + "$BUILD_DIR/linuxcnc_corexykins_source_probe.o" \ + "$VENDOR_DIR/src/emc/kinematics/corexykins.c" \ + TP_FLAGS + +build_object_target \ + linuxcnc_rotatekins_source_probe \ + "$BUILD_DIR/linuxcnc_rotatekins_source_probe.o" \ + "$VENDOR_DIR/src/emc/kinematics/rotatekins.c" \ + TP_FLAGS + +build_object_target \ + linuxcnc_rosekins_source_probe \ + "$BUILD_DIR/linuxcnc_rosekins_source_probe.o" \ + "$VENDOR_DIR/src/emc/kinematics/rosekins.c" \ + TP_FLAGS + +build_object_target \ + linuxcnc_maxkins_source_probe \ + "$BUILD_DIR/linuxcnc_maxkins_source_probe.o" \ + "$VENDOR_DIR/src/emc/kinematics/maxkins.c" \ + TP_FLAGS + build_object_target \ linuxcnc_interp_convert_source_probe \ "$BUILD_DIR/linuxcnc_interp_convert_source_probe.o" \ diff --git a/wasm-port/tools/source-manifest.txt b/wasm-port/tools/source-manifest.txt index d6fc161..1b844b8 100644 --- a/wasm-port/tools/source-manifest.txt +++ b/wasm-port/tools/source-manifest.txt @@ -40,6 +40,10 @@ src/emc/kinematics/5axiskins.c src/emc/kinematics/trtfuncs.c src/emc/kinematics/xyzac-trt-kins.c src/emc/kinematics/xyzbc-trt-kins.c +src/emc/kinematics/corexykins.c +src/emc/kinematics/rotatekins.c +src/emc/kinematics/rosekins.c +src/emc/kinematics/maxkins.c src/emc/tp/tp.h src/emc/tp/tp_types.h src/emc/tp/tc.h diff --git a/wasm-port/vendor/linuxcnc/src/emc/kinematics/corexykins.c b/wasm-port/vendor/linuxcnc/src/emc/kinematics/corexykins.c new file mode 100644 index 0000000..df39c42 --- /dev/null +++ b/wasm-port/vendor/linuxcnc/src/emc/kinematics/corexykins.c @@ -0,0 +1,89 @@ +/******************************************************************** +* Description: kinematics for corexy +* Adapted from trivkins.c +* ref: http://corexy.com/theory.html +********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct data { + hal_s32_t joints[EMCMOT_MAX_JOINTS]; +} *data; + +int kinematicsForward(const double *joints + ,EmcPose *pos + ,const KINEMATICS_FORWARD_FLAGS *fflags + ,KINEMATICS_INVERSE_FLAGS *iflags + ) { + (void)fflags; + (void)iflags; + pos->tran.x = 0.5 * (joints[0] + joints[1]); + pos->tran.y = 0.5 * (joints[0] - joints[1]); + pos->tran.z = joints[2]; + pos->a = joints[3]; + pos->b = joints[4]; + pos->c = joints[5]; + pos->u = joints[6]; + pos->v = joints[7]; + pos->w = joints[8]; + + return 0; +} + +int kinematicsInverse(const EmcPose *pos + ,double *joints + ,const KINEMATICS_INVERSE_FLAGS *iflags + ,KINEMATICS_FORWARD_FLAGS *fflags + ) { + (void)iflags; + (void)fflags; + joints[0] = pos->tran.x + pos->tran.y; + joints[1] = pos->tran.x - pos->tran.y; + joints[2] = pos->tran.z; + joints[3] = pos->a; + joints[4] = pos->b; + joints[5] = pos->c; + joints[6] = pos->u; + joints[7] = pos->v; + joints[8] = pos->w; + + return 0; +} + +int kinematicsHome(EmcPose *world + ,double *joint + ,KINEMATICS_FORWARD_FLAGS *fflags + ,KINEMATICS_INVERSE_FLAGS *iflags + ) { + *fflags = 0; + *iflags = 0; + return kinematicsForward(joint, world, fflags, iflags); +} + +KINEMATICS_TYPE kinematicsType() { return KINEMATICS_BOTH; } + +KINS_NOT_SWITCHABLE +EXPORT_SYMBOL(kinematicsType); +EXPORT_SYMBOL(kinematicsForward); +EXPORT_SYMBOL(kinematicsInverse); +MODULE_LICENSE("GPL"); + +static int comp_id; +int rtapi_app_main(void) { + comp_id = hal_init("corexykins"); + if(comp_id < 0) return comp_id; + + data = hal_malloc(sizeof(struct data)); + + hal_ready(comp_id); + return 0; +} + +void rtapi_app_exit(void) { hal_exit(comp_id); } diff --git a/wasm-port/vendor/linuxcnc/src/emc/kinematics/maxkins.c b/wasm-port/vendor/linuxcnc/src/emc/kinematics/maxkins.c new file mode 100644 index 0000000..ebb38a1 --- /dev/null +++ b/wasm-port/vendor/linuxcnc/src/emc/kinematics/maxkins.c @@ -0,0 +1,148 @@ +/******************************************************************** +* Description: maxkins.c +* Kinematics for Chris Radek's tabletop 5 axis mill named 'max'. +* This mill has a tilting head (B axis) and horizontal rotary +* mounted to the table (C axis). +* +* Author: Chris Radek +* License: GPL Version 2 +* +* Copyright (c) 2007 Chris Radek +********************************************************************/ + +/******************************************************************** +* Note: The direction of the B axis is the opposite of the +* conventional axis direction. See +* https://linuxcnc.org/docs/html/gcode/machining-center.html +********************************************************************/ + +#include +#include +#include +#include +#include /* these decls */ + +#define d2r(d) ((d)*PM_PI/180.0) +#define r2d(r) ((r)*180.0/PM_PI) + +#ifndef hypot +#define hypot(a,b) (sqrt((a)*(a)+(b)*(b))) +#endif + +struct haldata { + hal_float_t *pivot_length; + hal_bit_t *conventional_directions; //default is false +} *haldata; + +int kinematicsForward(const double *joints, + EmcPose * pos, + const KINEMATICS_FORWARD_FLAGS * fflags, + KINEMATICS_INVERSE_FLAGS * iflags) +{ + (void)fflags; + (void)iflags; + + const real_t con = *(haldata->conventional_directions) ? 1.0 : -1.0; + + // B correction + const double zb = (*(haldata->pivot_length) + joints[8]) * cos(d2r(joints[4])); + const double xb = (*(haldata->pivot_length) + joints[8]) * sin(d2r(joints[4])); + + // C correction + const double xyr = hypot(joints[0], joints[1]); + const double xytheta = atan2(joints[1], joints[0]) + d2r(joints[5]); + + // U correction + const double zv = joints[6] * sin(d2r(joints[4])); + const double xv = joints[6] * cos(d2r(joints[4])); + + // V correction is always in joint 1 only + + pos->tran.x = xyr * cos(xytheta) - (con * xb) - xv; + pos->tran.y = xyr * sin(xytheta) - joints[7]; + pos->tran.z = joints[2] - zb - (con * zv) + *(haldata->pivot_length); + + pos->a = joints[3]; + pos->b = joints[4]; + pos->c = joints[5]; + pos->u = joints[6]; + pos->v = joints[7]; + pos->w = joints[8]; + + return 0; +} + +int kinematicsInverse(const EmcPose * pos, + double *joints, + const KINEMATICS_INVERSE_FLAGS * iflags, + KINEMATICS_FORWARD_FLAGS * fflags) +{ + (void)iflags; + (void)fflags; + + const real_t con = *(haldata->conventional_directions) ? 1.0 : -1.0; + + // B correction + const double zb = (*(haldata->pivot_length) + pos->w) * cos(d2r(pos->b)); + const double xb = (*(haldata->pivot_length) + pos->w) * sin(d2r(pos->b)); + + // C correction + const double xyr = hypot(pos->tran.x, pos->tran.y); + const double xytheta = atan2(pos->tran.y, pos->tran.x) - d2r(pos->c); + + // U correction + const double zv = pos->u * sin(d2r(pos->b)); + const double xv = pos->u * cos(d2r(pos->b)); + + // V correction is always in joint 1 only + + joints[0] = xyr * cos(xytheta) + (con * xb) + xv; + joints[1] = xyr * sin(xytheta) + pos->v; + joints[2] = pos->tran.z + zb - (con * zv) - *(haldata->pivot_length); + + joints[3] = pos->a; + joints[4] = pos->b; + joints[5] = pos->c; + joints[6] = pos->u; + joints[7] = pos->v; + joints[8] = pos->w; + + return 0; +} + +KINEMATICS_TYPE kinematicsType() +{ + return KINEMATICS_BOTH; +} + +KINS_NOT_SWITCHABLE +EXPORT_SYMBOL(kinematicsType); +EXPORT_SYMBOL(kinematicsInverse); +EXPORT_SYMBOL(kinematicsForward); +MODULE_LICENSE("GPL"); + +int comp_id; +int rtapi_app_main(void) { + int result; + comp_id = hal_init("maxkins"); + if(comp_id < 0) return comp_id; + + haldata = hal_malloc(sizeof(struct haldata)); + + result = hal_pin_float_new("maxkins.pivot-length", HAL_IO, &(haldata->pivot_length), comp_id); + + result += hal_pin_bit_new("maxkins.conventional-directions", HAL_IN, &(haldata->conventional_directions), comp_id); + + if(result < 0) goto error; + + *(haldata->pivot_length) = 0.666; + *(haldata->conventional_directions) = 0; // default is unconventional + hal_ready(comp_id); + return 0; + +error: + hal_exit(comp_id); + return result; +} + +void rtapi_app_exit(void) { hal_exit(comp_id); } diff --git a/wasm-port/vendor/linuxcnc/src/emc/kinematics/rosekins.c b/wasm-port/vendor/linuxcnc/src/emc/kinematics/rosekins.c new file mode 100644 index 0000000..46d8f7f --- /dev/null +++ b/wasm-port/vendor/linuxcnc/src/emc/kinematics/rosekins.c @@ -0,0 +1,143 @@ +/* + Copyright 2016 Dewey Garrett + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include +#include + +KINS_NOT_SWITCHABLE +EXPORT_SYMBOL(kinematicsType); +EXPORT_SYMBOL(kinematicsInverse); +EXPORT_SYMBOL(kinematicsForward); +MODULE_LICENSE("GPL"); + +#ifndef hypot +#define hypot(a,b) (sqrt((a)*(a)+(b)*(b))) +#endif + +struct haldata { + hal_float_t *revolutions; + hal_float_t *theta_degrees; + hal_float_t *bigtheta_degrees; +} *haldata; + +int kinematicsForward(const double *joints, + EmcPose * pos, + const KINEMATICS_FORWARD_FLAGS * fflags, + KINEMATICS_INVERSE_FLAGS * iflags) +{ + (void)fflags; + (void)iflags; + double radius,z,theta; + + radius = joints[0]; + z = joints[1]; + theta = TO_RAD * joints[2]; + + pos->tran.x = radius * cos(theta); + pos->tran.y = radius * sin(theta); + pos->tran.z = z; + pos->a = 0; + pos->b = 0; + pos->c = 0; + pos->u = 0; + pos->v = 0; + pos->w = 0; + + return 0; +} + +int kinematicsInverse(const EmcPose * pos, + double *joints, + const KINEMATICS_INVERSE_FLAGS * iflags, + KINEMATICS_FORWARD_FLAGS * fflags) +{ + (void)iflags; + (void)fflags; +// There is a potential problem when accumulating bigtheta -- loss of +// precision based on size of mantissa -- but in practice, it is probably ok + + static int oldquad; + static int revolutions; + + double theta,bigtheta; + int nowquad = 0; + double x = pos->tran.x; + double y = pos->tran.y; + double z = pos->tran.z; + + if (x >= 0 && y >= 0) nowquad = 1; + else if (x < 0 && y >= 0) nowquad = 2; + else if (x < 0 && y < 0) nowquad = 3; + else if (x >= 0 && y < 0) nowquad = 4; + + if (oldquad == 2 && nowquad == 3) {revolutions += 1;} + if (oldquad == 3 && nowquad == 2) {revolutions -= 1;} + + theta = atan2(y,x); + bigtheta = theta + PM_2_PI * revolutions; + + *(haldata->revolutions) = revolutions; + *(haldata->theta_degrees) = theta * TO_DEG; + *(haldata->bigtheta_degrees) = bigtheta * TO_DEG; + + joints[0] = hypot(x,y); + joints[1] = z; + joints[2] = TO_DEG * bigtheta; + joints[3] = 0; + joints[4] = 0; + joints[5] = 0; + joints[6] = 0; + joints[7] = 0; + joints[8] = 0; + + oldquad = nowquad; + return 0; +} + +KINEMATICS_TYPE kinematicsType() +{ + return KINEMATICS_BOTH; +} + +static int comp_id; + +void rtapi_app_exit(void) { hal_exit(comp_id); } + +int rtapi_app_main(void) { + int ans; + comp_id = hal_init("rosekins"); + if(comp_id < 0) return comp_id; + + haldata = hal_malloc(sizeof(struct haldata)); + + if((ans = hal_pin_float_new("rosekins.revolutions", + HAL_OUT, &(haldata->revolutions), comp_id)) < 0) goto error; + if((ans = hal_pin_float_new("rosekins.theta_degrees", + HAL_OUT, &(haldata->theta_degrees), comp_id)) < 0) goto error; + if((ans = hal_pin_float_new("rosekins.bigtheta_degrees", + HAL_OUT, &(haldata->bigtheta_degrees), comp_id)) < 0) goto error; + + hal_ready(comp_id); + return 0; + +error: + return ans; +} diff --git a/wasm-port/vendor/linuxcnc/src/emc/kinematics/rotatekins.c b/wasm-port/vendor/linuxcnc/src/emc/kinematics/rotatekins.c new file mode 100644 index 0000000..838c917 --- /dev/null +++ b/wasm-port/vendor/linuxcnc/src/emc/kinematics/rotatekins.c @@ -0,0 +1,96 @@ +/******************************************************************** +* Description: rotatekins.c +* Simple example kinematics for a rotary table in software +* +* Derived from a work by Fred Proctor & Will Shackleford +* +* Author: Chris Radek +* License: GPL Version 2 +* System: Linux +* +* Copyright (c) 2006 All rights reserved. +* +********************************************************************/ + +#include +#include +#include +#include +#include /* these decls */ + +int kinematicsForward(const double *joints, + EmcPose * pos, + const KINEMATICS_FORWARD_FLAGS * fflags, + KINEMATICS_INVERSE_FLAGS * iflags) +{ + (void)fflags; + (void)iflags; + double c_rad = -joints[5]*M_PI/180; + pos->tran.x = joints[0] * cos(c_rad) - joints[1] * sin(c_rad); + pos->tran.y = joints[0] * sin(c_rad) + joints[1] * cos(c_rad); + pos->tran.z = joints[2]; + pos->a = joints[3]; + pos->b = joints[4]; + pos->c = joints[5]; + pos->u = joints[6]; + pos->v = joints[7]; + pos->w = joints[8]; + + return 0; +} + +int kinematicsInverse(const EmcPose * pos, + double *joints, + const KINEMATICS_INVERSE_FLAGS * iflags, + KINEMATICS_FORWARD_FLAGS * fflags) +{ + (void)iflags; + (void)fflags; + double c_rad = pos->c*M_PI/180; + joints[0] = pos->tran.x * cos(c_rad) - pos->tran.y * sin(c_rad); + joints[1] = pos->tran.x * sin(c_rad) + pos->tran.y * cos(c_rad); + joints[2] = pos->tran.z; + joints[3] = pos->a; + joints[4] = pos->b; + joints[5] = pos->c; + joints[6] = pos->u; + joints[7] = pos->v; + joints[8] = pos->w; + + return 0; +} + +/* implemented for these kinematics as giving joints preference */ +int kinematicsHome(EmcPose * world, + double *joint, + KINEMATICS_FORWARD_FLAGS * fflags, + KINEMATICS_INVERSE_FLAGS * iflags) +{ + *fflags = 0; + *iflags = 0; + + return kinematicsForward(joint, world, fflags, iflags); +} + +KINEMATICS_TYPE kinematicsType() +{ + return KINEMATICS_BOTH; +} + +KINS_NOT_SWITCHABLE +EXPORT_SYMBOL(kinematicsType); +EXPORT_SYMBOL(kinematicsForward); +EXPORT_SYMBOL(kinematicsInverse); +MODULE_LICENSE("GPL"); + +int comp_id; +int rtapi_app_main(void) { + comp_id = hal_init("rotatekins"); + if(comp_id > 0) { + hal_ready(comp_id); + return 0; + } + return comp_id; +} + +void rtapi_app_exit(void) { hal_exit(comp_id); }