889 lines
36 KiB
JavaScript
889 lines
36 KiB
JavaScript
export const gmoccapyHalModel = {
|
|
apiName: "web-rtcp-5axis-gmoccapy-hal-model",
|
|
profileId: "gmoccapy-xyzab",
|
|
nativeConfigPath: "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini",
|
|
halFiles: [
|
|
{
|
|
path: "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal",
|
|
stage: "HALFILE",
|
|
role: "trivkins and motmod simulation loopback",
|
|
semanticBoundary: "native_hal_reference",
|
|
},
|
|
{
|
|
path: "linuxcnc/configs/sim/gmoccapy/spindle_sim.hal",
|
|
stage: "HALFILE",
|
|
role: "spindle speed encoder and at-speed simulation",
|
|
semanticBoundary: "native_hal_reference",
|
|
},
|
|
{
|
|
path: "linuxcnc/configs/sim/gmoccapy/simulated_home.hal",
|
|
stage: "HALFILE",
|
|
role: "simulated X/Y/Z home switches",
|
|
semanticBoundary: "native_hal_reference",
|
|
},
|
|
{
|
|
path: "linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal",
|
|
stage: "POSTGUI_HALFILE",
|
|
role: "connections that require gmoccapy.* pins",
|
|
requiresHalcompReady: true,
|
|
semanticBoundary: "native_postgui_hal_reference",
|
|
},
|
|
],
|
|
nativePins: [
|
|
{
|
|
group: "hard-buttons",
|
|
pins: [
|
|
"gmoccapy.h-button.button-0",
|
|
"gmoccapy.h-button.button-1",
|
|
"gmoccapy.h-button.button-2",
|
|
"gmoccapy.h-button.button-3",
|
|
"gmoccapy.h-button.button-4",
|
|
"gmoccapy.h-button.button-5",
|
|
"gmoccapy.h-button.button-6",
|
|
"gmoccapy.h-button.button-7",
|
|
"gmoccapy.h-button.button-8",
|
|
"gmoccapy.h-button.button-9",
|
|
"gmoccapy.v-button.button-0",
|
|
"gmoccapy.v-button.button-1",
|
|
"gmoccapy.v-button.button-2",
|
|
"gmoccapy.v-button.button-3",
|
|
"gmoccapy.v-button.button-4",
|
|
"gmoccapy.v-button.button-5",
|
|
"gmoccapy.v-button.button-6",
|
|
],
|
|
webSource: "current visible Web button set",
|
|
semanticBoundary: "native_hardware_button_pin_reference",
|
|
},
|
|
{
|
|
group: "jog",
|
|
pins: [
|
|
"gmoccapy.jog.axis.jog-x-plus",
|
|
"gmoccapy.jog.axis.jog-x-minus",
|
|
"gmoccapy.jog.axis.jog-y-plus",
|
|
"gmoccapy.jog.axis.jog-y-minus",
|
|
"gmoccapy.jog.axis.jog-z-plus",
|
|
"gmoccapy.jog.axis.jog-z-minus",
|
|
"gmoccapy.jog.axis.jog-a-plus",
|
|
"gmoccapy.jog.axis.jog-a-minus",
|
|
"gmoccapy.jog.axis.jog-b-plus",
|
|
"gmoccapy.jog.axis.jog-b-minus",
|
|
"gmoccapy.jog.jog-inc-0",
|
|
"gmoccapy.jog.jog-inc-1",
|
|
"gmoccapy.jog.jog-inc-2",
|
|
"gmoccapy.jog.jog-inc-3",
|
|
"gmoccapy.jog.jog-inc-4",
|
|
"gmoccapy.jog.jog-inc-5",
|
|
"gmoccapy.jog.jog-increment",
|
|
"gmoccapy.jog.turtle-jog",
|
|
],
|
|
webSource: "JOG dispatch and machine.jogIncrement",
|
|
semanticBoundary: "native_jog_pin_reference_web_task_policy_gate",
|
|
},
|
|
{
|
|
group: "override",
|
|
pins: [
|
|
"gmoccapy.feed.feed-override.counts",
|
|
"gmoccapy.feed.feed-override.count-enable",
|
|
"gmoccapy.feed.feed-override.analog-enable",
|
|
"gmoccapy.feed.feed-override.direct-value",
|
|
"gmoccapy.feed.reset-feed-override",
|
|
"gmoccapy.spindle.spindle-override.counts",
|
|
"gmoccapy.spindle.spindle-override.count-enable",
|
|
"gmoccapy.spindle.spindle-override.analog-enable",
|
|
"gmoccapy.spindle.spindle-override.direct-value",
|
|
"gmoccapy.spindle.reset-spindle-override",
|
|
"gmoccapy.jog.jog-velocity.counts",
|
|
"gmoccapy.jog.jog-velocity.count-enable",
|
|
"gmoccapy.jog.jog-velocity.analog-enable",
|
|
"gmoccapy.jog.jog-velocity.direct-value",
|
|
"gmoccapy.rapid.rapid-override.counts",
|
|
"gmoccapy.rapid.rapid-override.count-enable",
|
|
"gmoccapy.rapid.rapid-override.analog-enable",
|
|
"gmoccapy.rapid.rapid-override.direct-value",
|
|
"gmoccapy.rapid.reset-rapid-override",
|
|
],
|
|
webSource: "feed/spindle override state",
|
|
semanticBoundary: "native_override_pin_reference_web_state_mapping",
|
|
},
|
|
{
|
|
group: "operator-inputs",
|
|
pins: [
|
|
"gmoccapy.ignore-limits",
|
|
"gmoccapy.optional-stop",
|
|
"gmoccapy.blockdelete",
|
|
],
|
|
webSource: "gmoccapyGui ignoreLimits, optionalBlocks, optionalStop",
|
|
semanticBoundary: "native_ignore_limits_optional_stop_blockdelete_pin_reference_web_state_mapping",
|
|
},
|
|
{
|
|
group: "settings",
|
|
pins: [
|
|
"gmoccapy.unlock-settings",
|
|
],
|
|
webSource: "gmoccapyGui settingsUnlockPin and setupSensitive",
|
|
semanticBoundary: "native_settings_unlock_pin_reference_web_diagnostic_state",
|
|
},
|
|
{
|
|
group: "tool",
|
|
pins: [
|
|
"gmoccapy.tooloffset-x",
|
|
"gmoccapy.tooloffset-z",
|
|
"gmoccapy.tool-diameter",
|
|
"gmoccapy.probeheight",
|
|
"gmoccapy.blockheight",
|
|
"gmoccapy.toolmeasurement",
|
|
"gmoccapy.searchvel",
|
|
"gmoccapy.probevel",
|
|
"gmoccapy.toolchange-change",
|
|
"gmoccapy.toolchange-changed",
|
|
"gmoccapy.toolchange-number",
|
|
"gmoccapy.toolchange-confirm",
|
|
],
|
|
webSource: "toolPreview, disconnected manual tool-change diagnostics, and disabled XYZAB tool measurement outputs",
|
|
semanticBoundary: "native_tool_pin_reference_simulated_tool_loop",
|
|
},
|
|
{
|
|
group: "program",
|
|
pins: [
|
|
"gmoccapy.program.length",
|
|
"gmoccapy.program.current-line",
|
|
"gmoccapy.program.progress",
|
|
],
|
|
webSource: "programLines, activeLine, programRuntimeFeedback",
|
|
semanticBoundary: "native_program_pin_reference_web_execution_status",
|
|
},
|
|
{
|
|
group: "message",
|
|
pins: [
|
|
"gmoccapy.error",
|
|
"gmoccapy.delete-message",
|
|
"gmoccapy.warning-confirm",
|
|
],
|
|
webSource: "operatorMessage and browser diagnostics",
|
|
semanticBoundary: "native_message_pin_reference_web_operator_message",
|
|
},
|
|
{
|
|
group: "spindle-postgui",
|
|
pins: [
|
|
"gmoccapy.spindle_feedback_bar",
|
|
"gmoccapy.spindle_at_speed_led",
|
|
],
|
|
webSource: "spindle rpm/status panel",
|
|
semanticBoundary: "postgui_spindle_feedback_reference",
|
|
},
|
|
],
|
|
coreNets: [
|
|
{
|
|
signal: "Xpos",
|
|
source: "joint.0.motor-pos-cmd",
|
|
target: "joint.0.motor-pos-fb",
|
|
role: "X command-to-feedback simulation loop",
|
|
},
|
|
{
|
|
signal: "Ypos",
|
|
source: "joint.1.motor-pos-cmd",
|
|
target: "joint.1.motor-pos-fb",
|
|
role: "Y command-to-feedback simulation loop",
|
|
},
|
|
{
|
|
signal: "Zpos",
|
|
source: "joint.2.motor-pos-cmd",
|
|
target: "joint.2.motor-pos-fb",
|
|
role: "Z command-to-feedback simulation loop",
|
|
},
|
|
{
|
|
signal: "Apos",
|
|
source: "joint.3.motor-pos-cmd",
|
|
target: "joint.3.motor-pos-fb",
|
|
role: "A command-to-feedback simulation loop",
|
|
},
|
|
{
|
|
signal: "Bpos",
|
|
source: "joint.4.motor-pos-cmd",
|
|
target: "joint.4.motor-pos-fb",
|
|
role: "B command-to-feedback simulation loop",
|
|
},
|
|
{
|
|
signal: "estop-loop",
|
|
source: "iocontrol.0.user-enable-out",
|
|
target: "iocontrol.0.emc-enable-in",
|
|
role: "simulated estop enable loop",
|
|
},
|
|
{
|
|
signal: "tool-prep-loop",
|
|
source: "iocontrol.0.tool-prepare",
|
|
target: "iocontrol.0.tool-prepared",
|
|
role: "simulated tool prepare completion",
|
|
},
|
|
{
|
|
signal: "tool-change-loop",
|
|
source: "iocontrol.0.tool-change",
|
|
target: "iocontrol.0.tool-changed",
|
|
role: "simulated automatic tool-change completion",
|
|
},
|
|
{
|
|
signal: "flood",
|
|
source: "iocontrol.0.coolant-flood",
|
|
target: "gmoccapy coolant display via status",
|
|
role: "coolant flood state",
|
|
},
|
|
{
|
|
signal: "mist",
|
|
source: "iocontrol.0.coolant-mist",
|
|
target: "gmoccapy coolant display via status",
|
|
role: "coolant mist state",
|
|
},
|
|
],
|
|
spindleNets: [
|
|
{
|
|
signal: "spindle-speed-cmd",
|
|
source: "spindle.0.speed-out",
|
|
target: "limit_speed.in",
|
|
role: "commanded spindle speed",
|
|
},
|
|
{
|
|
signal: "spindle-speed-limited",
|
|
source: "limit_speed.out",
|
|
target: "sim_encoder_0.speed",
|
|
role: "simulated spindle inertia",
|
|
},
|
|
{
|
|
signal: "spindle-pos",
|
|
source: "encoder_0.position",
|
|
target: "spindle.0.revs",
|
|
role: "encoder feedback position",
|
|
},
|
|
{
|
|
signal: "spindle-at-speed",
|
|
source: "near_speed.out",
|
|
target: "spindle.0.at-speed",
|
|
role: "at-speed comparator result",
|
|
},
|
|
],
|
|
postguiNets: [
|
|
{
|
|
signal: "spindle-abs",
|
|
source: "abs_spindle_feedback.out",
|
|
target: "gmoccapy.spindle_feedback_bar",
|
|
requiresHalcompReady: true,
|
|
role: "spindle feedback bar",
|
|
},
|
|
{
|
|
signal: "spindle-at-speed",
|
|
source: "spindle.0.at-speed",
|
|
target: "gmoccapy.spindle_at_speed_led",
|
|
requiresHalcompReady: true,
|
|
role: "spindle at-speed LED",
|
|
},
|
|
{
|
|
signal: "tooloffset-x",
|
|
source: "motion.tooloffset.x",
|
|
target: "gmoccapy.tooloffset-x",
|
|
requiresHalcompReady: true,
|
|
role: "tool X offset display",
|
|
},
|
|
{
|
|
signal: "tooloffset-z",
|
|
source: "motion.tooloffset.z",
|
|
target: "gmoccapy.tooloffset-z",
|
|
requiresHalcompReady: true,
|
|
role: "tool Z offset display",
|
|
},
|
|
{
|
|
signal: "tool-change-loop",
|
|
source: "iocontrol.0.tool-change",
|
|
target: "iocontrol.0.tool-changed",
|
|
requiresHalcompReady: true,
|
|
simulationLoop: true,
|
|
role: "automatic simulated tool-change completion",
|
|
},
|
|
],
|
|
hardwareButtons: {
|
|
source: {
|
|
path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py",
|
|
methods: ["_button_pin_changed", "_get_child_button", "_make_hal_pins"],
|
|
},
|
|
behavior: {
|
|
edge: "rising-edge-only",
|
|
hButtonContainer: "current ntb_button page visible children",
|
|
vButtonContainer: "vbtb_main visible children",
|
|
insensitiveTarget: "ignored",
|
|
hiddenLabelsSkipped: true,
|
|
semanticBoundary: "native_gmoccapy_hardware_button_pin_to_visible_sensitive_button",
|
|
},
|
|
verticalMain: [
|
|
{
|
|
index: 0,
|
|
pin: "gmoccapy.v-button.button-0",
|
|
nativeWidget: "tbtn_estop",
|
|
webAction: "ESTOP",
|
|
webDispatch: { type: "ESTOP" },
|
|
webSelector: '[data-action="estop"]',
|
|
gate: "always clickable safety action",
|
|
},
|
|
{
|
|
index: 1,
|
|
pin: "gmoccapy.v-button.button-1",
|
|
nativeWidget: "tbtn_on",
|
|
webAction: "TOGGLE_POWER",
|
|
webDispatch: { type: "TOGGLE_POWER" },
|
|
webSelector: '[data-action="power"]',
|
|
gate: "blocked while STATE_ESTOP",
|
|
},
|
|
{
|
|
index: 2,
|
|
pin: "gmoccapy.v-button.button-2",
|
|
nativeWidget: "rbt_manual",
|
|
webAction: "SET_MODE manual",
|
|
webDispatch: { type: "SET_MODE", mode: "manual" },
|
|
webSelector: '[data-action="mode-manual"]',
|
|
gate: "machine on and AUTO interpreter idle",
|
|
},
|
|
{
|
|
index: 3,
|
|
pin: "gmoccapy.v-button.button-3",
|
|
nativeWidget: "rbt_mdi",
|
|
webAction: "SET_MODE mdi",
|
|
webDispatch: { type: "SET_MODE", mode: "mdi" },
|
|
webSelector: '[data-action="mode-mdi"]',
|
|
gate: "machine on and homed when NO_FORCE_HOMING=0",
|
|
},
|
|
{
|
|
index: 4,
|
|
pin: "gmoccapy.v-button.button-4",
|
|
nativeWidget: "rbt_auto",
|
|
webAction: "SET_MODE auto",
|
|
webDispatch: { type: "SET_MODE", mode: "auto" },
|
|
webSelector: '[data-action="mode-auto"]',
|
|
gate: "machine on and homed when NO_FORCE_HOMING=0",
|
|
},
|
|
{
|
|
index: 5,
|
|
pin: "gmoccapy.v-button.button-5",
|
|
nativeWidget: "tbtn_user_tabs",
|
|
webAction: "GMOCAPY_NATIVE_PAGE user-tabs",
|
|
webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "user-tabs", nativeWidget: "tbtn_user_tabs" },
|
|
webSelector: null,
|
|
gate: "native user tabs page is diagnostic-only in the Web shell",
|
|
},
|
|
{
|
|
index: 6,
|
|
pin: "gmoccapy.v-button.button-6",
|
|
nativeWidget: "tbtn_setup",
|
|
webAction: "GMOCAPY_NATIVE_PAGE setup",
|
|
webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "setup", nativeWidget: "tbtn_setup" },
|
|
webSelector: null,
|
|
gate: "native setup page is diagnostic-only in the Web shell",
|
|
},
|
|
],
|
|
bottomMain: [
|
|
{
|
|
index: 0,
|
|
pin: "gmoccapy.h-button.button-0",
|
|
nativeWidget: "btn_homing",
|
|
webAction: "HOME",
|
|
webDispatch: { type: "HOME" },
|
|
webSelector: '[data-action="HOME"]',
|
|
gate: "machine on and manual mode",
|
|
},
|
|
{
|
|
index: 1,
|
|
pin: "gmoccapy.h-button.button-1",
|
|
nativeWidget: "btn_touch",
|
|
webAction: "GMOCAPY_NATIVE_PAGE touch-off",
|
|
webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "touch-off", nativeWidget: "btn_touch" },
|
|
webSelector: null,
|
|
gate: "touch-off page not implemented in Web shell",
|
|
},
|
|
{
|
|
index: 3,
|
|
pin: "gmoccapy.h-button.button-3",
|
|
nativeWidget: "btn_tool",
|
|
webAction: "GMOCAPY_NATIVE_PAGE tool-editor",
|
|
webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "tool-editor", nativeWidget: "btn_tool" },
|
|
webSelector: null,
|
|
gate: "tool editor page not implemented in Web shell",
|
|
},
|
|
{
|
|
index: 6,
|
|
pin: "gmoccapy.h-button.button-6",
|
|
nativeWidget: "tbtn_switch_mode",
|
|
webAction: "GMOCAPY_NATIVE_PAGE switchkins-mode",
|
|
webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "switchkins-mode", nativeWidget: "tbtn_switch_mode" },
|
|
webSelector: null,
|
|
gate: "native joint/world switch page position is diagnostic-only in the Web shell",
|
|
},
|
|
],
|
|
},
|
|
halPinActions: {
|
|
source: {
|
|
path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py",
|
|
methods: [
|
|
"_ignore_limits",
|
|
"_optional_blocks",
|
|
"_blockdelete",
|
|
"_on_pin_jog_changed",
|
|
"_on_pin_incr_changed",
|
|
"_on_counts_changed",
|
|
"_on_analog_enable_changed",
|
|
"_on_analog_value_changed",
|
|
"_reset_override",
|
|
"_del_message_changed",
|
|
"_on_unlock_settings_changed",
|
|
"_check_toolmeasurement",
|
|
"on_chk_use_tool_measurement_toggled",
|
|
"on_btn_block_height_clicked",
|
|
"_on_blockheight_value_changed",
|
|
"_init_user_messages",
|
|
"_show_user_message",
|
|
],
|
|
prefPath: "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.pref",
|
|
},
|
|
jogPins: {
|
|
axes: [
|
|
{ axis: "x", plus: "gmoccapy.jog.axis.jog-x-plus", minus: "gmoccapy.jog.axis.jog-x-minus" },
|
|
{ axis: "y", plus: "gmoccapy.jog.axis.jog-y-plus", minus: "gmoccapy.jog.axis.jog-y-minus" },
|
|
{ axis: "z", plus: "gmoccapy.jog.axis.jog-z-plus", minus: "gmoccapy.jog.axis.jog-z-minus" },
|
|
{ axis: "a", plus: "gmoccapy.jog.axis.jog-a-plus", minus: "gmoccapy.jog.axis.jog-a-minus" },
|
|
{ axis: "b", plus: "gmoccapy.jog.axis.jog-b-plus", minus: "gmoccapy.jog.axis.jog-b-minus" },
|
|
],
|
|
increments: [
|
|
{ index: 0, pin: "gmoccapy.jog.jog-inc-0", label: "Continuous", distance: 0 },
|
|
{ index: 1, pin: "gmoccapy.jog.jog-inc-1", label: "1.000 mm", distance: 1 },
|
|
{ index: 2, pin: "gmoccapy.jog.jog-inc-2", label: "0.100 mm", distance: 0.1 },
|
|
{ index: 3, pin: "gmoccapy.jog.jog-inc-3", label: "0.010 mm", distance: 0.01 },
|
|
{ index: 4, pin: "gmoccapy.jog.jog-inc-4", label: "0.001 mm", distance: 0.001 },
|
|
{ index: 5, pin: "gmoccapy.jog.jog-inc-5", label: "1.2345 in", distance: 31.3563 },
|
|
],
|
|
outputPin: "gmoccapy.jog.jog-increment",
|
|
turtlePin: "gmoccapy.jog.turtle-jog",
|
|
nativeCallbacks: {
|
|
axis: "_on_pin_jog_changed -> _on_btn_jog_pressed/_on_btn_jog_released",
|
|
increment: "_on_pin_incr_changed -> _jog_increment_changed",
|
|
turtle: "_on_pin_turtle_jog -> tbtn_turtle_jog.set_active",
|
|
},
|
|
},
|
|
operatorPins: [
|
|
{
|
|
pin: "gmoccapy.ignore-limits",
|
|
nativeCallback: "_ignore_limits -> chk_ignore_limits.set_active",
|
|
nativeCommand: "on_chk_ignore_limits_toggled -> command.override_limits() when active",
|
|
webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.ignore-limits" },
|
|
webState: "gmoccapyGui.ignoreLimits",
|
|
},
|
|
{
|
|
pin: "gmoccapy.optional-stop",
|
|
nativeCallback: "_optional_blocks",
|
|
nativeCommand: "tbtn_optional_blocks -> command.set_block_delete(state)",
|
|
webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.optional-stop" },
|
|
webState: "gmoccapyGui.optionalBlocks",
|
|
},
|
|
{
|
|
pin: "gmoccapy.blockdelete",
|
|
nativeCallback: "_blockdelete",
|
|
nativeCommand: "command.set_optional_stop(state)",
|
|
webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.blockdelete" },
|
|
webState: "gmoccapyGui.optionalStop",
|
|
},
|
|
],
|
|
settingsPins: [
|
|
{
|
|
pin: "gmoccapy.unlock-settings",
|
|
nativeCallback: "_on_unlock_settings_changed",
|
|
nativeCommand: "rbt_hal_unlock active gates tbtn_setup sensitivity from pin level",
|
|
prefDefault: "unlock_way=use",
|
|
webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.unlock-settings" },
|
|
webState: "gmoccapyGui.settingsUnlockPin",
|
|
},
|
|
],
|
|
overridePins: [
|
|
{
|
|
target: "feed",
|
|
counts: "gmoccapy.feed.feed-override.counts",
|
|
countEnable: "gmoccapy.feed.feed-override.count-enable",
|
|
analogEnable: "gmoccapy.feed.feed-override.analog-enable",
|
|
directValue: "gmoccapy.feed.feed-override.direct-value",
|
|
reset: "gmoccapy.feed.reset-feed-override",
|
|
nativeWidget: "spc_feed",
|
|
scalePref: "scale_feed_override=1",
|
|
webState: "feed.feedOverride",
|
|
},
|
|
{
|
|
target: "rapid",
|
|
counts: "gmoccapy.rapid.rapid-override.counts",
|
|
countEnable: "gmoccapy.rapid.rapid-override.count-enable",
|
|
analogEnable: "gmoccapy.rapid.rapid-override.analog-enable",
|
|
directValue: "gmoccapy.rapid.rapid-override.direct-value",
|
|
reset: "gmoccapy.rapid.reset-rapid-override",
|
|
nativeWidget: "spc_rapid",
|
|
scalePref: "scale_rapid_override=1",
|
|
webState: "feed.rapidOverride",
|
|
},
|
|
{
|
|
target: "spindle",
|
|
counts: "gmoccapy.spindle.spindle-override.counts",
|
|
countEnable: "gmoccapy.spindle.spindle-override.count-enable",
|
|
analogEnable: "gmoccapy.spindle.spindle-override.analog-enable",
|
|
directValue: "gmoccapy.spindle.spindle-override.direct-value",
|
|
reset: "gmoccapy.spindle.reset-spindle-override",
|
|
nativeWidget: "spc_spindle",
|
|
scalePref: "scale_spindle_override=1",
|
|
webState: "spindle.override",
|
|
},
|
|
{
|
|
target: "jogVelocity",
|
|
counts: "gmoccapy.jog.jog-velocity.counts",
|
|
countEnable: "gmoccapy.jog.jog-velocity.count-enable",
|
|
analogEnable: "gmoccapy.jog.jog-velocity.analog-enable",
|
|
directValue: "gmoccapy.jog.jog-velocity.direct-value",
|
|
reset: null,
|
|
nativeWidget: "spc_lin_jog_vel",
|
|
scalePref: "scale_jog_vel=140.4",
|
|
webState: "gmoccapyGui.jogVelocity",
|
|
},
|
|
],
|
|
messagePins: [
|
|
{
|
|
pin: "gmoccapy.delete-message",
|
|
nativeCallback: "_del_message_changed",
|
|
nativeCommand: "pin true deletes first alert message when gmoccapy.error is set, otherwise del_last()",
|
|
webState: "operatorMessage",
|
|
},
|
|
{
|
|
pin: "gmoccapy.warning-confirm",
|
|
nativeCallback: "dialogs.warning_dialog periodic confirm_pin poll",
|
|
nativeCommand: "pin true responds OK to active warning dialog",
|
|
webState: "gmoccapyGui.warningConfirm",
|
|
},
|
|
{
|
|
pin: "gmoccapy.error",
|
|
nativeCallback: "_show_error/_on_message_deleted",
|
|
nativeCommand: "HAL OUT bit tracks alert messages",
|
|
webState: "gmoccapyGui.error",
|
|
},
|
|
],
|
|
toolMeasurementPins: {
|
|
toolsensorConfigured: false,
|
|
useToolMeasurementPref: false,
|
|
prefDefaults: {
|
|
useToolMeasurement: "use_toolmeasurement=False",
|
|
blockHeight: "blockheight=0.0",
|
|
},
|
|
disabledReason: "gmoccapy_XYZAB.ini has no [TOOLSENSOR] data, so _check_toolmeasurement disables the controls",
|
|
pins: [
|
|
{
|
|
pin: "gmoccapy.probeheight",
|
|
direction: "HAL_OUT",
|
|
nativeCallback: "on_spbtn_probe_height_value_changed / on_chk_use_tool_measurement_toggled / on_btn_block_height_clicked",
|
|
webState: "gmoccapyGui.probeHeight",
|
|
},
|
|
{
|
|
pin: "gmoccapy.blockheight",
|
|
direction: "HAL_OUT",
|
|
nativeCallback: "on_btn_block_height_clicked / _on_blockheight_value_changed",
|
|
webState: "gmoccapyGui.blockHeight",
|
|
},
|
|
{
|
|
pin: "gmoccapy.toolmeasurement",
|
|
direction: "HAL_OUT",
|
|
nativeCallback: "on_chk_use_tool_measurement_toggled",
|
|
webState: "gmoccapyGui.toolMeasurement",
|
|
},
|
|
{
|
|
pin: "gmoccapy.searchvel",
|
|
direction: "HAL_OUT",
|
|
nativeCallback: "on_spbtn_search_vel_value_changed / on_chk_use_tool_measurement_toggled",
|
|
webState: "gmoccapyGui.searchVelocity",
|
|
},
|
|
{
|
|
pin: "gmoccapy.probevel",
|
|
direction: "HAL_OUT",
|
|
nativeCallback: "on_spbtn_probe_vel_value_changed / on_chk_use_tool_measurement_toggled",
|
|
webState: "gmoccapyGui.probeVelocity",
|
|
},
|
|
],
|
|
},
|
|
userMessages: {
|
|
configured: false,
|
|
configuredMessageCount: 0,
|
|
pins: [],
|
|
source: "get_ini_info.get_user_messages()",
|
|
disabledReason: "gmoccapy_XYZAB.ini has no MESSAGE_* entries, so _init_user_messages() returns without creating messages.* pins",
|
|
dynamicPinPatterns: [
|
|
"gmoccapy.messages.<pinname>",
|
|
"gmoccapy.messages.<pinname>-waiting",
|
|
"gmoccapy.messages.<pinname>-response",
|
|
],
|
|
supportedTypes: ["status", "okdialog", "yesnodialog"],
|
|
},
|
|
behavior: {
|
|
optionalStopPinCrossesToBlockDelete: true,
|
|
blockdeletePinCrossesToOptionalStop: true,
|
|
unlockSettingsLevelDriven: true,
|
|
jogAxisPinsPressRelease: true,
|
|
jogPinsUseTaskPolicyGate: true,
|
|
jogIncrementPinsRisingEdgeOnly: true,
|
|
jogIncrementZeroIsContinuous: true,
|
|
turtleJogLevelDriven: true,
|
|
countInputRequiresEnable: true,
|
|
directValueRequiresAnalogEnable: true,
|
|
resetPinsRisingEdgeOnly: true,
|
|
deleteMessageRisingEdgeOnly: true,
|
|
warningConfirmLevelPolled: true,
|
|
toolMeasurementPinsAreHalOut: true,
|
|
toolMeasurementDisabledWithoutToolsensor: true,
|
|
userMessagesDynamicIniOnly: true,
|
|
directValueRange: "0..1",
|
|
semanticBoundary: "native_gmoccapy_hal_pin_callbacks_to_web_store_actions",
|
|
},
|
|
},
|
|
nativePages: {
|
|
source: {
|
|
path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py",
|
|
gladePath: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.glade",
|
|
methods: [
|
|
"_init_IconFileSelection",
|
|
"_init_file_to_load",
|
|
"on_btn_load_clicked",
|
|
"on_IconFileSelection1_selected",
|
|
"on_hal_status_file_loaded",
|
|
"_make_macro_button",
|
|
"_on_btn_macro_pressed",
|
|
"_init_tooleditor",
|
|
"_show_tooledit_tab",
|
|
"on_btn_tool_clicked",
|
|
"on_btn_selected_tool_clicked",
|
|
"on_btn_select_tool_by_no_clicked",
|
|
"on_tbtn_setup_toggled",
|
|
"on_tbtn_user_tabs_toggled",
|
|
"on_btn_touch_clicked",
|
|
],
|
|
},
|
|
filePage: {
|
|
pageId: "file-load",
|
|
nativeNotebookPage: "_BB_LOAD_FILE / ntb_preview page 3",
|
|
nativeWidget: "IconFileSelection1",
|
|
programPrefix: "../../nc_files/",
|
|
defaultOpenPreference: "open_file",
|
|
fileExtensions: [
|
|
"*.ngc",
|
|
"*.png",
|
|
"*.gif",
|
|
"*.jpg",
|
|
"*.py",
|
|
],
|
|
nativeCallbacks: [
|
|
"on_btn_load_clicked -> _show_iconview_tab(True)",
|
|
"on_IconFileSelection1_selected -> hal_action_open.load_file(path)",
|
|
"on_hal_status_file_loaded -> gmoccapy.program.length",
|
|
"on_hal_status_line_changed -> gmoccapy.program.current-line/progress",
|
|
],
|
|
webSurface: "OPEN_FILE input, staged LinuxCNC G-code source selector and program preview",
|
|
webAction: "GMOCAPY_PAGE_ACTION file-load diagnostics",
|
|
implementation: "partial",
|
|
boundary: "native_GtkIconFileSelection_not_embedded_in_browser",
|
|
},
|
|
macroPage: {
|
|
pageId: "mdi-macros",
|
|
nativeContainer: "hbtb_MDI",
|
|
iniSection: "[MACROS]",
|
|
macroLimit: 14,
|
|
macros: [
|
|
{ name: "i_am_lost", args: [], file: "macros/i_am_lost.ngc", commandTemplate: "O<i_am_lost> call" },
|
|
{ name: "halo_world", args: [], file: "macros/halo_world.ngc", commandTemplate: "O<halo_world> call" },
|
|
{ name: "jog_around", args: [], file: "macros/jog_around.ngc", commandTemplate: "O<jog_around> call" },
|
|
{ name: "increment", args: ["xinc", "yinc"], file: "macros/increment.ngc", commandTemplate: "O<increment> call [xinc] [yinc]" },
|
|
{ name: "go_to_position", args: ["X-pos", "Y-pos", "Z-pos"], file: "macros/go_to_position.ngc", commandTemplate: "O<go_to_position> call [X-pos] [Y-pos] [Z-pos]" },
|
|
],
|
|
nativeCallbacks: [
|
|
"_make_macro_button -> get_ini_info.get_macros()",
|
|
"_on_btn_macro_pressed -> command.mdi(O<name> call [args])",
|
|
"on_hal_status_interp_idle enables macro buttons",
|
|
"on_hal_status_interp_run disables macro buttons",
|
|
],
|
|
webAction: "GMOCAPY_RUN_MACRO",
|
|
implementation: "partial",
|
|
boundary: "macro_buttons_map_to_MDI_command_without_native_entry_dialogs",
|
|
},
|
|
toolEditorPage: {
|
|
pageId: "tool-editor",
|
|
nativeNotebookPage: "ntb_preview page 2 / _BB_TOOL",
|
|
nativeWidget: "tooledit1",
|
|
toolTablePath: "linuxcnc/configs/sim/gmoccapy/tool.tbl",
|
|
visibleAxes: ["X", "Y", "Z", "A", "B"],
|
|
toolCount: 17,
|
|
nativeCallbacks: [
|
|
"_init_tooleditor -> tooledit1.set_filename(tool.tbl)",
|
|
"_show_tooledit_tab(True) -> tooledit1.reload()",
|
|
"on_btn_selected_tool_clicked -> M61 Q? or T? M6",
|
|
"on_btn_save_tool_changes_clicked -> tooledit1.save(None)",
|
|
"on_btn_reload_tooltable_clicked -> tooledit1.reload(None)",
|
|
],
|
|
webAction: "GMOCAPY_TOOL_EDITOR_ACTION diagnostics",
|
|
editableInWeb: false,
|
|
implementation: "diagnostic-only",
|
|
boundary: "tool_table_writeback_not_promoted_browser_keeps_iocontrol_loopback",
|
|
},
|
|
implementationMatrix: [
|
|
{ pageId: "main", nativeWidget: "ntb_main page 0", implementation: "implemented", webSurface: "DRO/G-code/preview/main controls", hardButton: null },
|
|
{ pageId: "manual-home", nativeWidget: "btn_homing / _BB_HOME", implementation: "partial", webSurface: "HOME action", hardButton: "gmoccapy.h-button.button-0" },
|
|
{ pageId: "mdi-macros", nativeWidget: "hbtb_MDI macro buttons", implementation: "partial", webSurface: "MDI macro diagnostics and dispatch", hardButton: null },
|
|
{ pageId: "auto-run", nativeWidget: "_BB_AUTO buttons", implementation: "partial", webSurface: "RUN/STOP/PAUSE/STEP controls", hardButton: null },
|
|
{ pageId: "file-load", nativeWidget: "IconFileSelection1 / _BB_LOAD_FILE", implementation: "partial", webSurface: "OPEN_FILE input and staged source selector", hardButton: null },
|
|
{ pageId: "tool-editor", nativeWidget: "btn_tool / tooledit1", implementation: "diagnostic-only", webSurface: "tool table summary and action diagnostics", hardButton: "gmoccapy.h-button.button-3" },
|
|
{ pageId: "touch-off", nativeWidget: "btn_touch / offsetpage1", implementation: "diagnostic-only", webSurface: "touch-off boundary diagnostics", hardButton: "gmoccapy.h-button.button-1" },
|
|
{ pageId: "setup", nativeWidget: "tbtn_setup / ntb_setup", implementation: "diagnostic-only", webSurface: "settings/unlock diagnostics", hardButton: "gmoccapy.v-button.button-6" },
|
|
{ pageId: "user-tabs", nativeWidget: "tbtn_user_tabs / ntb_user_tabs", implementation: "diagnostic-only", webSurface: "user tab boundary diagnostics", hardButton: "gmoccapy.v-button.button-5" },
|
|
{ pageId: "switchkins-mode", nativeWidget: "tbtn_switch_mode", implementation: "diagnostic-only", webSurface: "identity-only XYZAB switchkins diagnostic", hardButton: "gmoccapy.h-button.button-6" },
|
|
{ pageId: "edit", nativeWidget: "_BB_EDIT / gcode_view editable", implementation: "native-only", webSurface: "not promoted", hardButton: null },
|
|
{ pageId: "offset-editor", nativeWidget: "offsetpage1 edit offsets", implementation: "native-only", webSurface: "not promoted", hardButton: null },
|
|
],
|
|
behavior: {
|
|
unimplementedPagesDiagnosticOnly: true,
|
|
hardButtonsDoNotFakeNativePages: true,
|
|
fileChooserNotNativeGtk: true,
|
|
macroButtonsUseMdiGate: true,
|
|
toolEditorWritebackDisabled: true,
|
|
toolEditorKeepsIocontrolLoopback: true,
|
|
semanticBoundary: "native_gmoccapy_page_matrix_web_diagnostic_boundary",
|
|
},
|
|
},
|
|
toolChange: {
|
|
strategy: "iocontrol-loopback",
|
|
manualGmoccapyPinsConnected: false,
|
|
remapCodes: ["M6", "M61"],
|
|
postguiUnlinks: [
|
|
{
|
|
pin: "iocontrol.0.tool-change",
|
|
reason: "gmoccapy_postgui.hal removes the core_sim connection before applying the final loopback",
|
|
},
|
|
{
|
|
pin: "iocontrol.0.tool-changed",
|
|
reason: "gmoccapy_postgui.hal removes the core_sim connection before applying the final loopback",
|
|
},
|
|
{
|
|
pin: "iocontrol.0.tool-prep-number",
|
|
reason: "manual gmoccapy tool-change number net is not active in this simulation",
|
|
},
|
|
],
|
|
commentedManualGuiNets: [
|
|
{
|
|
signal: "tool-change",
|
|
source: "iocontrol.0.tool-change",
|
|
target: "gmoccapy.toolchange-change",
|
|
},
|
|
{
|
|
signal: "tool-changed",
|
|
source: "gmoccapy.toolchange-changed",
|
|
target: "iocontrol.0.tool-changed",
|
|
},
|
|
{
|
|
signal: "tool-prep-number",
|
|
source: "iocontrol.0.tool-prep-number",
|
|
target: "gmoccapy.toolchange-number",
|
|
},
|
|
],
|
|
activeLoop: {
|
|
signal: "tool-change-loop",
|
|
source: "iocontrol.0.tool-change",
|
|
target: "iocontrol.0.tool-changed",
|
|
stage: "POSTGUI_HALFILE",
|
|
},
|
|
semanticBoundary: "gmoccapy_xyzab_iocontrol_tool_change_loop_no_manual_gui_dialog",
|
|
},
|
|
semanticBoundary: "gmoccapy_hal_pin_postgui_reference_web_diagnostic_only",
|
|
};
|
|
|
|
export function createGmoccapyHalSummary(model = gmoccapyHalModel) {
|
|
const pinCount = model.nativePins.reduce((total, group) => total + group.pins.length, 0);
|
|
const postguiFile = model.halFiles.find((file) => file.stage === "POSTGUI_HALFILE");
|
|
const mappedHardwareButtonCount = [
|
|
...(model.hardwareButtons?.verticalMain || []),
|
|
...(model.hardwareButtons?.bottomMain || []),
|
|
].filter((button) => button.webSelector).length;
|
|
return {
|
|
apiName: `${model.apiName}-summary`,
|
|
profileId: model.profileId,
|
|
halFileCount: model.halFiles.length,
|
|
nativePinGroupCount: model.nativePins.length,
|
|
nativePinCount: pinCount,
|
|
coreNetCount: model.coreNets.length,
|
|
spindleNetCount: model.spindleNets.length,
|
|
postguiNetCount: model.postguiNets.length,
|
|
postguiRequiresHalcompReady: Boolean(postguiFile?.requiresHalcompReady) &&
|
|
model.postguiNets.every((net) => net.requiresHalcompReady),
|
|
hasToolChangeSimulationLoop: model.postguiNets.some((net) => net.simulationLoop),
|
|
toolChangeStrategy: model.toolChange.strategy,
|
|
manualToolChangeGuiConnected: model.toolChange.manualGmoccapyPinsConnected,
|
|
postguiToolUnlinkCount: model.toolChange.postguiUnlinks.length,
|
|
commentedManualToolChangeNetCount: model.toolChange.commentedManualGuiNets.length,
|
|
hardwareButtonVerticalCount: model.hardwareButtons.verticalMain.length,
|
|
hardwareButtonBottomMainCount: model.hardwareButtons.bottomMain.length,
|
|
mappedHardwareButtonCount,
|
|
hardwareButtonEdge: model.hardwareButtons.behavior.edge,
|
|
hardwareButtonInsensitiveTarget: model.hardwareButtons.behavior.insensitiveTarget,
|
|
operatorInputPinCount: model.halPinActions.operatorPins.length,
|
|
settingsInputPinCount: model.halPinActions.settingsPins.length,
|
|
overridePinTargetCount: model.halPinActions.overridePins.length,
|
|
jogAxisPinCount: (model.halPinActions.jogPins?.axes || []).length * 2,
|
|
jogIncrementPinCount: model.halPinActions.jogPins?.increments?.length || 0,
|
|
messageInputPinCount: model.halPinActions.messagePins.length,
|
|
toolMeasurementPinCount: model.halPinActions.toolMeasurementPins.pins.length,
|
|
toolMeasurementEnabled: model.halPinActions.toolMeasurementPins.useToolMeasurementPref,
|
|
toolsensorConfigured: model.halPinActions.toolMeasurementPins.toolsensorConfigured,
|
|
userMessagePinCount: model.halPinActions.userMessages.pins.length,
|
|
userMessagesConfigured: model.halPinActions.userMessages.configured,
|
|
optionalStopPinCrossesToBlockDelete: model.halPinActions.behavior.optionalStopPinCrossesToBlockDelete,
|
|
blockdeletePinCrossesToOptionalStop: model.halPinActions.behavior.blockdeletePinCrossesToOptionalStop,
|
|
unlockSettingsLevelDriven: model.halPinActions.behavior.unlockSettingsLevelDriven,
|
|
jogAxisPinsPressRelease: model.halPinActions.behavior.jogAxisPinsPressRelease,
|
|
jogPinsUseTaskPolicyGate: model.halPinActions.behavior.jogPinsUseTaskPolicyGate,
|
|
jogIncrementPinsRisingEdgeOnly: model.halPinActions.behavior.jogIncrementPinsRisingEdgeOnly,
|
|
jogIncrementZeroIsContinuous: model.halPinActions.behavior.jogIncrementZeroIsContinuous,
|
|
turtleJogLevelDriven: model.halPinActions.behavior.turtleJogLevelDriven,
|
|
countInputRequiresEnable: model.halPinActions.behavior.countInputRequiresEnable,
|
|
directValueRequiresAnalogEnable: model.halPinActions.behavior.directValueRequiresAnalogEnable,
|
|
resetPinsRisingEdgeOnly: model.halPinActions.behavior.resetPinsRisingEdgeOnly,
|
|
deleteMessageRisingEdgeOnly: model.halPinActions.behavior.deleteMessageRisingEdgeOnly,
|
|
warningConfirmLevelPolled: model.halPinActions.behavior.warningConfirmLevelPolled,
|
|
toolMeasurementPinsAreHalOut: model.halPinActions.behavior.toolMeasurementPinsAreHalOut,
|
|
toolMeasurementDisabledWithoutToolsensor: model.halPinActions.behavior.toolMeasurementDisabledWithoutToolsensor,
|
|
userMessagesDynamicIniOnly: model.halPinActions.behavior.userMessagesDynamicIniOnly,
|
|
nativePageCount: model.nativePages.implementationMatrix.length,
|
|
implementedNativePageCount: model.nativePages.implementationMatrix
|
|
.filter((page) => page.implementation === "implemented").length,
|
|
partialNativePageCount: model.nativePages.implementationMatrix
|
|
.filter((page) => page.implementation === "partial").length,
|
|
diagnosticOnlyNativePageCount: model.nativePages.implementationMatrix
|
|
.filter((page) => page.implementation === "diagnostic-only").length,
|
|
nativeOnlyPageCount: model.nativePages.implementationMatrix
|
|
.filter((page) => page.implementation === "native-only").length,
|
|
filePageImplementation: model.nativePages.filePage.implementation,
|
|
filePageBoundary: model.nativePages.filePage.boundary,
|
|
macroCount: model.nativePages.macroPage.macros.length,
|
|
macroLimit: model.nativePages.macroPage.macroLimit,
|
|
macroButtonsUseMdiGate: model.nativePages.behavior.macroButtonsUseMdiGate,
|
|
toolEditorImplementation: model.nativePages.toolEditorPage.implementation,
|
|
toolEditorWritebackDisabled: model.nativePages.behavior.toolEditorWritebackDisabled,
|
|
hardButtonsDoNotFakeNativePages: model.nativePages.behavior.hardButtonsDoNotFakeNativePages,
|
|
unimplementedPagesDiagnosticOnly: model.nativePages.behavior.unimplementedPagesDiagnosticOnly,
|
|
semanticBoundary: model.semanticBoundary,
|
|
};
|
|
}
|
|
|
|
export function resolveGmoccapyHardwareButton(input, model = gmoccapyHalModel) {
|
|
const pin = typeof input === "string" ? input : input?.pin;
|
|
const location = typeof input === "object" ? input?.location || input?.panel : null;
|
|
const index = typeof input === "object" && input?.index !== undefined ? Number(input.index) : null;
|
|
const allButtons = [
|
|
...(model.hardwareButtons?.verticalMain || []).map((button) => ({ ...button, panel: "right", location: "v" })),
|
|
...(model.hardwareButtons?.bottomMain || []).map((button) => ({ ...button, panel: "bottom", location: "h" })),
|
|
];
|
|
if (pin) return allButtons.find((button) => button.pin === pin) || null;
|
|
if (!Number.isFinite(index)) return null;
|
|
const normalizedLocation = location === "right" || location === "v" || location === "vertical" ? "v"
|
|
: location === "bottom" || location === "h" || location === "horizontal" ? "h"
|
|
: null;
|
|
return allButtons.find((button) => button.location === normalizedLocation && button.index === index) || null;
|
|
}
|