按规划持续工作
结论:新增 5axis native remap 执行验证,使用 vendored LinuxCNC REMAP/NGC 路径执行 xyzac-trt 与 xyzbc-trt 的 M429 -> M428 -> M430 -> M429,并确认 _hal[motion.switchkins-type] 随 LinuxCNC M68/M66 流程正确读回。
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
#define private public
|
||||
#include "emc/rs274ngc/rs274ngc_interp.hh"
|
||||
#undef private
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "canon_event_sink.hh"
|
||||
#include "emc/ini/inifile.hh"
|
||||
#include "emc/rs274ngc/interp_internal.hh"
|
||||
#include "linuxcnc_hal_adapter.hh"
|
||||
#include "linuxcnc_tool_adapter.hh"
|
||||
|
||||
#ifndef LINUXCNC_VENDOR_DIR
|
||||
#error "LINUXCNC_VENDOR_DIR must point at wasm-port/vendor/linuxcnc"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
struct MachineCase {
|
||||
const char *label;
|
||||
const char *ini_rel;
|
||||
};
|
||||
|
||||
std::filesystem::path vendor_path(const std::string &rel)
|
||||
{
|
||||
return std::filesystem::path(LINUXCNC_VENDOR_DIR) / rel;
|
||||
}
|
||||
|
||||
void print_bool(const std::string &name, bool value)
|
||||
{
|
||||
std::cout << name << "=" << (value ? 1 : 0) << "\n";
|
||||
}
|
||||
|
||||
void seed_switchkins_hal()
|
||||
{
|
||||
standalone::reset_hal_adapter();
|
||||
|
||||
hal_data_u switchkins{};
|
||||
switchkins.f = 0.0;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "motion.switchkins-type",
|
||||
HAL_FLOAT, switchkins);
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "motion.analog-out-03",
|
||||
HAL_FLOAT, switchkins);
|
||||
standalone::link_hal_pin_alias("motion.analog-out-03", "motion.switchkins-type");
|
||||
}
|
||||
|
||||
void initialize_interp(Interp &interp)
|
||||
{
|
||||
seed_switchkins_hal();
|
||||
standalone::reset_tool_adapter();
|
||||
standalone::reset_canon_events();
|
||||
|
||||
interp._setup.length_units = CANON_UNITS_MM;
|
||||
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
|
||||
interp._setup.plane = CANON_PLANE::XY;
|
||||
interp._setup.motion_mode = G_0;
|
||||
interp._setup.percent_flag = false;
|
||||
interp._setup.sequence_number = 0;
|
||||
interp._setup.parameter_occurrence = 0;
|
||||
interp._setup.num_spindles = 1;
|
||||
interp._setup.feature_set = FEATURE_INI_VARS | FEATURE_HAL_PIN_VARS;
|
||||
interp._setup.parameter_g73_peck_clearance = 1.0;
|
||||
interp._setup.parameter_g83_peck_clearance = 1.0;
|
||||
interp._setup.parameters[5599] = 1.0;
|
||||
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||
interp.init_named_parameters();
|
||||
}
|
||||
|
||||
bool read_hal_named(Interp &interp, const std::string &label, const char *name, double expected)
|
||||
{
|
||||
int status = 0;
|
||||
double value = 0.0;
|
||||
const int rc = interp.find_named_param(name, &status, &value);
|
||||
std::cout << label << "_" << name << ": rc=" << rc << " found=" << status
|
||||
<< " value=" << value << "\n";
|
||||
return rc == INTERP_OK && status == 1 && std::fabs(value - expected) < 0.000001;
|
||||
}
|
||||
|
||||
bool parse_machine_remaps(Interp &interp, const MachineCase &machine)
|
||||
{
|
||||
const auto ini_path = vendor_path(machine.ini_rel);
|
||||
const auto machine_dir = ini_path.parent_path();
|
||||
const auto remap_dir = machine_dir / "remap_subs";
|
||||
|
||||
linuxcnc::IniFile ini(ini_path.string());
|
||||
const bool opened = static_cast<bool>(ini);
|
||||
print_bool(std::string(machine.label) + "_ini_open", opened);
|
||||
if (!opened) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::snprintf(interp._setup.program_prefix, sizeof(interp._setup.program_prefix), "%s",
|
||||
machine_dir.c_str());
|
||||
interp._setup.subroutines[0] = strstore(remap_dir.c_str());
|
||||
|
||||
bool ok = true;
|
||||
int remap_count = 0;
|
||||
int line_number = 0;
|
||||
while (auto remap = ini.findString(++remap_count, "REMAP", "RS274NGC")) {
|
||||
line_number = ini.lineOf(remap_count, "REMAP", "RS274NGC").second;
|
||||
const int rc = interp.parse_remap(remap->c_str(), line_number);
|
||||
std::cout << machine.label << "_parse_remap_" << remap_count << "=" << rc << "\n";
|
||||
ok &= rc == INTERP_OK;
|
||||
}
|
||||
|
||||
remap_count -= 1;
|
||||
std::cout << machine.label << "_parsed_remap_count=" << remap_count << "\n";
|
||||
ok &= remap_count == 3;
|
||||
print_bool(std::string(machine.label) + "_remaps_ready", ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
std::string command_label(const char *command)
|
||||
{
|
||||
std::string value = command ? command : "";
|
||||
while (!value.empty() && (value.back() == '\n' || value.back() == '\r')) {
|
||||
value.pop_back();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool execute_step(Interp &interp, const std::string &label, const char *command, double expected)
|
||||
{
|
||||
const std::string step = command_label(command);
|
||||
int rc = interp.execute(command);
|
||||
std::cout << label << "_" << step << "_execute_0=" << rc << "\n";
|
||||
|
||||
int finish_count = 0;
|
||||
while (rc == INTERP_EXECUTE_FINISH && finish_count < 8) {
|
||||
++finish_count;
|
||||
rc = interp.execute();
|
||||
std::cout << label << "_" << step << "_execute_" << finish_count << "=" << rc << "\n";
|
||||
}
|
||||
|
||||
std::cout << label << "_" << step << "_execute_finish_count=" << finish_count << "\n";
|
||||
bool ok = rc == INTERP_OK;
|
||||
ok &= read_hal_named(interp, label, "_hal[motion.switchkins-type]", expected);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool check_machine(const MachineCase &machine)
|
||||
{
|
||||
Interp interp;
|
||||
initialize_interp(interp);
|
||||
|
||||
bool ok = parse_machine_remaps(interp, machine);
|
||||
ok &= read_hal_named(interp, machine.label, "_hal[motion.switchkins-type]", 0.0);
|
||||
ok &= execute_step(interp, machine.label, "M429\n", 0.0);
|
||||
ok &= execute_step(interp, machine.label, "M428\n", 1.0);
|
||||
ok &= execute_step(interp, machine.label, "M430\n", 2.0);
|
||||
ok &= execute_step(interp, machine.label, "M429\n", 0.0);
|
||||
|
||||
print_bool(std::string(machine.label) + "_linuxcnc_remap_execute_path", ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
const MachineCase cases[] = {
|
||||
{
|
||||
"xyzac_trt",
|
||||
"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
|
||||
},
|
||||
{
|
||||
"xyzbc_trt",
|
||||
"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini",
|
||||
},
|
||||
};
|
||||
|
||||
bool ok = true;
|
||||
for (const auto &machine : cases) {
|
||||
ok &= check_machine(machine);
|
||||
}
|
||||
|
||||
print_bool("fiveaxis_linuxcnc_remap_execute_path", ok);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user