From 05e7ebacfb9aeb5bbdb96be8069faca8a9f3e24a Mon Sep 17 00:00:00 2001 From: Bertho Stultiens Date: Thu, 2 Jul 2026 15:34:57 +0200 Subject: [PATCH] Preliminary - HAL types update and HAL isolation --- docs/po4a.cfg | 1 + .../getting-started/updating-linuxcnc.adoc | 170 ++++++++---------- docs/src/hal/comp.adoc | 1 + docs/src/hal/components.adoc | 1 + include/kins_module.h | 23 ++- src/Makefile | 2 +- src/emc/kinematics/5axiskins.c | 4 +- src/emc/kinematics/genhexkins.c | 56 +++--- src/emc/kinematics/genserfuncs.c | 12 +- src/emc/kinematics/kins_util.c | 58 ++++-- src/emc/kinematics/lineardeltakins.c | 4 +- src/emc/kinematics/maxkins.c | 6 +- src/emc/kinematics/pentakins.c | 22 +-- src/emc/kinematics/pumakins.c | 10 +- src/emc/kinematics/rosekins.c | 6 +- src/emc/kinematics/rotarydeltakins.c | 8 +- src/emc/kinematics/scarakins.c | 12 +- src/emc/kinematics/three21kins.c | 16 +- src/emc/kinematics/tripodkins.c | 6 +- src/emc/kinematics/trtfuncs.c | 16 +- src/emc/kinematics/userkfuncs.c | 8 +- .../kinematics_userspace/kinematics_user.c | 8 +- src/emc/motion/axis.c | 2 +- src/emc/task/taskclass.cc | 59 +++--- src/hal/components/.gitignore | 1 + src/hal/components/comp.comp | 1 + src/hal/components/conv_real_bool.comp | 23 +++ src/hal/components/ilowpass.comp | 4 +- src/hal/components/matrixkins.comp | 18 +- src/hal/components/sim_encoder.c | 31 ++-- src/hal/components/switchkinscomp.comp | 2 +- src/hal/components/userkins.comp | 4 +- src/hal/components/xyzab_tdr_kins.comp | 12 +- src/hal/components/xyzacb_trsrn.comp | 22 +-- src/hal/components/xyzbca_trsrn.comp | 22 +-- src/hal/utils/halcompile.g | 51 +++++- tests/ilowpass/low-gain/expected | 1 + tests/ilowpass/low-gain/ilowpasstest.py | 33 ++++ tests/ilowpass/low-gain/test.hal | 12 +- tests/ilowpass/wrap-around/README | 2 - tests/ilowpass/wrap-around/expected | 2 - tests/ilowpass/wrap-around/test.hal | 12 -- 42 files changed, 436 insertions(+), 328 deletions(-) create mode 100644 src/hal/components/conv_real_bool.comp create mode 100755 tests/ilowpass/low-gain/ilowpasstest.py delete mode 100644 tests/ilowpass/wrap-around/README delete mode 100644 tests/ilowpass/wrap-around/expected delete mode 100644 tests/ilowpass/wrap-around/test.hal diff --git a/docs/po4a.cfg b/docs/po4a.cfg index 5ca4619aa21..fe0852dc513 100644 --- a/docs/po4a.cfg +++ b/docs/po4a.cfg @@ -411,6 +411,7 @@ [type: man_def] build/man/man9/conv_bool_real.9 $lang:build/man/$lang/man9/conv_bool_real.9 [type: man_def] build/man/man9/conv_bool_sint.9 $lang:build/man/$lang/man9/conv_bool_sint.9 [type: man_def] build/man/man9/conv_bool_uint.9 $lang:build/man/$lang/man9/conv_bool_uint.9 +[type: man_def] build/man/man9/conv_real_bool.9 $lang:build/man/$lang/man9/conv_real_bool.9 [type: man_def] build/man/man9/conv_real_sint.9 $lang:build/man/$lang/man9/conv_real_sint.9 [type: man_def] build/man/man9/conv_real_uint.9 $lang:build/man/$lang/man9/conv_real_uint.9 [type: man_def] build/man/man9/conv_sint_bool.9 $lang:build/man/$lang/man9/conv_sint_bool.9 diff --git a/docs/src/getting-started/updating-linuxcnc.adoc b/docs/src/getting-started/updating-linuxcnc.adoc index 819630d7da0..dae3a91fd74 100644 --- a/docs/src/getting-started/updating-linuxcnc.adoc +++ b/docs/src/getting-started/updating-linuxcnc.adoc @@ -13,28 +13,32 @@ updates. If you don't have an internet connection to your PC see == Upgrade to the new version -This section describes how to upgrade LinuxCNC from version 2.8.x to a 2.9.y version. -It assumes that you have an existing 2.8 install that you want to update. +This section describes how to upgrade LinuxCNC from version 2.9.x to a 2.10.y version. +It assumes that you have an existing 2.9 install that you want to update. -To upgrade LinuxCNC from a version older than 2.8, you have to first -https://linuxcnc.org/docs/2.8/html/getting-started/updating-linuxcnc.html[upgrade your old install to 2.8], +To upgrade LinuxCNC from a version older than 2.9, you have to first +https://linuxcnc.org/docs/2.9/html/getting-started/updating-linuxcnc.html[upgrade your old install to 2.9], then follow these instructions to upgrade to the new version. If you do not have an old version of LinuxCNC to upgrade, then you're best off making a fresh install of the new version as described in the section <>. -Furthermore, if you are running Ubuntu Precise, Debian Wheezy or Debian Buster it is -well worth considering making a backup of the "linuxcnc" directory on -removable media and performing a +Furthermore, if you are running Ubuntu Precise, Debian Wheezy, Debian Buster or +Debian Bullseye it is well worth considering making a backup of the "linuxcnc" +directory on removable media and performing a <> -as these releases were EOL in 2017, 2018 and 2022 respectively. +as these releases were EOL in 2017, 2018, 2022 and 2026 respectively. If you are running on Ubuntu Lucid then you will have to do this, as Lucid is no longer supported by LinuxCNC (it was EOL in 2013). -To upgrade major versions like 2.8 to 2.9 when you have a network connection at +If you are running Debian Bookworm, then we *strongly* recommend that you upgrade to Debian Trixie. +Moving to the latest Debian version allows for better compatibility and a longer stable path for your installation. +Debian Trixie will have LTS support until June 2030. + +To upgrade major versions like 2.9 to 2.10 when you have a network connection at the machine you need to disable the old linuxcnc.org apt sources in the file /etc/apt/sources.list -and add a new linuxcnc.org apt source for 2.9, then upgrade LinuxCNC. +and add a new linuxcnc.org apt source for 2.10, then upgrade LinuxCNC. The details will depend on which platform you're running on. Open a <> then type `lsb_release -ic` to find this information out: @@ -45,8 +49,8 @@ Distributor ID: Debian Codename: Trixie ---- -You should be running on Debian Bullseye, Bookworm or Trixie or Ubuntu 20.04 "Focal Fossa" or newer. -LinuxCNC 2.9.y will not run on older distributions than these. +You should be running on Debian Bookworm or, recommended, Trixie or Ubuntu 24.04 "Noble Numbat" or newer. +LinuxCNC 2.10.y may not run on older distributions than these and is not supported on anything older. You will also need to check which realtime kernel is being used: @@ -87,11 +91,10 @@ RTAI packages are available for Bookworm and Buster but not currently for Bullse [cols="3,5",options="header"] |=== | OS / Realtime Version | Repository -| Debian Bullseye - preempt m| deb https://linuxcnc.org bullseye base 2.9-uspace -| Debian Bookworm - preempt m| deb https://linuxcnc.org bookworm base 2.9-uspace -| Debian Bookworm - RTAI m| deb https://linuxcnc.org bookworm base 2.9-rt -| Debian Trixie - preempt m| deb https://linuxcnc.org trixie base 2.9-uspace -| Debian Trixie - RTAI m| deb https://linuxcnc.org trixie base 2.9-rt +| Debian Bookworm - preempt m| deb https://linuxcnc.org bookworm base 2.10-uspace +| Debian Bookworm - RTAI m| deb https://linuxcnc.org bookworm base 2.10-rt +| Debian Trixie - preempt m| deb https://linuxcnc.org trixie base 2.10-uspace +| Debian Trixie - RTAI m| deb https://linuxcnc.org trixie base 2.10-rt |=== .Figure with a screenshot of the repository configuration of the synaptic package manager. @@ -145,77 +148,83 @@ Codename: trixie ---- Pick the OS from the list then pick the major version you want like -2.9-rt for RTAI or 2.9-uspace for preempt-rt. +2.10-rt for RTAI or 2.10-uspace for preempt-rt. Next pick the type of computer you have: binary-amd64 for 64-bit PC or binary-arm64 (64bit) for Raspberry Pi. Next pick the version you want from the bottom of the list like -'linuxcnc-uspace_2.9.8_amd64.deb' (choose the latest by date). +'linuxcnc-uspace_2.10.0_amd64.deb' (choose the latest by date). Download the deb and copy it to your home directory. You can rename the file to something a bit shorter with the file manager like -'linuxcnc_2.9.8.deb' then open a terminal and install it with the +'linuxcnc_2.19.0.deb' then open a terminal and install it with the package manager with this command: ---- -sudo dpkg -i linuxcnc_2.9.8.deb +sudo dpkg -i linuxcnc_2.10.0.deb ---- +== Updating to 2.10 -== Updating Configuration Files for 2.9 - -=== Stricter handling of pluggable interpreters - -If you just run regular G-code and you don't know what a pluggable -interpreter is, then this section does not affect you. - -A seldom-used feature of LinuxCNC is support for pluggable interpreters, -controlled by the undocumented `[TASK]INTERPRETER` INI setting. +A large set of changes have been implemented in the new version. +The changes include: -Versions of LinuxCNC before 2.9.0 used to handle an incorrect -`[TASK]INTERPRETER` setting by automatically falling back to using the -default G-code interpreter. +* INI: Reworked INI-file parser with consistent types +* HAL: API breaking change implementing new HAL types +* HAL: Make the underlying HAL memory inaccessible and use a proper API +* TP: New selectable scurve trajectory planner added -Since 2.9.0, an incorrect `[TASK]INTERPRETER` value will cause -LinuxCNC to refuse to start up. Fix this condition by deleting the -`[TASK]INTERPRETER` setting from your INI file, so that LinuxCNC will -use the default G-code interpreter. +=== New HAL types +All integer HAL pins are now 64-bit only and the old HAL type names have changed: -=== Canterp +* `HAL_BOOL` - formerly HAL_BIT +* `HAL_REAL` - formerly HAL_FLOAT +* `HAL_SINT` - formerly HAL_S64 +* `HAL_UINT` - formerly HAL_U64 -If you just run regular G-code and you don't use the `canterp` pluggable -interpreter, then this section does not affect you. +The old 32-bit types have been removed: +* `HAL_S32` - removed +* `HAL_U32` - removed -In the extremely unlikely event that you are using `canterp`, -know that the module has moved from `/usr/lib/libcanterp.so` to -`/usr/lib/linuxcnc/canterp.so`, and the `[TASK]INTERPRETER` setting -correspondingly needs to change from `libcanterp.so` to `canterp.so`. - - -=== Spindle limits in the INI +[IMPORTANT] +==== +Any user components must be updated and recompiled. +The old HAL API is no longer available and access to pins/params is not done by getter/setter. +See ...FIXME... for a more detailed description how to update your components. +==== -It is now possible to add settings to the [SPINDLE] section of the INI file +=== Component changes -MAX_FORWARD_VELOCITY = 20000 The maximum spindle speed (in rpm) +Components were renamed in the HAL type replacement process because they included the old type names: +* conv_XXXX_YYYY - coversion between types now use 'bool', 'real', 'sint' and 'uint' for XXXX and YYYY. +* abs_s32 - replaced by abs_sint. +* abs_s64 - replaced by abs_sint. +* scaled_s32_sums - replaced by scaled_sint_sums. +* mux_generic - renamed pins +* demux_generic - renamed pins +* demux - renamed pin sel-s32 to sel-sint -MIN_FORWARD_VELOCITY = 3000 The minimum spindle speed (in rpm) +=== Updated Python interface -MAX_REVERSE_VELOCITY = 20000 This setting will default to -MAX_FORWARD_VELOCITY if omitted. +The HAL type update is also added to the `hal` module. +Additionally, the type names and direction names have been added as IntEnum types. +All code has been updated to use them and you are encouraged to do the same: -MIN_REVERSE_VELOCITY = 3000` This setting is equivalent to -MIN_FORWARD_VELOCITY but for reverse spindle rotation. It will default -to the MIN_FORWARD_VELOCITY if omitted. +[source,python] +---- +import hal +... -INCREMENT = 200 Sets the step size for spindle speed increment / -decrement commands. This can have a different value for each spindle. -This setting is effective with AXIS and Touchy but note that some -control screens may handle things differently. +# Old: +comp.newpin("pinname", hal.HAL_FLOAT, hal.HAL_IN) -HOME_SEARCH_VELOCITY = 100 - Accepted but currently does nothing +# New: +comp.newpin("pinname", hal.Type.REAL, hal.Dir.IN) +---- -HOME_SEQUENCE = 0 - Accepted but currently does nothing +The old HAL_S32 and HAL_U32 names have been removed and the old HAL type names +HAL_BIT, HAL_FLOAT, HAL_S64 and HAL_U64 will result in a deprecation warning. == Updating Configuration Files for 2.10.y @@ -453,39 +462,16 @@ depth/blend state a part left behind. == New HAL components === Non-Realtime -mdro -mqtt-publisher -pi500_vfd -pmx485-test -qtplasmac-cfg2prefs -qtplasmac-materials -qtplasmac-plasmac2qt -qtplasmac-setup -sim-torch -svd-ps_vfd -=== Realtime -anglejog -div2 -enum -filter_kalman -flipflop -homecomp -limit_axis -mesa_uart -millturn -scaled_s32_sums -tof -ton +...FIXME... -== New Drivers - -A framework for controlling ModBus devices using the serial ports on -many Mesa cards has been introduced. -http://linuxcnc.org/docs/2.9/html/drivers/mesa_modbus.html +=== Realtime -A new GPIO driver for any GPIO which is supported by the gpiod library -is now included: -http://linuxcnc.org/docs/2.9/html/drivers/hal_gpio.html +...FIXME... +== New Drivers +A new ModBus universal driver `hm2_modbus` for Mesa hardware has been created. +It replaces the old mesa_modbus driver and is much more capable. +See hm2_modbus(9) and mesambccc(1). +There are example configurations under `/usr/share/doc/linuxcnc/examples/sample-configs/by_interface/mesa/hm2-modbus`. diff --git a/docs/src/hal/comp.adoc b/docs/src/hal/comp.adoc index 18fca5a909a..db90427cab5 100644 --- a/docs/src/hal/comp.adoc +++ b/docs/src/hal/comp.adoc @@ -180,6 +180,7 @@ Declarations include: * 'component HALNAME (DOC);' * 'pin PINDIRECTION TYPE HALNAME ([SIZE]|[MAXSIZE: CONDSIZE]) (if CONDITION) (= STARTVALUE) (DOC) ;' * 'param PARAMDIRECTION TYPE HALNAME ([SIZE]|[MAXSIZE: CONDSIZE]) (if CONDITION) (= STARTVALUE) (DOC) ;' +* 'alias HALNAME HALNAME ;' * 'function HALNAME (fp | nofp) (DOC);' * 'option OPT (VALUE);' * 'variable CTYPE STARREDNAME ([SIZE]);' diff --git a/docs/src/hal/components.adoc b/docs/src/hal/components.adoc index 507070983cf..b60eec57272 100644 --- a/docs/src/hal/components.adoc +++ b/docs/src/hal/components.adoc @@ -285,6 +285,7 @@ Limit its slew rate to less than maxv per second. Limit its second derivative to | link:../man/man9/conv_bool_real.9.html[conv_bool_real] |Converts from bool to real || | link:../man/man9/conv_bool_sint.9.html[conv_bool_sint] |Convert a value from bool to sint || | link:../man/man9/conv_bool_uint.9.html[conv_bool_uint] |Convert a value from bool to uint || +| link:../man/man9/conv_real_bool.9.html[conv_real_bool] |Convert a value from real to bool || | link:../man/man9/conv_real_sint.9.html[conv_real_sint] |Convert a value from real to sint || | link:../man/man9/conv_real_uint.9.html[conv_real_uint] |Convert a value from real to uint || | link:../man/man9/conv_sint_bool.9.html[conv_sint_bool] |Convert a value from sint to bool || diff --git a/include/kins_module.h b/include/kins_module.h index 13dc8f62411..de4a1a57888 100644 --- a/include/kins_module.h +++ b/include/kins_module.h @@ -13,6 +13,9 @@ #define __LINUXCNC_KINS_MODULE_H #include "kinematics.h" +#include "rtapi_stdint.h" +#include "rtapi_bool.h" + #ifdef __cplusplus extern "C" { @@ -252,10 +255,15 @@ extern int identityKinematicsJacobian(const double *joint, #define KINS_MAX_TYPES SWITCHKINS_MAX_TYPES typedef enum { - KINS_PARAM_FLOAT = 0, - KINS_PARAM_BIT, - KINS_PARAM_S32, - KINS_PARAM_U32 + KINS_PARAM_REAL = 0, + KINS_PARAM_BOOL, + KINS_PARAM_SINT, + KINS_PARAM_UINT, + + KINS_PARAM_FLOAT __attribute__((deprecated("Please rename to KINS_PARAM_REAL"))) = KINS_PARAM_REAL, + KINS_PARAM_BIT __attribute__((deprecated("Please rename to KINS_PARAM_BOOL"))) = KINS_PARAM_BOOL, + KINS_PARAM_S32 __attribute__((deprecated("No longer supported. Please migrate to KINS_PARAM_SINT"))) = KINS_PARAM_SINT, + KINS_PARAM_U32 __attribute__((deprecated("No longer supported. Please migrate to KINS_PARAM_UINT"))) = KINS_PARAM_UINT, } kins_param_type; typedef enum { @@ -274,7 +282,12 @@ typedef struct kins_param_desc_tag { kins_param_type type; kins_param_dir dir; int tool; - double dflt; + union { + rtapi_real r; + rtapi_bool b; + rtapi_sint s; + rtapi_uint u; + } dflt; } kins_param_desc; /* The machine, as far as the kinematics is concerned. One copy may be diff --git a/src/Makefile b/src/Makefile index 05715dd7985..26bd88def1b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -496,7 +496,7 @@ genclean: -rm -f ../lib/*.so.[0-9]* -rm -rf ../docs/build/man -rm -f ../rtlib/*.$(MODULE_EXT) - -rm -f hal/components/conv_*.comp + -rm -f $(patsubst %,hal/components/%,$(notdir $(CONVERTERS))) pycheck-python-files: @echo 'Checking *.py files for python3 compatibility...' diff --git a/src/emc/kinematics/5axiskins.c b/src/emc/kinematics/5axiskins.c index d1df89d9f36..cebcd9975a4 100644 --- a/src/emc/kinematics/5axiskins.c +++ b/src/emc/kinematics/5axiskins.c @@ -63,8 +63,8 @@ // the geometry, one pin each; the maths reads it from the block static const kins_param_desc fiveaxis_params[] = { - { "pivot-length", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PIVOT_LENGTH }, - { "tool-length", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, + { "pivot-length", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PIVOT_LENGTH} }, + { "tool-length", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, }; enum { P_PIVOT_LENGTH, P_TOOL_LENGTH }; diff --git a/src/emc/kinematics/genhexkins.c b/src/emc/kinematics/genhexkins.c index 45222f0a810..3f6298f3e2e 100644 --- a/src/emc/kinematics/genhexkins.c +++ b/src/emc/kinematics/genhexkins.c @@ -150,19 +150,19 @@ enum { }; #define STRUT_ROWS(i, bx, by, bz, px, py, pz, bnx, bny, bnz, pnx, pny, pnz) \ - { "base." #i ".x", KINS_PARAM_FLOAT, KINS_IN, 0, bx }, \ - { "base." #i ".y", KINS_PARAM_FLOAT, KINS_IN, 0, by }, \ - { "base." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, bz }, \ - { "platform." #i ".x", KINS_PARAM_FLOAT, KINS_IN, 0, px }, \ - { "platform." #i ".y", KINS_PARAM_FLOAT, KINS_IN, 0, py }, \ - { "platform." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, pz }, \ - { "base-n." #i ".x", KINS_PARAM_FLOAT, KINS_IN, 0, bnx }, \ - { "base-n." #i ".y", KINS_PARAM_FLOAT, KINS_IN, 0, bny }, \ - { "base-n." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, bnz }, \ - { "platform-n." #i ".x", KINS_PARAM_FLOAT, KINS_IN, 0, pnx }, \ - { "platform-n." #i ".y", KINS_PARAM_FLOAT, KINS_IN, 0, pny }, \ - { "platform-n." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, pnz }, \ - { "correction." #i, KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 } + { "base." #i ".x", KINS_PARAM_REAL, KINS_IN, 0, {.r=bx} }, \ + { "base." #i ".y", KINS_PARAM_REAL, KINS_IN, 0, {.r=by} }, \ + { "base." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=bz} }, \ + { "platform." #i ".x", KINS_PARAM_REAL, KINS_IN, 0, {.r=px} }, \ + { "platform." #i ".y", KINS_PARAM_REAL, KINS_IN, 0, {.r=py} }, \ + { "platform." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=pz} }, \ + { "base-n." #i ".x", KINS_PARAM_REAL, KINS_IN, 0, {.r=bnx} }, \ + { "base-n." #i ".y", KINS_PARAM_REAL, KINS_IN, 0, {.r=bny} }, \ + { "base-n." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=bnz} }, \ + { "platform-n." #i ".x", KINS_PARAM_REAL, KINS_IN, 0, {.r=pnx} }, \ + { "platform-n." #i ".y", KINS_PARAM_REAL, KINS_IN, 0, {.r=pny} }, \ + { "platform-n." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=pnz} }, \ + { "correction." #i, KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} } static const kins_param_desc genhex_params[P_COUNT] = { STRUT_ROWS(0, DEFAULT_BASE_0_X, DEFAULT_BASE_0_Y, DEFAULT_BASE_0_Z, @@ -189,23 +189,23 @@ static const kins_param_desc genhex_params[P_COUNT] = { DEFAULT_PLATFORM_5_X, DEFAULT_PLATFORM_5_Y, DEFAULT_PLATFORM_5_Z, DEFAULT_BASE_5_NX, DEFAULT_BASE_5_NY, DEFAULT_BASE_5_NZ, DEFAULT_PLATFORM_5_NX, DEFAULT_PLATFORM_5_NY, DEFAULT_PLATFORM_5_NZ), - [P_LAST_ITER] = { "last-iterations", KINS_PARAM_U32, KINS_OUT, 0, 0 }, - [P_MAX_ITER] = { "max-iterations", KINS_PARAM_U32, KINS_OUT, 0, 0 }, - [P_MAX_ERROR] = { "max-error", KINS_PARAM_FLOAT, KINS_IN, 0, 500.0 }, - [P_CONV_CRITERION] = { "convergence-criterion", KINS_PARAM_FLOAT, KINS_IN, 0, 1e-9 }, - [P_ITER_LIMIT] = { "limit-iterations", KINS_PARAM_U32, KINS_IN, 0, 120 }, - [P_TOOL_OFFSET] = { "tool-offset", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, - [P_SPINDLE_OFFSET] = { "spindle-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - [P_SCREW_LEAD] = { "screw-lead", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_SCREW_LEAD }, + [P_LAST_ITER] = { "last-iterations", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, + [P_MAX_ITER] = { "max-iterations", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, + [P_MAX_ERROR] = { "max-error", KINS_PARAM_REAL, KINS_IN, 0, {.r=500.0} }, + [P_CONV_CRITERION] = { "convergence-criterion", KINS_PARAM_REAL, KINS_IN, 0, {.r=1e-9} }, + [P_ITER_LIMIT] = { "limit-iterations", KINS_PARAM_UINT, KINS_IN, 0, {.u=120} }, + [P_TOOL_OFFSET] = { "tool-offset", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, + [P_SPINDLE_OFFSET] = { "spindle-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + [P_SCREW_LEAD] = { "screw-lead", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_SCREW_LEAD} }, // the pose the forward found, for a vismach gui; switchkins provides // the skgui.* pins for the same purpose - [P_GUI_X] = { "x", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_GUI_Y] = { "y", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_GUI_Z] = { "z", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_GUI_A] = { "a", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_GUI_B] = { "b", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_GUI_C] = { "c", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - [P_FWD_FAIL] = { "fwd-kins-fail", KINS_PARAM_BIT, KINS_OUT, 0, 0 }, + [P_GUI_X] = { "x", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_GUI_Y] = { "y", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_GUI_Z] = { "z", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_GUI_A] = { "a", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_GUI_B] = { "b", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_GUI_C] = { "c", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + [P_FWD_FAIL] = { "fwd-kins-fail", KINS_PARAM_BOOL, KINS_OUT, 0, {.b=0} }, }; // the most iterations a converged solution has taken this session, kept diff --git a/src/emc/kinematics/genserfuncs.c b/src/emc/kinematics/genserfuncs.c index b4f4d59fd14..b0173450e14 100644 --- a/src/emc/kinematics/genserfuncs.c +++ b/src/emc/kinematics/genserfuncs.c @@ -68,10 +68,10 @@ enum { }; #define JOINT_ROWS(i, a, alpha, d) \ - { "A-" #i, KINS_PARAM_FLOAT, KINS_IN, 0, a }, \ - { "ALPHA-" #i, KINS_PARAM_FLOAT, KINS_IN, 0, alpha }, \ - { "D-" #i, KINS_PARAM_FLOAT, KINS_IN, 0, d }, \ - { "unrotate-" #i, KINS_PARAM_S32, KINS_IN, 0, 0 } + { "A-" #i, KINS_PARAM_REAL, KINS_IN, 0, {.r=a} }, \ + { "ALPHA-" #i, KINS_PARAM_REAL, KINS_IN, 0, {.r=alpha} }, \ + { "D-" #i, KINS_PARAM_REAL, KINS_IN, 0, {.r=d} }, \ + { "unrotate-" #i, KINS_PARAM_SINT, KINS_IN, 0, {.s=0} } const kins_param_desc GENSER_PARAMS[P_COUNT] = { JOINT_ROWS(0, DEFAULT_A1, DEFAULT_ALPHA1, DEFAULT_D1), @@ -80,8 +80,8 @@ const kins_param_desc GENSER_PARAMS[P_COUNT] = { JOINT_ROWS(3, DEFAULT_A4, DEFAULT_ALPHA4, DEFAULT_D4), JOINT_ROWS(4, DEFAULT_A5, DEFAULT_ALPHA5, DEFAULT_D5), JOINT_ROWS(5, DEFAULT_A6, DEFAULT_ALPHA6, DEFAULT_D6), - [P_LAST_ITER] = { "last-iterations", KINS_PARAM_U32, KINS_OUT, 0, 0 }, - [P_MAX_ITER] = { "max-iterations", KINS_PARAM_U32, KINS_IN, 0, GENSER_DEFAULT_MAX_ITERATIONS }, + [P_LAST_ITER] = { "last-iterations", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, + [P_MAX_ITER] = { "max-iterations", KINS_PARAM_UINT, KINS_IN, 0, {.u=GENSER_DEFAULT_MAX_ITERATIONS} }, }; const int GENSER_NPARAMS = P_COUNT; diff --git a/src/emc/kinematics/kins_util.c b/src/emc/kinematics/kins_util.c index b66b3d9b9e7..daf6a7b9e07 100644 --- a/src/emc/kinematics/kins_util.c +++ b/src/emc/kinematics/kins_util.c @@ -1532,8 +1532,16 @@ int kinsParamsInit(kins_params *p, return -1; } for (i = 0; i < info->nparams; i++) { - p->geometry[i] = info->params[i].dflt; - if (info->params[i].tool) { p->tool.tran.z = info->params[i].dflt; } + double v; + switch(info->params[i].type) { + case KINS_PARAM_REAL: v = info->params[i].dflt.r; break; + case KINS_PARAM_BOOL: v = info->params[i].dflt.b ? 1.0 : 0.0; break; + case KINS_PARAM_SINT: v = info->params[i].dflt.s; break; + case KINS_PARAM_UINT: v = info->params[i].dflt.u; break; + default: v = 0.0; break; + } + p->geometry[i] = v; + if (info->params[i].tool) { p->tool.tran.z = v; } } return 0; } // kinsParamsInit() @@ -1789,17 +1797,17 @@ int kinsParamsPinsCreate(int comp_id, const char *prefix, const kins_param_desc *d = ¶ms[i]; hal_pdir_t dir = d->dir == KINS_OUT ? HAL_OUT : d->dir == KINS_IO ? HAL_IO : HAL_IN; switch (d->type) { - case KINS_PARAM_FLOAT: - res += hal_pin_new_real(comp_id, dir, &pins[i].r, d->dflt, "%s.%s", prefix, d->name); + case KINS_PARAM_REAL: + res += hal_pin_new_real(comp_id, dir, &pins[i].r, d->dflt.r, "%s.%s", prefix, d->name); break; - case KINS_PARAM_BIT: - res += hal_pin_new_bool(comp_id, dir, &pins[i].b, d->dflt != 0, "%s.%s", prefix, d->name); + case KINS_PARAM_BOOL: + res += hal_pin_new_bool(comp_id, dir, &pins[i].b, d->dflt.b, "%s.%s", prefix, d->name); break; - case KINS_PARAM_S32: - res += hal_pin_new_si32(comp_id, dir, &pins[i].s, (rtapi_s32)d->dflt, "%s.%s", prefix, d->name); + case KINS_PARAM_SINT: + res += hal_pin_new_sint(comp_id, dir, &pins[i].s, d->dflt.s, "%s.%s", prefix, d->name); break; - case KINS_PARAM_U32: - res += hal_pin_new_ui32(comp_id, dir, &pins[i].u, (rtapi_u32)d->dflt, "%s.%s", prefix, d->name); + case KINS_PARAM_UINT: + res += hal_pin_new_uint(comp_id, dir, &pins[i].u, d->dflt.u, "%s.%s", prefix, d->name); break; default: res = -1; @@ -1824,10 +1832,10 @@ void kinsParamsPinsRead(const kins_pin_ref *pins, double v; if (d->dir == KINS_OUT) { continue; } switch (d->type) { - case KINS_PARAM_FLOAT: v = hal_get_real(pins[i].r); break; - case KINS_PARAM_BIT: v = hal_get_bool(pins[i].b) ? 1.0 : 0.0; break; - case KINS_PARAM_S32: v = hal_get_si32(pins[i].s); break; - case KINS_PARAM_U32: v = hal_get_ui32(pins[i].u); break; + case KINS_PARAM_REAL: v = hal_get_real(pins[i].r); break; + case KINS_PARAM_BOOL: v = hal_get_bool(pins[i].b) ? 1.0 : 0.0; break; + case KINS_PARAM_SINT: v = hal_get_sint(pins[i].s); break; + case KINS_PARAM_UINT: v = hal_get_uint(pins[i].u); break; default: v = 0; } p->geometry[i] = v; @@ -1845,10 +1853,24 @@ void kinsParamsPinsWrite(const kins_pin_ref *pins, const kins_param_desc *d = ¶ms[i]; if (d->dir != KINS_OUT) { continue; } switch (d->type) { - case KINS_PARAM_FLOAT: hal_set_real(pins[i].r, s->out[i]); break; - case KINS_PARAM_BIT: hal_set_bool(pins[i].b, s->out[i] != 0); break; - case KINS_PARAM_S32: hal_set_si32(pins[i].s, (rtapi_s32)s->out[i]); break; - case KINS_PARAM_U32: hal_set_ui32(pins[i].u, (rtapi_u32)s->out[i]); break; + case KINS_PARAM_REAL: hal_set_real(pins[i].r, s->out[i]); break; + case KINS_PARAM_BOOL: hal_set_bool(pins[i].b, s->out[i] != 0); break; + case KINS_PARAM_SINT: + if (s->out[i] >= (rtapi_real)RTAPI_SINT_MAX) + hal_set_sint(pins[i].s, RTAPI_SINT_MAX); + else if (s->out[i] <= (rtapi_real)RTAPI_SINT_MIN) + hal_set_sint(pins[i].s, RTAPI_SINT_MIN); + else + hal_set_sint(pins[i].s, (rtapi_sint)s->out[i]); + break; + case KINS_PARAM_UINT: + if (s->out[i] < 0.0) + hal_set_uint(pins[i].u, 0); + else if (s->out[i] >= (rtapi_real)RTAPI_UINT_MAX) + hal_set_uint(pins[i].u, RTAPI_UINT_MAX); + else + hal_set_uint(pins[i].u, s->out[i]); + break; default: break; } } diff --git a/src/emc/kinematics/lineardeltakins.c b/src/emc/kinematics/lineardeltakins.c index d61f3c58ff9..91fdca727cf 100644 --- a/src/emc/kinematics/lineardeltakins.c +++ b/src/emc/kinematics/lineardeltakins.c @@ -25,8 +25,8 @@ // the two lengths, one pin each static const kins_param_desc ld_params[] = { - { "R", KINS_PARAM_FLOAT, KINS_IN, 0, DELTA_RADIUS }, - { "L", KINS_PARAM_FLOAT, KINS_IN, 0, DELTA_DIAGONAL_ROD }, + { "R", KINS_PARAM_REAL, KINS_IN, 0, {.r=DELTA_RADIUS} }, + { "L", KINS_PARAM_REAL, KINS_IN, 0, {.r=DELTA_DIAGONAL_ROD} }, }; enum { P_R, P_L }; diff --git a/src/emc/kinematics/maxkins.c b/src/emc/kinematics/maxkins.c index a32981d12cf..80f6e2c555c 100644 --- a/src/emc/kinematics/maxkins.c +++ b/src/emc/kinematics/maxkins.c @@ -33,9 +33,9 @@ // the geometry, one pin each; the maths reads it from the block static const kins_param_desc max_params[] = { - { "pivot-length", KINS_PARAM_FLOAT, KINS_IO, 0, 0.666 }, - { "conventional-directions", KINS_PARAM_BIT, KINS_IN, 0, 0 }, // default is unconventional - { "tool-length", KINS_PARAM_FLOAT, KINS_IN, 1, 0 }, + { "pivot-length", KINS_PARAM_REAL, KINS_IO, 0, {.r=0.666} }, + { "conventional-directions", KINS_PARAM_BOOL, KINS_IN, 0, {.b=0} }, // default is unconventional + { "tool-length", KINS_PARAM_REAL, KINS_IN, 1, {.r=0} }, }; enum { P_PIVOT_LENGTH, P_CON, P_TOOL_LENGTH }; diff --git a/src/emc/kinematics/pentakins.c b/src/emc/kinematics/pentakins.c index 4be3a0918cf..31acd5cc68a 100644 --- a/src/emc/kinematics/pentakins.c +++ b/src/emc/kinematics/pentakins.c @@ -79,11 +79,11 @@ enum { }; #define STRUT_ROWS(i, bx, by, bz, er, ez) \ - { "base." #i ".x", KINS_PARAM_FLOAT, KINS_IN, 0, bx }, \ - { "base." #i ".y", KINS_PARAM_FLOAT, KINS_IN, 0, by }, \ - { "base." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, bz }, \ - { "effector." #i ".r", KINS_PARAM_FLOAT, KINS_IN, 0, er }, \ - { "effector." #i ".z", KINS_PARAM_FLOAT, KINS_IN, 0, ez } + { "base." #i ".x", KINS_PARAM_REAL, KINS_IN, 0, {.r=bx} }, \ + { "base." #i ".y", KINS_PARAM_REAL, KINS_IN, 0, {.r=by} }, \ + { "base." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=bz} }, \ + { "effector." #i ".r", KINS_PARAM_REAL, KINS_IN, 0, {.r=er} }, \ + { "effector." #i ".z", KINS_PARAM_REAL, KINS_IN, 0, {.r=ez} } static const kins_param_desc penta_params[P_COUNT] = { STRUT_ROWS(0, DEFAULT_BASE_0_X, DEFAULT_BASE_0_Y, DEFAULT_BASE_0_Z, DEFAULT_EFFECTOR_0_R, DEFAULT_EFFECTOR_0_Z), @@ -91,12 +91,12 @@ static const kins_param_desc penta_params[P_COUNT] = { STRUT_ROWS(2, DEFAULT_BASE_2_X, DEFAULT_BASE_2_Y, DEFAULT_BASE_2_Z, DEFAULT_EFFECTOR_2_R, DEFAULT_EFFECTOR_2_Z), STRUT_ROWS(3, DEFAULT_BASE_3_X, DEFAULT_BASE_3_Y, DEFAULT_BASE_3_Z, DEFAULT_EFFECTOR_3_R, DEFAULT_EFFECTOR_3_Z), STRUT_ROWS(4, DEFAULT_BASE_4_X, DEFAULT_BASE_4_Y, DEFAULT_BASE_4_Z, DEFAULT_EFFECTOR_4_R, DEFAULT_EFFECTOR_4_Z), - [P_LAST_ITER] = { "last-iterations", KINS_PARAM_U32, KINS_OUT, 0, 0 }, - [P_MAX_ITER] = { "max-iterations", KINS_PARAM_U32, KINS_OUT, 0, 0 }, - [P_MAX_ERROR] = { "max-error", KINS_PARAM_FLOAT, KINS_IO, 0, 100.0 }, - [P_CONV_CRITERION] = { "convergence-criterion", KINS_PARAM_FLOAT, KINS_IO, 0, 1e-9 }, - [P_ITER_LIMIT] = { "limit-iterations", KINS_PARAM_U32, KINS_IO, 0, 120 }, - [P_TOOL_OFFSET] = { "tool-offset", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, + [P_LAST_ITER] = { "last-iterations", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, + [P_MAX_ITER] = { "max-iterations", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, + [P_MAX_ERROR] = { "max-error", KINS_PARAM_REAL, KINS_IO, 0, {.r=100.0} }, + [P_CONV_CRITERION] = { "convergence-criterion", KINS_PARAM_REAL, KINS_IO, 0, {.r=1e-9} }, + [P_ITER_LIMIT] = { "limit-iterations", KINS_PARAM_UINT, KINS_IO, 0, {.u=120} }, + [P_TOOL_OFFSET] = { "tool-offset", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, }; // the most iterations a converged solution has taken this session, kept diff --git a/src/emc/kinematics/pumakins.c b/src/emc/kinematics/pumakins.c index 220042cc3bf..82b1e2bdd81 100644 --- a/src/emc/kinematics/pumakins.c +++ b/src/emc/kinematics/pumakins.c @@ -27,11 +27,11 @@ // the five dimensions, one pin each; the maths reads them from the block static const kins_param_desc puma_params[] = { - { "A2", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PUMA560_A2 }, - { "A3", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PUMA560_A3 }, - { "D3", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PUMA560_D3 }, - { "D4", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PUMA560_D4 }, - { "D6", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_PUMA560_D6 }, + { "A2", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PUMA560_A2} }, + { "A3", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PUMA560_A3} }, + { "D3", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PUMA560_D3} }, + { "D4", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PUMA560_D4} }, + { "D6", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_PUMA560_D6} }, }; enum { P_A2, P_A3, P_D3, P_D4, P_D6 }; diff --git a/src/emc/kinematics/rosekins.c b/src/emc/kinematics/rosekins.c index 1c807d5c2ce..d1587504d3a 100644 --- a/src/emc/kinematics/rosekins.c +++ b/src/emc/kinematics/rosekins.c @@ -32,9 +32,9 @@ MODULE_LICENSE("GPL"); // the inverse reports the turn count it keeps and the angles it saw static const kins_param_desc rose_params[] = { - { "revolutions", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - { "theta_degrees", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, - { "bigtheta_degrees", KINS_PARAM_FLOAT, KINS_OUT, 0, 0.0 }, + { "revolutions", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + { "theta_degrees", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, + { "bigtheta_degrees", KINS_PARAM_REAL, KINS_OUT, 0, {.r=0.0} }, }; enum { O_REVOLUTIONS, O_THETA, O_BIGTHETA }; diff --git a/src/emc/kinematics/rotarydeltakins.c b/src/emc/kinematics/rotarydeltakins.c index d406406e76d..9de7c45b374 100644 --- a/src/emc/kinematics/rotarydeltakins.c +++ b/src/emc/kinematics/rotarydeltakins.c @@ -26,10 +26,10 @@ // the four lengths, one pin each static const kins_param_desc rd_params[] = { - { "platformradius", KINS_PARAM_FLOAT, KINS_IN, 0, RDELTA_PFR }, - { "thighlength", KINS_PARAM_FLOAT, KINS_IN, 0, RDELTA_TL }, - { "shinlength", KINS_PARAM_FLOAT, KINS_IN, 0, RDELTA_SL }, - { "footradius", KINS_PARAM_FLOAT, KINS_IN, 0, RDELTA_FR }, + { "platformradius", KINS_PARAM_REAL, KINS_IN, 0, {.r=RDELTA_PFR} }, + { "thighlength", KINS_PARAM_REAL, KINS_IN, 0, {.r=RDELTA_TL} }, + { "shinlength", KINS_PARAM_REAL, KINS_IN, 0, {.r=RDELTA_SL} }, + { "footradius", KINS_PARAM_REAL, KINS_IN, 0, {.r=RDELTA_FR} }, }; enum { P_PFR, P_TL, P_SL, P_FR }; diff --git a/src/emc/kinematics/scarakins.c b/src/emc/kinematics/scarakins.c index a416724a5c2..a3340a968c5 100644 --- a/src/emc/kinematics/scarakins.c +++ b/src/emc/kinematics/scarakins.c @@ -68,12 +68,12 @@ // the six dimensions, one pin each; the maths reads them from the block static const kins_param_desc scara_params[] = { - { "D1", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D1 }, - { "D2", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D2 }, - { "D3", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D3 }, - { "D4", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D4 }, - { "D5", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D5 }, - { "D6", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_D6 }, + { "D1", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D1} }, + { "D2", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D2} }, + { "D3", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D3} }, + { "D4", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D4} }, + { "D5", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D5} }, + { "D6", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_D6} }, }; enum { P_D1, P_D2, P_D3, P_D4, P_D5, P_D6 }; diff --git a/src/emc/kinematics/three21kins.c b/src/emc/kinematics/three21kins.c index 438d36ecf0c..a22ed430338 100644 --- a/src/emc/kinematics/three21kins.c +++ b/src/emc/kinematics/three21kins.c @@ -30,14 +30,14 @@ // the eight dimensions, one pin each; the maths reads them from the block static const kins_param_desc three21_params[] = { - { "A1", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_A1 }, - { "A2", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_A2 }, - { "A3", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_A3 }, - { "D1", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_D1 }, - { "D2", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_D2 }, - { "D3", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_D3 }, - { "D4", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_D4 }, - { "D6", KINS_PARAM_FLOAT, KINS_IN, 0, DEFAULT_THREE21_D6 }, + { "A1", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_A1} }, + { "A2", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_A2} }, + { "A3", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_A3} }, + { "D1", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_D1} }, + { "D2", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_D2} }, + { "D3", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_D3} }, + { "D4", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_D4} }, + { "D6", KINS_PARAM_REAL, KINS_IN, 0, {.r=DEFAULT_THREE21_D6} }, }; enum { P_A1, P_A2, P_A3, P_D1, P_D2, P_D3, P_D4, P_D6 }; diff --git a/src/emc/kinematics/tripodkins.c b/src/emc/kinematics/tripodkins.c index 7ce648fc581..2323788eff8 100644 --- a/src/emc/kinematics/tripodkins.c +++ b/src/emc/kinematics/tripodkins.c @@ -72,9 +72,9 @@ // the base geometry, one pin each, poked from HAL as before static const kins_param_desc tripod_params[] = { - { "Bx", KINS_PARAM_FLOAT, KINS_IO, 0, 1.0 }, - { "Cx", KINS_PARAM_FLOAT, KINS_IO, 0, 1.0 }, - { "Cy", KINS_PARAM_FLOAT, KINS_IO, 0, 1.0 }, + { "Bx", KINS_PARAM_REAL, KINS_IO, 0, {.r=1.0} }, + { "Cx", KINS_PARAM_REAL, KINS_IO, 0, {.r=1.0} }, + { "Cy", KINS_PARAM_REAL, KINS_IO, 0, {.r=1.0} }, }; enum { P_BX, P_CX, P_CY }; diff --git a/src/emc/kinematics/trtfuncs.c b/src/emc/kinematics/trtfuncs.c index 4aa6c99a925..2836f9581bf 100644 --- a/src/emc/kinematics/trtfuncs.c +++ b/src/emc/kinematics/trtfuncs.c @@ -42,14 +42,14 @@ // the geometry both machines share, one pin each const kins_param_desc TRT_PARAMS[] = { - { "x-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "x-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "tool-offset", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, - { "conventional-directions", KINS_PARAM_BIT, KINS_IN, 0, 0.0 }, // default: false + { "x-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "x-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "tool-offset", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, + { "conventional-directions", KINS_PARAM_BOOL, KINS_IN, 0, {.b=0} }, // default: false }; const int TRT_NPARAMS = sizeof(TRT_PARAMS)/sizeof(TRT_PARAMS[0]); diff --git a/src/emc/kinematics/userkfuncs.c b/src/emc/kinematics/userkfuncs.c index 2d76ef2fedd..09dd076a0dd 100644 --- a/src/emc/kinematics/userkfuncs.c +++ b/src/emc/kinematics/userkfuncs.c @@ -83,8 +83,8 @@ int userkKinematicsSetup(const int comp_id, if (!udata) goto error; // HAL_IO used to allow resetting demo pins: - res += hal_pin_new_si32(comp_id, HAL_IO, &(udata->fct), 0, "userk.fct"); - res += hal_pin_new_si32(comp_id, HAL_IO, &(udata->ict), 0, "userk.ict"); + res += hal_pin_new_sint(comp_id, HAL_IO, &(udata->fct), 0, "userk.fct"); + res += hal_pin_new_sint(comp_id, HAL_IO, &(udata->ict), 0, "userk.ict"); if (res) goto error; userk_inited = 1; @@ -104,7 +104,7 @@ int userkKinematicsForward(const double *joint, "userkKinematics: not initialized\n"); return -1; } - hal_set_si32(udata->fct, hal_get_si32(udata->fct) + 1); + hal_set_sint(udata->fct, hal_get_sint(udata->fct) + 1); return identityKinematicsForward(joint,world,fflags,iflags); } @@ -113,6 +113,6 @@ int userkKinematicsInverse(const EmcPose * pos, const KINEMATICS_INVERSE_FLAGS * iflags, KINEMATICS_FORWARD_FLAGS * fflags) { - hal_set_si32(udata->ict, hal_get_si32(udata->ict) + 1); + hal_set_sint(udata->ict, hal_get_sint(udata->ict) + 1); return identityKinematicsInverse(pos,joint,iflags,fflags); } diff --git a/src/emc/kinematics_userspace/kinematics_user.c b/src/emc/kinematics_userspace/kinematics_user.c index 92de369697a..24e37b47d52 100644 --- a/src/emc/kinematics_userspace/kinematics_user.c +++ b/src/emc/kinematics_userspace/kinematics_user.c @@ -122,10 +122,10 @@ static int note_pin(KinematicsUserContext *ctx, const char *pin_name, static hal_type_t hal_type_of(kins_param_type t) { switch (t) { - case KINS_PARAM_BIT: return HAL_BOOL; - case KINS_PARAM_S32: return HAL_SINT; - case KINS_PARAM_U32: return HAL_UINT; - default: return HAL_REAL; + case KINS_PARAM_BOOL: return HAL_BOOL; + case KINS_PARAM_SINT: return HAL_SINT; + case KINS_PARAM_UINT: return HAL_UINT; + default: return HAL_REAL; } } diff --git a/src/emc/motion/axis.c b/src/emc/motion/axis.c index f6dd8d4aef0..4aa4a26ba13 100644 --- a/src/emc/motion/axis.c +++ b/src/emc/motion/axis.c @@ -447,7 +447,7 @@ void axis_handle_jogwheels(bool motion_teleop_flag, bool motion_enable_flag, boo aaccel_limit = ajog_accel_fraction * axis->acc_limit; } - new_ajog_counts = hal_get_si32(axis_data->ajog_counts); + new_ajog_counts = hal_get_sint(axis_data->ajog_counts); delta = new_ajog_counts - axis->old_ajog_counts; axis->old_ajog_counts = new_ajog_counts; if ( first_pass ) { continue; } diff --git a/src/emc/task/taskclass.cc b/src/emc/task/taskclass.cc index 5f05e638334..25b29756958 100644 --- a/src/emc/task/taskclass.cc +++ b/src/emc/task/taskclass.cc @@ -54,11 +54,11 @@ int Task::iocontrol_hal_init(void) CHK(hal_pin_new_bool(comp_id, HAL_OUT, &iocontrol_data->user_request_enable, 0, IOC0".user-request-enable")); CHK(hal_pin_new_bool(comp_id, HAL_OUT, &iocontrol_data->coolant_mist, 0, IOC0".coolant-mist")); CHK(hal_pin_new_bool(comp_id, HAL_OUT, &iocontrol_data->coolant_flood, 0, IOC0".coolant-flood")); - CHK(hal_pin_new_si32(comp_id, HAL_OUT, &iocontrol_data->tool_prep_pocket, 0, IOC0".tool-prep-pocket")); - CHK(hal_pin_new_si32(comp_id, HAL_OUT, &iocontrol_data->tool_from_pocket, 0, IOC0".tool-from-pocket")); - CHK(hal_pin_new_si32(comp_id, HAL_OUT, &iocontrol_data->tool_prep_index, 0, IOC0".tool-prep-index")); - CHK(hal_pin_new_si32(comp_id, HAL_OUT, &iocontrol_data->tool_prep_number, 0, IOC0".tool-prep-number")); - CHK(hal_pin_new_si32(comp_id, HAL_OUT, &iocontrol_data->tool_number, 0, IOC0".tool-number")); + CHK(hal_pin_new_sint(comp_id, HAL_OUT, &iocontrol_data->tool_prep_pocket, 0, IOC0".tool-prep-pocket")); + CHK(hal_pin_new_sint(comp_id, HAL_OUT, &iocontrol_data->tool_from_pocket, 0, IOC0".tool-from-pocket")); + CHK(hal_pin_new_sint(comp_id, HAL_OUT, &iocontrol_data->tool_prep_index, 0, IOC0".tool-prep-index")); + CHK(hal_pin_new_sint(comp_id, HAL_OUT, &iocontrol_data->tool_prep_number, 0, IOC0".tool-prep-number")); + CHK(hal_pin_new_sint(comp_id, HAL_OUT, &iocontrol_data->tool_number, 0, IOC0".tool-number")); CHK(hal_pin_new_bool(comp_id, HAL_OUT, &iocontrol_data->tool_prepare, 0, IOC0".tool-prepare")); CHK(hal_pin_new_bool(comp_id, HAL_IN, &iocontrol_data->tool_prepared, 0, IOC0".tool-prepared")); CHK(hal_pin_new_bool(comp_id, HAL_OUT, &iocontrol_data->tool_change, 0, IOC0".tool-change")); @@ -87,12 +87,12 @@ void Task::hal_init_pins(void) hal_set_bool(iocontrol_data->coolant_mist, 0); /* coolant mist output pin */ hal_set_bool(iocontrol_data->coolant_flood, 0); /* coolant flood output pin */ hal_set_bool(iocontrol_data->tool_prepare, 0); /* output, pin that notifies HAL it needs to prepare a tool */ - hal_set_si32(iocontrol_data->tool_prep_number, 0); /* output, pin that holds the tool number to be prepared, only valid when tool-prepare=TRUE */ - hal_set_si32(iocontrol_data->tool_prep_pocket, 0); /* output, pin that holds the pocketno for the tool to be prepared, only valid when tool-prepare=TRUE */ - hal_set_si32(iocontrol_data->tool_from_pocket, 0); /* output, always 0 at startup */ - hal_set_si32(iocontrol_data->tool_prep_index, 0); /* output, pin that holds the internal index (idx) of the tool to be prepared, for debug */ + hal_set_sint(iocontrol_data->tool_prep_number, 0); /* output, pin that holds the tool number to be prepared, only valid when tool-prepare=TRUE */ + hal_set_sint(iocontrol_data->tool_prep_pocket, 0); /* output, pin that holds the pocketno for the tool to be prepared, only valid when tool-prepare=TRUE */ + hal_set_sint(iocontrol_data->tool_from_pocket, 0); /* output, always 0 at startup */ + hal_set_sint(iocontrol_data->tool_prep_index, 0); /* output, pin that holds the internal index (idx) of the tool to be prepared, for debug */ hal_set_bool(iocontrol_data->tool_change, 0); /* output, notifies a tool-change should happen (emc should be in the tool-change position) */ - hal_set_si32(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); + hal_set_sint(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); } Task *task_methods; @@ -467,29 +467,29 @@ int Task::emcToolPrepare(int toolno) } rtapi_print_msg(RTAPI_MSG_DBG, "EMC_TOOL_PREPARE tool=%d idx=%d\n", toolno, idx); - hal_set_si32(iocontrol_data->tool_prep_index, idx); // any type of changer + hal_set_sint(iocontrol_data->tool_prep_index, idx); // any type of changer // Note: some of the following logic could be simplified // but is maintained to preserve runtests expectations // Set HAL pins for tool number, pocket, and index. if (random_toolchanger) { // RANDOM_TOOLCHANGER - hal_set_si32(iocontrol_data->tool_prep_number, tdata.toolno); + hal_set_sint(iocontrol_data->tool_prep_number, tdata.toolno); if (idx == 0) { emcioStatus.tool.pocketPrepped = 0; // pocketPrepped is an idx - hal_set_si32(iocontrol_data->tool_prep_pocket, 0); + hal_set_sint(iocontrol_data->tool_prep_pocket, 0); return 0; } - hal_set_si32(iocontrol_data->tool_prep_pocket, tdata.pocketno); + hal_set_sint(iocontrol_data->tool_prep_pocket, tdata.pocketno); } else { // NON_RANDOM_TOOLCHANGER if (idx == 0) { emcioStatus.tool.pocketPrepped = 0; // pocketPrepped is an idx - hal_set_si32(iocontrol_data->tool_prep_number, 0); - hal_set_si32(iocontrol_data->tool_prep_pocket, 0); + hal_set_sint(iocontrol_data->tool_prep_number, 0); + hal_set_sint(iocontrol_data->tool_prep_pocket, 0); } else { - hal_set_si32(iocontrol_data->tool_prep_number, tdata.toolno); - hal_set_si32(iocontrol_data->tool_prep_pocket, tdata.pocketno); + hal_set_sint(iocontrol_data->tool_prep_number, tdata.toolno); + hal_set_sint(iocontrol_data->tool_prep_pocket, tdata.pocketno); } } // it doesn't make sense to prep the spindle pocket @@ -613,9 +613,9 @@ int Task::emcToolSetNumber(int number)//EMC_TOOL_SET_NUMBER "EMC_TOOL_SET_NUMBER old_loaded_tool=%d new_idx_number=%d new_tool=%d\n" , emcioStatus.tool.toolInSpindle, idx, tdata.toolno); //likewise in HAL - hal_set_si32(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); + hal_set_sint(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); if (emcioStatus.tool.toolInSpindle == 0) { - emcioStatus.tool.toolFromPocket = hal_set_si32(iocontrol_data->tool_from_pocket, 0); // no tool in spindle + emcioStatus.tool.toolFromPocket = hal_set_sint(iocontrol_data->tool_from_pocket, 0); // no tool in spindle } return 0; @@ -638,7 +638,10 @@ int Task::emcToolSetNumber(int number)//EMC_TOOL_SET_NUMBER int Task::read_tool_inputs(void) { if (hal_get_bool(iocontrol_data->tool_prepare) && hal_get_bool(iocontrol_data->tool_prepared)) { - emcioStatus.tool.pocketPrepped = hal_get_si32(iocontrol_data->tool_prep_index); //check if tool has been (idx) prepared + // We get the clamped HAL value from tool_prep_index because it is + // assigned elsewhere to int and would be truncated. The content + // is a relative small index value anyway. + emcioStatus.tool.pocketPrepped = hal_get_si32_clamped(iocontrol_data->tool_prep_index); //check if tool has been (idx) prepared hal_set_bool(iocontrol_data->tool_prepare, 0); emcioStatus.status = RCS_STATUS::DONE; // we finally finished to do tool-changing, signal task with RCS_DONE return 10; //prepped finished @@ -647,7 +650,7 @@ int Task::read_tool_inputs(void) if (hal_get_bool(iocontrol_data->tool_change) && hal_get_bool(iocontrol_data->tool_changed)) { if(!random_toolchanger && emcioStatus.tool.pocketPrepped == 0) { emcioStatus.tool.toolInSpindle = 0; - emcioStatus.tool.toolFromPocket = hal_set_si32(iocontrol_data->tool_from_pocket, 0); + emcioStatus.tool.toolFromPocket = hal_set_sint(iocontrol_data->tool_from_pocket, 0); } else { // the tool now in the spindle is the one that was prepared CANON_TOOL_TABLE tdata; @@ -655,17 +658,17 @@ int Task::read_tool_inputs(void) UNEXPECTED_MSG; return -1; } emcioStatus.tool.toolInSpindle = tdata.toolno; - emcioStatus.tool.toolFromPocket = hal_set_si32(iocontrol_data->tool_from_pocket, tdata.pocketno); + emcioStatus.tool.toolFromPocket = hal_set_sint(iocontrol_data->tool_from_pocket, tdata.pocketno); } if (emcioStatus.tool.toolInSpindle == 0) { - emcioStatus.tool.toolFromPocket = hal_set_si32(iocontrol_data->tool_from_pocket, 0); + emcioStatus.tool.toolFromPocket = hal_set_sint(iocontrol_data->tool_from_pocket, 0); } - hal_set_si32(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); //likewise in HAL + hal_set_sint(iocontrol_data->tool_number, emcioStatus.tool.toolInSpindle); //likewise in HAL load_tool(emcioStatus.tool.pocketPrepped); emcioStatus.tool.pocketPrepped = -1; //reset the tool preped number, -1 to permit tool 0 to be loaded - hal_set_si32(iocontrol_data->tool_prep_number, 0); //likewise in HAL - hal_set_si32(iocontrol_data->tool_prep_pocket, 0); //likewise in HAL - hal_set_si32(iocontrol_data->tool_prep_index, 0); //likewise in HAL + hal_set_sint(iocontrol_data->tool_prep_number, 0); //likewise in HAL + hal_set_sint(iocontrol_data->tool_prep_pocket, 0); //likewise in HAL + hal_set_sint(iocontrol_data->tool_prep_index, 0); //likewise in HAL hal_set_bool(iocontrol_data->tool_change, 0); //also reset the tool change signal emcioStatus.status = RCS_STATUS::DONE; // we finally finished to do tool-changing, signal task with RCS_DONE return 11; //change finished diff --git a/src/hal/components/.gitignore b/src/hal/components/.gitignore index 01a447a5a38..c18fb61471b 100644 --- a/src/hal/components/.gitignore +++ b/src/hal/components/.gitignore @@ -1 +1,2 @@ conv_*.comp +!conv_real_bool.comp diff --git a/src/hal/components/comp.comp b/src/hal/components/comp.comp index cf27ca469e0..8365df255fb 100644 --- a/src/hal/components/comp.comp +++ b/src/hal/components/comp.comp @@ -16,6 +16,7 @@ option period no; function _ "Update the comparator"; license "GPL"; author "Jeff Epler"; +see_also "conv_real_bool(9)."; ;; FUNCTION(_) { rtapi_real tmp = in1 - in0; diff --git a/src/hal/components/conv_real_bool.comp b/src/hal/components/conv_real_bool.comp new file mode 100644 index 00000000000..a00ee0d2dd7 --- /dev/null +++ b/src/hal/components/conv_real_bool.comp @@ -0,0 +1,23 @@ +component conv_real_bool """Convert a value from real to bool + +The output value `out` is False when `in` is within `±eps` of zero. +The `out` pin is set to True once the `in` value reaches beyond. + +* `in` < `-eps` -> `out` = True +* `in` > `+eps` -> `out` = True +* `-eps` ≤ `in` ≤ `+eps` -> `out` = False + +In effect: `out = |in| > |eps|` + +"""; +pin in real in "Input value to convert."; +pin out bool out "Output value is False when input is within ±eps."; +param rw real eps = 1e-8 "Epsilon value to determine the input to be zero."; +option period no; +function _ "Update 'out' based on 'in' to be within 'eps' or not."; +license "GPL"; +author "LinuxCNC authors"; +see_also "comp(9)."; +include ; +;; +out_set(fabs(in) > fabs(eps)); diff --git a/src/hal/components/ilowpass.comp b/src/hal/components/ilowpass.comp index 79f4fe9c540..f6a01c57720 100644 --- a/src/hal/components/ilowpass.comp +++ b/src/hal/components/ilowpass.comp @@ -13,9 +13,9 @@ on the MPG. Choose *gain* according to the smoothing level desired. Divide the **axis**.__N__.**jog-scale** values by *scale*."""; -pin in si32 in; +pin in sint in; -pin out si32 out """*out* tracks *in* * *scale* through a low-pass +pin out sint out """*out* tracks *in* * *scale* through a low-pass filter of *gain* per period."""; param rw real scale = 1024 """A scale factor applied to the output diff --git a/src/hal/components/matrixkins.comp b/src/hal/components/matrixkins.comp index ff542cde5d7..6d541317a3f 100644 --- a/src/hal/components/matrixkins.comp +++ b/src/hal/components/matrixkins.comp @@ -185,15 +185,15 @@ license "GPL"; // the calibration matrix, one pin each; the maths reads it from the block static const kins_param_desc matrix_params[] = { - { "C_xx", KINS_PARAM_FLOAT, KINS_IN, 0, 1.0 }, - { "C_xy", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_xz", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_yx", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_yy", KINS_PARAM_FLOAT, KINS_IN, 0, 1.0 }, - { "C_yz", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_zx", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_zy", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "C_zz", KINS_PARAM_FLOAT, KINS_IN, 0, 1.0 }, + { "C_xx", KINS_PARAM_REAL, KINS_IN, 0, {.r=1.0} }, + { "C_xy", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_xz", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_yx", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_yy", KINS_PARAM_REAL, KINS_IN, 0, {.r=1.0} }, + { "C_yz", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_zx", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_zy", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "C_zz", KINS_PARAM_REAL, KINS_IN, 0, {.r=1.0} }, }; enum { C_XX, C_XY, C_XZ, C_YX, C_YY, C_YZ, C_ZX, C_ZY, C_ZZ }; diff --git a/src/hal/components/sim_encoder.c b/src/hal/components/sim_encoder.c index 1e02030b178..df092f874d7 100644 --- a/src/hal/components/sim_encoder.c +++ b/src/hal/components/sim_encoder.c @@ -87,7 +87,7 @@ RTAPI_MP_ARRAY_STRING(names, MAX_CHAN, "names of sim_encoder"); typedef struct { signed long addval; /* frequency generator add value */ - unsigned long accum; /* frequency generator accumulator */ + signed long accum; /* frequency generator accumulator */ signed char state; /* current quadrature state */ long cycle; /* current cycle */ hal_bool_t phaseA; /* pins for output signals */ @@ -239,25 +239,24 @@ void rtapi_app_exit(void) static void make_pulses(void *arg, long period) { sim_enc_t *sim_enc; - int n, overunder, dir; + int n, overunder; /* store period so scaling constants can be (re)calculated */ periodns = period; /* point to sim_enc data structures */ sim_enc = arg; for (n = 0; n < howmany; n++) { - /* get current value of bit 31 */ - overunder = sim_enc->accum >> 31; + /* get current sign */ + overunder = sim_enc->accum < 0; /* update the accumulator */ sim_enc->accum += sim_enc->addval; - /* test for overflow/underflow (change in bit 31) */ - overunder ^= sim_enc->accum >> 31; + /* test for overflow/underflow (change in sign bit) */ + overunder ^= sim_enc->accum < 0; if ( overunder ) { /* time to update outputs */ /* get direction bit, 1 if negative, 0 if positive */ - dir = sim_enc->addval >> 31; - if ( dir ) { - hal_set_si32(sim_enc->rawcounts, hal_get_si32(sim_enc->rawcounts) - 1); + if ( sim_enc->addval < 0 ) { + hal_set_sint(sim_enc->rawcounts, hal_get_sint(sim_enc->rawcounts) - 1); /* negative rotation, decrement state, detect underflow */ if (--(sim_enc->state) < 0) { /* state underflow, roll over */ @@ -265,19 +264,19 @@ static void make_pulses(void *arg, long period) /* decrement cycle, detect underflow */ if (--(sim_enc->cycle) < 0) { /* cycle underflow, roll over */ - sim_enc->cycle += hal_get_ui32(sim_enc->ppr); + sim_enc->cycle += hal_get_uint(sim_enc->ppr); } } } else { - hal_set_si32(sim_enc->rawcounts, hal_get_si32(sim_enc->rawcounts) + 1); + hal_set_sint(sim_enc->rawcounts, hal_get_sint(sim_enc->rawcounts) + 1); /* positive rotation, increment state, detect overflow */ if (++(sim_enc->state) > 3) { /* state overflow, roll over */ sim_enc->state = 0; /* increment cycle, detect overflow */ - if (++(sim_enc->cycle) >= hal_get_ui32(sim_enc->ppr)) { + if (++(sim_enc->cycle) >= (long)hal_get_uint(sim_enc->ppr)) { /* cycle overflow, roll over */ - sim_enc->cycle -= hal_get_ui32(sim_enc->ppr); + sim_enc->cycle -= hal_get_uint(sim_enc->ppr); } } } @@ -348,7 +347,7 @@ static void update_speed(void *arg, long period) /* convert speed command (user units) to revs/sec */ rev_sec = hal_get_real(sim_enc->speed) * sim_enc->scale_mult; /* convert speed command (revs per sec) to counts/sec */ - freq = rev_sec * (hal_get_ui32(sim_enc->ppr)) * 4.0; + freq = rev_sec * (hal_get_uint(sim_enc->ppr)) * 4.0; /* limit the commanded frequency */ if (freq > maxf) { freq = maxf; @@ -377,7 +376,7 @@ static int export_sim_enc(sim_enc_t * addr, char *prefix) msg = rtapi_get_msg_level(); rtapi_set_msg_level(RTAPI_MSG_WARN); /* export param variable for pulses per rev */ - retval = hal_pin_new_ui32(comp_id, HAL_IO, &(addr->ppr), 100, + retval = hal_pin_new_uint(comp_id, HAL_IO, &(addr->ppr), 100, "%s.ppr", prefix); if (retval != 0) { return retval; @@ -411,7 +410,7 @@ static int export_sim_enc(sim_enc_t * addr, char *prefix) return retval; } /* export pin for rawcounts */ - retval = hal_pin_new_si32(comp_id, HAL_IN, &(addr->rawcounts), 0, + retval = hal_pin_new_sint(comp_id, HAL_IN, &(addr->rawcounts), 0, "%s.rawcounts", prefix); if (retval != 0) { return retval; diff --git a/src/hal/components/switchkinscomp.comp b/src/hal/components/switchkinscomp.comp index 4550d7d1fb4..d4d9b448f3d 100644 --- a/src/hal/components/switchkinscomp.comp +++ b/src/hal/components/switchkinscomp.comp @@ -83,7 +83,7 @@ RTAPI_MP_STRING(coordinates, "Axes-to-joints-ordering"); // need; an entry flagged as the tool arrives in p->tool.tran.z as well. static const kins_param_desc my_params[] = { - { "x-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, + { "x-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, }; enum { P_X_OFFSET }; diff --git a/src/hal/components/userkins.comp b/src/hal/components/userkins.comp index 263aee5a86a..aab96ac010a 100644 --- a/src/hal/components/userkins.comp +++ b/src/hal/components/userkins.comp @@ -88,8 +88,8 @@ author "Dewey Garrett"; // (written from s->out[] after it), or an input that can be poked // (KINS_IO). The example pair below echoes 'in' to 'out'. static const kins_param_desc userkins_params[] = { - { "in", KINS_PARAM_U32, KINS_IN, 0, 0 }, - { "out", KINS_PARAM_U32, KINS_OUT, 0, 0 }, + { "in", KINS_PARAM_UINT, KINS_IN, 0, {.u=0} }, + { "out", KINS_PARAM_UINT, KINS_OUT, 0, {.u=0} }, }; enum { P_IN, P_OUT }; diff --git a/src/hal/components/xyzab_tdr_kins.comp b/src/hal/components/xyzab_tdr_kins.comp index 0444c68e1d1..b8b7bbeeab9 100644 --- a/src/hal/components/xyzab_tdr_kins.comp +++ b/src/hal/components/xyzab_tdr_kins.comp @@ -47,12 +47,12 @@ RTAPI_MP_STRING(coordinates, "Axes-to-joints-ordering"); // the geometry, one pin each; the maths reads it from the block (see // kins_module.h), and the tool length from p->tool.tran.z static const kins_param_desc tdr_params[] = { - { "tool-offset-z", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, - { "x-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "x-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-rot-point", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, + { "tool-offset-z", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, + { "x-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "x-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-rot-point", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, }; enum { P_TOOL, P_XO, P_ZO, P_XR, P_YR, P_ZR }; diff --git a/src/hal/components/xyzacb_trsrn.comp b/src/hal/components/xyzacb_trsrn.comp index 2ee44e38849..b3e131d18c4 100644 --- a/src/hal/components/xyzacb_trsrn.comp +++ b/src/hal/components/xyzacb_trsrn.comp @@ -31,17 +31,17 @@ RTAPI_MP_STRING(coordinates, "Axes-to-joints-ordering"); // pins are what the TOOL kinematics uses in place of the head joints: // the remap writes them. static const kins_param_desc trsrn_params[] = { - { "tool-offset-z", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, - { "y-pivot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-pivot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "x-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-rot-axis", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-rot-axis", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "pre-rot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "nut-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "primary-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "secondary-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, + { "tool-offset-z", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, + { "y-pivot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-pivot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "x-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-rot-axis", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-rot-axis", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "pre-rot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "nut-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "primary-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "secondary-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, }; enum { P_TOOL, P_PIVOT, P_ZPIVOT, P_XO, P_YO, P_ROT_AXIS, P_ZROT_AXIS, P_PRE_ROT, P_NUT, P_PRIM, P_SEC }; diff --git a/src/hal/components/xyzbca_trsrn.comp b/src/hal/components/xyzbca_trsrn.comp index f914794a1f4..56a8e21bc45 100644 --- a/src/hal/components/xyzbca_trsrn.comp +++ b/src/hal/components/xyzbca_trsrn.comp @@ -31,17 +31,17 @@ RTAPI_MP_STRING(coordinates, "Axes-to-joints-ordering"); // pins are what the TOOL kinematics uses in place of the head joints: // the remap writes them. static const kins_param_desc trsrn_params[] = { - { "tool-offset-z", KINS_PARAM_FLOAT, KINS_IN, 1, 0.0 }, - { "x-pivot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-pivot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "x-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "y-offset", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "x-rot-axis", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "z-rot-axis", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "pre-rot", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "nut-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "primary-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, - { "secondary-angle", KINS_PARAM_FLOAT, KINS_IN, 0, 0.0 }, + { "tool-offset-z", KINS_PARAM_REAL, KINS_IN, 1, {.r=0.0} }, + { "x-pivot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-pivot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "x-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "y-offset", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "x-rot-axis", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "z-rot-axis", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "pre-rot", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "nut-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "primary-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, + { "secondary-angle", KINS_PARAM_REAL, KINS_IN, 0, {.r=0.0} }, }; enum { P_TOOL, P_PIVOT, P_ZPIVOT, P_XO, P_YO, P_ROT_AXIS, P_ZROT_AXIS, P_PRE_ROT, P_NUT, P_PRIM, P_SEC }; diff --git a/src/hal/utils/halcompile.g b/src/hal/utils/halcompile.g index 785b48cacaf..382eac4aaca 100644 --- a/src/hal/utils/halcompile.g +++ b/src/hal/utils/halcompile.g @@ -41,6 +41,7 @@ parser Hal: rule Declaration: "pin" PINDIRECTION TYPE HALNAME OptArray OptSAssign OptPersonality OptString ";" {{ pin(HALNAME, TYPE, OptArray, PINDIRECTION, OptString, OptSAssign, OptPersonality) }} | "param" PARAMDIRECTION TYPE HALNAME OptArray OptSAssign OptPersonality OptString ";" {{ param(HALNAME, TYPE, OptArray, PARAMDIRECTION, OptString, OptSAssign, OptPersonality) }} + | "alias" HALNAME OptArray {{ ppname = HALNAME; pparr = OptArray }} HALNAME OptArray ";" {{ alias(ppname, pparr, HALNAME, OptArray) }} | "function" NAME OptFP OptString ";" {{ function(NAME, OptFP, OptString) }} | "variable" NAME STARREDNAME OptSimpleArray OptAssign ";" {{ variable(NAME, STARREDNAME, OptSimpleArray, OptAssign) }} | "option" NAME OptValue ";" {{ option(NAME, OptValue) }} @@ -166,11 +167,14 @@ typemap = { def initialize(): global functions, params, pins, comp_name, names, docs, variables - global modparams, includes, hal_pin_names, hal_funct_names + global modparams, includes + global hal_pin_names, hal_funct_names global funct_derived_claims + global aliases functions = []; params = []; pins = []; options = {}; variables = [] modparams = []; docs = []; includes = []; + aliases = {} comp_name = None names = {} @@ -307,6 +311,22 @@ def param(name, type_, array, dir_, doc, value, personality): names[name] = 'param' params.append((name, type_, array, dir_, value, personality)) +def alias(name, namearr, aliasname, aliasarr): + if namearr != aliasarr: + Error(f"Alias arrays for pin '{namearr}' != '{aliasarr}'") + checkarray(name, namearr) + checkarray(aliasname, aliasarr) + if aliasname in names: + Error(f"Alias name '{aliasname}' already in use") + if name not in names: + Error(f"Pin/param name '{name}' not found, cannot alias") + if name in aliases: + Error(f"Alias for pin/param '{name}' already exists as '{aliases[name][2]}'") + if names[name] not in ('pin', 'param'): + Error(f"Expected '{name}' to be pin or param, but got '{names[name]}'"); + aliases[name] = (name, namearr, aliasname, aliasarr, names[name]) + names[aliasname] = 'alias' # Must register to prevent collision + def function(name, fp, doc): check_name_ok(name) hal_name = to_hal(name) @@ -590,6 +610,35 @@ static int comp_id; print(" if(r != 0) return r;", file=f) print("}", file=f) + if len(aliases) > 0: + print(" {", file=f) + print(" char pinname[HAL_NAME_LEN+1], alsname[HAL_NAME_LEN+1];", file=f) + for k, v in aliases.items(): + name, namearr, aliasname, aliasarr, nametype = v + if isinstance(array, tuple): + lim, cnt = array + print(" if((%s) > (%s)) {" % (cnt, lim), file=f) + print(' rtapi_print_msg(RTAPI_MSG_ERR,' \ + '"Alias %s: Requested size %%d exceeds max size %%d\\n",' + '(int)(%s), (int)(%s));' % (name, cnt, lim), file=f) + print(" return -ENOSPC;", file=f) + print(" }", file=f) + else: + cnt = array + if namearr: + print( " for(j = 0; j < (%s); j++) {" % cnt, file=f) + print(f" rtapi_snprintf(pinname, sizeof(pinname), \"%s.{to_hal(name)}\", prefix, j);", file=f) + print(f" rtapi_snprintf(alsname, sizeof(alsname), \"%s.{to_hal(aliasname)}\", prefix, j);", file=f) + print(f" r = {nametype}(pinname, alsname);", file=f) + print( " if(r != 0) return r;", file=f) + print( " }" % cnt, file=f) + else: + print(f" rtapi_snprintf(pinname, sizeof(pinname), \"%s.{to_hal(name)}\", prefix);", file=f) + print(f" rtapi_snprintf(alsname, sizeof(alsname), \"%s.{to_hal(aliasname)}\", prefix);", file=f) + print(f" r = hal_{nametype}_alias(pinname, alsname);", file=f) + print( " if(r != 0) return r;", file=f) + print(" }", file=f) + for type_, name, array, value in variables: if value is None: continue if array: diff --git a/tests/ilowpass/low-gain/expected b/tests/ilowpass/low-gain/expected index b5ff9099284..54cb93c5bd9 100644 --- a/tests/ilowpass/low-gain/expected +++ b/tests/ilowpass/low-gain/expected @@ -1,3 +1,4 @@ 4 0 -5 +10 diff --git a/tests/ilowpass/low-gain/ilowpasstest.py b/tests/ilowpass/low-gain/ilowpasstest.py new file mode 100755 index 00000000000..932578a0e62 --- /dev/null +++ b/tests/ilowpass/low-gain/ilowpasstest.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +import time +import sys +import hal + +# Wait for thread cycles (threadbeat) +def cycleWait(delta): + oldtime = time.time() + oldval = hal.get_value("thread1.threadbeat") + time.sleep(delta * 0.001) # Initial delay, approx + newval = hal.get_value("thread1.threadbeat") + while newval - oldval < delta: + if time.time() - oldtime >= 10.0: + sys.exit("error: cycleWait(): Timeout") + time.sleep(0.001) + newval = hal.get_value("thread1.threadbeat") + +# +# The filter is an IIR type, which requires quite a few cycles to stabelize, +# depending initial step size to reach the target 'value-0.5', after which the +# filter calculation rounds it up. The number of cycles to reach 'value-0.5' +# increases with the step size because the rounding addition (0.5) is constant +# and does not scale with the step size. +# A step size of 15 (-5 -> +10) needs at least 33 cycles +# A step size of 150 would need at least 55 cycles +# A step size of 1500 would need at least 76 cycles +# (every decade adds about 22 cycles at gain 0.1) +# +for val in [4, 0, -5, 10]: + hal.set_p("ilowpass.0.in", val) + cycleWait(35) + print(hal.get_p("ilowpass.0.out")) diff --git a/tests/ilowpass/low-gain/test.hal b/tests/ilowpass/low-gain/test.hal index 633c28c48d2..6d5c47bc46f 100644 --- a/tests/ilowpass/low-gain/test.hal +++ b/tests/ilowpass/low-gain/test.hal @@ -7,14 +7,4 @@ setp ilowpass.0.gain 0.1 start -setp ilowpass.0.in 4 -loadusr -w sleep 1 -getp ilowpass.0.out - -setp ilowpass.0.in 0 -loadusr -w sleep 1 -getp ilowpass.0.out - -setp ilowpass.0.in -5 -loadusr -w sleep 1 -getp ilowpass.0.out +loadusr -w ./ilowpasstest.py diff --git a/tests/ilowpass/wrap-around/README b/tests/ilowpass/wrap-around/README deleted file mode 100644 index f4f1cfd017a..00000000000 --- a/tests/ilowpass/wrap-around/README +++ /dev/null @@ -1,2 +0,0 @@ -Test that ilowpass's output wraps around. The magic -2147467296 is -2147500000 - (2^32). diff --git a/tests/ilowpass/wrap-around/expected b/tests/ilowpass/wrap-around/expected deleted file mode 100644 index 05b9cd75022..00000000000 --- a/tests/ilowpass/wrap-around/expected +++ /dev/null @@ -1,2 +0,0 @@ -2147400000 --2147467296 diff --git a/tests/ilowpass/wrap-around/test.hal b/tests/ilowpass/wrap-around/test.hal deleted file mode 100644 index 536aaacb394..00000000000 --- a/tests/ilowpass/wrap-around/test.hal +++ /dev/null @@ -1,12 +0,0 @@ -loadrt threads -loadrt ilowpass -addf ilowpass.0 thread1 -setp ilowpass.0.scale 100000 -setp ilowpass.0.in 21474 -setp ilowpass.0.gain 1 -start -loadusr -w sleep .1 -getp ilowpass.0.out -setp ilowpass.0.in 21475 -loadusr -w sleep .1 -getp ilowpass.0.out