#!/usr/bin/env bash set -euo pipefail ROOT="/home/mes006/linuxcncWebWASM" LINUXCNC_ROOT="${ROOT}/linuxcnc" SOURCE_CASE="${LINUXCNC_ROOT}/configs/sim/axis/vismach/3axis-tutorial" PROGRAM_FILE="${LINUXCNC_ROOT}/nc_files/3dtest.ngc" switch_to_english_input() { printf 'Switching input method to English before LinuxCNC startup...\n' if command -v ibus >/dev/null 2>&1; then if ibus engine xkb:us::eng >/dev/null 2>&1; then printf ' IBus engine: xkb:us::eng\n' else printf ' IBus English engine switch failed\n' fi fi if command -v gsettings >/dev/null 2>&1; then gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('ibus', 'libpinyin')]" >/dev/null 2>&1 || true gsettings set org.gnome.desktop.input-sources mru-sources "[('xkb', 'us'), ('ibus', 'libpinyin')]" >/dev/null 2>&1 || true fi if command -v setxkbmap >/dev/null 2>&1; then setxkbmap us >/dev/null 2>&1 || true fi } cleanup_linuxcnc() { local phase="${1:-cleanup}" printf 'Cleaning LinuxCNC simulation %s...\n' "${phase}" local command for command in "axis-remote --quit" "halcmd stop" "halcmd unload all" "/usr/lib/linuxcnc/realtime stop"; do if timeout 3s bash -lc "cd \"${LINUXCNC_ROOT}\" && ${command}" >/dev/null 2>&1; then printf ' cleanup passed: %s\n' "${command}" else printf ' cleanup skipped/failed: %s\n' "${command}" fi done local self_pid="$$" parent_pid="${PPID}" pid process_args while read -r pid process_args; do [[ -n "${pid:-}" ]] || continue [[ "${pid}" == "${self_pid}" || "${pid}" == "${parent_pid}" ]] && continue case "${process_args}" in *linuxcncsvr*|*milltask*|*motion-logger*|*rtapi_app*|*halui*|*iocontrol*|*/usr/bin/axis*|*/usr/bin/linuxcnc*|*/linuxcnc-*axis.*/*) printf ' stopping process %s: %s\n' "${pid}" "${process_args}" kill -TERM "${pid}" 2>/dev/null || true ;; esac done < <(ps -eo pid=,args=) local deadline=$((SECONDS + 3)) while (( SECONDS < deadline )); do if ! ps -eo args= | rg -q 'linuxcncsvr|milltask|motion-logger|rtapi_app|halui|iocontrol|/usr/bin/axis|/usr/bin/linuxcnc'; then break fi sleep 0.1 done while read -r pid process_args; do [[ -n "${pid:-}" ]] || continue [[ "${pid}" == "${self_pid}" || "${pid}" == "${parent_pid}" ]] && continue case "${process_args}" in *linuxcncsvr*|*milltask*|*motion-logger*|*rtapi_app*|*halui*|*iocontrol*|*/usr/bin/axis*|*/usr/bin/linuxcnc*|*/linuxcnc-*axis.*/*) kill -KILL "${pid}" 2>/dev/null || true ;; esac done < <(ps -eo pid=,args=) if [[ -e /tmp/linuxcnc.lock ]] && ! ps -eo args= | rg -q 'linuxcncsvr|milltask|motion-logger|rtapi_app|halui|iocontrol|/usr/bin/axis|/usr/bin/linuxcnc'; then rm -f -- /tmp/linuxcnc.lock printf ' removed stale lock: /tmp/linuxcnc.lock\n' fi } cleanup_linuxcnc "before startup" switch_to_english_input export GTK_IM_MODULE=ibus export QT_IM_MODULE=ibus export XMODIFIERS=@im=ibus for required in "${SOURCE_CASE}/3axis-tutorial.ini" "${SOURCE_CASE}/3axis-tutorial.hal" \ "${SOURCE_CASE}/3axis-tutorial" "${SOURCE_CASE}/tool.tbl" "${PROGRAM_FILE}"; do if [[ ! -f "${required}" ]]; then printf 'Required LinuxCNC file not found: %s\n' "${required}" >&2 exit 1 fi done RUNTIME_DIR="$(mktemp -d "${TMPDIR:-/tmp}/linuxcnc-3dtest-axis.XXXXXX")" cleanup_done=0 cleanup() { if (( cleanup_done == 1 )); then return fi cleanup_done=1 cleanup_linuxcnc "after exit" rm -rf -- "${RUNTIME_DIR}" } trap cleanup EXIT INT TERM for name in 3axis-tutorial.ini 3axis-tutorial.hal 3axis-tutorial tool.tbl; do cp -- "${SOURCE_CASE}/${name}" "${RUNTIME_DIR}/${name}" done chmod +x "${RUNTIME_DIR}/3axis-tutorial" # The tutorial model uses millimetres, while 3dtest.ngc reaches Z=1.75in. # Keep this limit change local to the temporary runtime copy. sed -i \ -e "s|^PROGRAM_PREFIX.*|PROGRAM_PREFIX = ${LINUXCNC_ROOT}/nc_files|" \ -e "s|^OPEN_FILE.*|OPEN_FILE = ${PROGRAM_FILE}|" \ -e '/^MAX_FEED_OVERRIDE/a HOMING_PROMPT = 1' \ -e '/^\[AXIS_Z\]/,/^\[/ s/^MAX_LIMIT[[:space:]]*=.*/MAX_LIMIT = 100.0/' \ -e '/^\[JOINT_2\]/,/^\[/ s/^MAX_LIMIT[[:space:]]*=.*/MAX_LIMIT = 100.0/' \ "${RUNTIME_DIR}/3axis-tutorial.ini" cd "${LINUXCNC_ROOT}" update_ini -f "${RUNTIME_DIR}/3axis-tutorial.ini" >/dev/null export AXIS_OPEN_FILE="${PROGRAM_FILE}" printf 'Starting LinuxCNC AXIS simulation. Load: %s\n' "${PROGRAM_FILE}" printf 'Manual sequence: reset E-stop, power on, accept the homing prompt, then press Run.\n' printf 'If no prompt appears: select X, Y, and Z in turn and click Home Axis for each.\n' /usr/bin/linuxcnc -r "${RUNTIME_DIR}/3axis-tutorial.ini"