|
|
|
|
@@ -0,0 +1,235 @@
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <iterator>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "emc/ini/inifile.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;
|
|
|
|
|
const char *machine;
|
|
|
|
|
const char *kinematics;
|
|
|
|
|
const char *coordinates;
|
|
|
|
|
const char *joints;
|
|
|
|
|
const char *parameter_file;
|
|
|
|
|
const char *tool_table;
|
|
|
|
|
bool expects_m430;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string vendor_path(const std::string &rel)
|
|
|
|
|
{
|
|
|
|
|
return std::string(LINUXCNC_VENDOR_DIR) + "/" + rel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string read_text(const std::string &path)
|
|
|
|
|
{
|
|
|
|
|
std::ifstream input(path);
|
|
|
|
|
return std::string(
|
|
|
|
|
std::istreambuf_iterator<char>(input),
|
|
|
|
|
std::istreambuf_iterator<char>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool contains(const std::string &text, const std::string &needle)
|
|
|
|
|
{
|
|
|
|
|
return text.find(needle) != std::string::npos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void print_bool(const std::string &name, bool value)
|
|
|
|
|
{
|
|
|
|
|
std::cout << name << "=" << (value ? 1 : 0) << "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_string(
|
|
|
|
|
const linuxcnc::IniFile &ini,
|
|
|
|
|
const std::string &label,
|
|
|
|
|
const std::string §ion,
|
|
|
|
|
const std::string &tag,
|
|
|
|
|
const std::string &expected)
|
|
|
|
|
{
|
|
|
|
|
const auto actual = ini.findString(tag, section);
|
|
|
|
|
std::cout << label << "_" << section << "." << tag << "="
|
|
|
|
|
<< (actual ? *actual : "<missing>") << "\n";
|
|
|
|
|
const bool ok = actual && *actual == expected;
|
|
|
|
|
print_bool(label + "_" + section + "." + tag + "_ok", ok);
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_remap_entry(
|
|
|
|
|
const std::vector<std::string> &remaps,
|
|
|
|
|
const std::string &label,
|
|
|
|
|
const std::string &mcode,
|
|
|
|
|
const std::string &ngc)
|
|
|
|
|
{
|
|
|
|
|
const std::string mcode_needle = "REMAP = " + mcode;
|
|
|
|
|
const std::string ngc_needle = "ngc=" + ngc;
|
|
|
|
|
bool ok = false;
|
|
|
|
|
for (const auto &remap : remaps) {
|
|
|
|
|
if (contains(remap, mcode) && contains(remap, ngc_needle)) {
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
print_bool(label + "_remap_" + mcode + "_" + ngc, ok);
|
|
|
|
|
(void)mcode_needle;
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_remap_file(
|
|
|
|
|
const std::string &label,
|
|
|
|
|
const std::string &dir_rel,
|
|
|
|
|
const std::string &mcode,
|
|
|
|
|
const std::string &expected_kinstype)
|
|
|
|
|
{
|
|
|
|
|
const std::string path = vendor_path(dir_rel + "/remap_subs/" + mcode.substr(1) + "remap.ngc");
|
|
|
|
|
const std::string text = read_text(path);
|
|
|
|
|
const bool ok =
|
|
|
|
|
contains(text, "o<" + mcode.substr(1) + "remap>sub") &&
|
|
|
|
|
contains(text, "#<kinstype> = " + expected_kinstype) &&
|
|
|
|
|
contains(text, "#<SWITCHKINS_PIN> = 3") &&
|
|
|
|
|
contains(text, "#<_hal[motion.switchkins-type]>") &&
|
|
|
|
|
contains(text, "M68") &&
|
|
|
|
|
contains(text, "M66") &&
|
|
|
|
|
contains(text, "o<" + mcode.substr(1) + "remap>endsub");
|
|
|
|
|
print_bool(label + "_" + mcode + "_remap_file_from_linuxcnc", ok);
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_text_mcodes(
|
|
|
|
|
const std::string &label,
|
|
|
|
|
const std::string &rel,
|
|
|
|
|
bool expects_m428,
|
|
|
|
|
bool expects_m429)
|
|
|
|
|
{
|
|
|
|
|
const std::string text = read_text(vendor_path(rel));
|
|
|
|
|
const bool ok =
|
|
|
|
|
(!expects_m428 || contains(text, "M428")) &&
|
|
|
|
|
(!expects_m429 || contains(text, "M429"));
|
|
|
|
|
print_bool(label + "_switch_mcodes_from_linuxcnc", ok);
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_machine(const MachineCase &machine)
|
|
|
|
|
{
|
|
|
|
|
bool ok = true;
|
|
|
|
|
const std::string ini_path = vendor_path(machine.ini_rel);
|
|
|
|
|
linuxcnc::IniFile ini(ini_path);
|
|
|
|
|
const bool opened = static_cast<bool>(ini);
|
|
|
|
|
print_bool(std::string(machine.label) + "_ini_open", opened);
|
|
|
|
|
if (!opened) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ok &= check_string(ini, machine.label, "EMC", "MACHINE", machine.machine);
|
|
|
|
|
ok &= check_string(ini, machine.label, "KINS", "KINEMATICS", machine.kinematics);
|
|
|
|
|
ok &= check_string(ini, machine.label, "TRAJ", "COORDINATES", machine.coordinates);
|
|
|
|
|
ok &= check_string(ini, machine.label, "KINS", "JOINTS", machine.joints);
|
|
|
|
|
ok &= check_string(ini, machine.label, "RS274NGC", "SUBROUTINE_PATH", "./remap_subs");
|
|
|
|
|
ok &= check_string(ini, machine.label, "RS274NGC", "PARAMETER_FILE", machine.parameter_file);
|
|
|
|
|
ok &= check_string(ini, machine.label, "EMCIO", "TOOL_TABLE", machine.tool_table);
|
|
|
|
|
|
|
|
|
|
const auto remaps = ini.findStringAll("REMAP", "RS274NGC");
|
|
|
|
|
std::cout << machine.label << "_remap_count=" << remaps.size() << "\n";
|
|
|
|
|
ok &= check_remap_entry(remaps, machine.label, "M428", "428remap");
|
|
|
|
|
ok &= check_remap_entry(remaps, machine.label, "M429", "429remap");
|
|
|
|
|
if (machine.expects_m430) {
|
|
|
|
|
ok &= check_remap_entry(remaps, machine.label, "M430", "430remap");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string ini_text = read_text(ini_path);
|
|
|
|
|
const bool has_switchkins_halcmd =
|
|
|
|
|
contains(ini_text, "motion.analog-out-03 => motion.switchkins-type");
|
|
|
|
|
ok &= has_switchkins_halcmd;
|
|
|
|
|
print_bool(std::string(machine.label) + "_halcmd_switchkins_from_linuxcnc", has_switchkins_halcmd);
|
|
|
|
|
|
|
|
|
|
const std::string dir_rel = std::string(machine.ini_rel).substr(
|
|
|
|
|
0,
|
|
|
|
|
std::string(machine.ini_rel).find_last_of('/'));
|
|
|
|
|
return ok && check_remap_file(machine.label, dir_rel, "M428",
|
|
|
|
|
std::string(machine.label) == "bridgemill" ? "0" : "1") &&
|
|
|
|
|
check_remap_file(machine.label, dir_rel, "M429",
|
|
|
|
|
std::string(machine.label) == "bridgemill" ? "1" : "0") &&
|
|
|
|
|
(!machine.expects_m430 || check_remap_file(machine.label, dir_rel, "M430", "2"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
const MachineCase cases[] = {
|
|
|
|
|
{
|
|
|
|
|
"bridgemill",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/bridgemill/5axis.ini",
|
|
|
|
|
"Sim-5Axis Bridge Mill (xyzbcw)",
|
|
|
|
|
"5axiskins coordinates=xyzbcwy",
|
|
|
|
|
"XYZBCWY",
|
|
|
|
|
"7",
|
|
|
|
|
"5axis.var",
|
|
|
|
|
"5axis.tbl",
|
|
|
|
|
true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"xyzab_tdr",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini",
|
|
|
|
|
"sim-xyzab-tdr-kins (switchkins)",
|
|
|
|
|
"xyzab_tdr_kins",
|
|
|
|
|
"XYZAB",
|
|
|
|
|
"5",
|
|
|
|
|
"xyzab-tdr.var",
|
|
|
|
|
"xyzab-tdr.tbl",
|
|
|
|
|
false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"xyzac_trt",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
|
|
|
|
|
"sim-xyzac-trt-kins (switchkins)",
|
|
|
|
|
"xyzac-trt-kins sparm=identityfirst",
|
|
|
|
|
"XYZAC",
|
|
|
|
|
"5",
|
|
|
|
|
"xyzac.var",
|
|
|
|
|
"xyzac-trt.tbl",
|
|
|
|
|
true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"xyzbc_trt",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini",
|
|
|
|
|
"sim-xyzbc-trt-kins (switchkins)",
|
|
|
|
|
"xyzbc-trt-kins sparm=identityfirst",
|
|
|
|
|
"XYZBC",
|
|
|
|
|
"5",
|
|
|
|
|
"xyzbc.var",
|
|
|
|
|
"xyzbc-trt.tbl",
|
|
|
|
|
true,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool ok = true;
|
|
|
|
|
for (const auto &machine : cases) {
|
|
|
|
|
ok &= check_machine(machine);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ok &= check_text_mcodes(
|
|
|
|
|
"xyzab_tdr",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-dual-rotary/README",
|
|
|
|
|
true,
|
|
|
|
|
true);
|
|
|
|
|
ok &= check_text_mcodes(
|
|
|
|
|
"xyzac_trt",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc",
|
|
|
|
|
true,
|
|
|
|
|
true);
|
|
|
|
|
ok &= check_text_mcodes(
|
|
|
|
|
"xyzbc_trt",
|
|
|
|
|
"configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc",
|
|
|
|
|
true,
|
|
|
|
|
true);
|
|
|
|
|
|
|
|
|
|
print_bool("fiveaxis_remap_assets_from_linuxcnc", ok);
|
|
|
|
|
return ok ? 0 : 1;
|
|
|
|
|
}
|