wasm-port: broaden native LinuxCNC interpreter probes
This commit is contained in:
109
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_adapter.cpp
Normal file
109
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_adapter.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "linuxcnc_hal_adapter.hh"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace {
|
||||
|
||||
struct HalEntry {
|
||||
hal_type_t type = HAL_TYPE_UNINITIALIZED;
|
||||
hal_data_u value{};
|
||||
bool connected = true;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, HalEntry> &pins()
|
||||
{
|
||||
static std::unordered_map<std::string, HalEntry> values;
|
||||
return values;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, HalEntry> &signals()
|
||||
{
|
||||
static std::unordered_map<std::string, HalEntry> values;
|
||||
return values;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, HalEntry> ¶ms()
|
||||
{
|
||||
static std::unordered_map<std::string, HalEntry> values;
|
||||
return values;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, HalEntry> &values_for(standalone::HalValueKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case standalone::HalValueKind::Pin:
|
||||
return pins();
|
||||
case standalone::HalValueKind::Signal:
|
||||
return signals();
|
||||
case standalone::HalValueKind::Param:
|
||||
return params();
|
||||
}
|
||||
return pins();
|
||||
}
|
||||
|
||||
int lookup_hal_value(const char *name, std::unordered_map<std::string, HalEntry> &values,
|
||||
hal_type_t *type, hal_data_u **ptr, bool *connected)
|
||||
{
|
||||
if (!name || !type || !ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto it = values.find(name);
|
||||
if (it == values.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*type = it->second.type;
|
||||
*ptr = &it->second.value;
|
||||
if (connected) {
|
||||
*connected = it->second.connected;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace standalone {
|
||||
|
||||
void reset_hal_adapter()
|
||||
{
|
||||
pins().clear();
|
||||
signals().clear();
|
||||
params().clear();
|
||||
}
|
||||
|
||||
void set_hal_value(HalValueKind kind, const char *name, hal_type_t type, hal_data_u value,
|
||||
bool connected)
|
||||
{
|
||||
values_for(kind)[name] = HalEntry{type, value, connected};
|
||||
}
|
||||
|
||||
} // namespace standalone
|
||||
|
||||
int hal_init(const char *)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hal_ready(int)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hal_get_pin_value_by_name(const char *name, hal_type_t *type, hal_data_u **ptr,
|
||||
bool *connected)
|
||||
{
|
||||
return lookup_hal_value(name, pins(), type, ptr, connected);
|
||||
}
|
||||
|
||||
int hal_get_signal_value_by_name(const char *name, hal_type_t *type, hal_data_u **ptr,
|
||||
bool *connected)
|
||||
{
|
||||
return lookup_hal_value(name, signals(), type, ptr, connected);
|
||||
}
|
||||
|
||||
int hal_get_param_value_by_name(const char *name, hal_type_t *type, hal_data_u **ptr)
|
||||
{
|
||||
return lookup_hal_value(name, params(), type, ptr, nullptr);
|
||||
}
|
||||
17
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_adapter.hh
Normal file
17
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_adapter.hh
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
namespace standalone {
|
||||
|
||||
enum class HalValueKind {
|
||||
Pin,
|
||||
Signal,
|
||||
Param,
|
||||
};
|
||||
|
||||
void reset_hal_adapter();
|
||||
void set_hal_value(HalValueKind kind, const char *name, hal_type_t type, hal_data_u value,
|
||||
bool connected = true);
|
||||
|
||||
} // namespace standalone
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <string>
|
||||
|
||||
#define private public
|
||||
#include "emc/rs274ngc/rs274ngc_interp.hh"
|
||||
#undef private
|
||||
|
||||
#include "emc/rs274ngc/rs274ngc_return.hh"
|
||||
#include "interp_python.hh"
|
||||
#include "pythonplugin/python_plugin.hh"
|
||||
|
||||
PythonPlugin *python_plugin = nullptr;
|
||||
int _task = 0;
|
||||
|
||||
struct _inittab {
|
||||
const char *name;
|
||||
void *initfunc;
|
||||
};
|
||||
|
||||
_inittab builtin_modules[] = {{nullptr, nullptr}};
|
||||
|
||||
InterpBase::~InterpBase() {}
|
||||
|
||||
PythonPlugin *PythonPlugin::instantiate(struct _inittab *)
|
||||
{
|
||||
static PythonPlugin standalone_plugin;
|
||||
python_plugin = &standalone_plugin;
|
||||
return python_plugin;
|
||||
}
|
||||
|
||||
std::string handle_pyerror()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Interp::is_pycallable(setup_pointer, const char *, const char *) { return false; }
|
||||
bool Interp::is_user_defined_g_code(int) { return false; }
|
||||
bool Interp::is_any_m_code_remapped(block_pointer, setup_pointer) { return false; }
|
||||
bool Interp::is_user_defined_m_code(block_pointer, setup_pointer, int) { return false; }
|
||||
bool Interp::is_m_code_remappable(int) { return false; }
|
||||
bool Interp::is_g_code_remappable(int) { return false; }
|
||||
bool Interp::remap_in_progress(const char *) { return false; }
|
||||
remap_pointer Interp::remapping(const char *) { return nullptr; }
|
||||
remap_pointer Interp::remapping(const char, int) { return nullptr; }
|
||||
int Interp::parse_remap(const char *, int) { return INTERP_ERROR; }
|
||||
int Interp::convert_remapped_code(block_pointer, setup_pointer, int, char, int) { return INTERP_ERROR; }
|
||||
int Interp::add_parameters(setup_pointer, block_pointer, char *) { return INTERP_ERROR; }
|
||||
int Interp::pycall(setup_pointer, context_pointer, const char *, const char *, int) { return INTERP_ERROR; }
|
||||
int Interp::py_execute(const char *, bool) { return INTERP_ERROR; }
|
||||
int Interp::py_reload() { return INTERP_OK; }
|
||||
@@ -9,11 +9,67 @@
|
||||
#include <vector>
|
||||
|
||||
#include "canon_event_sink.hh"
|
||||
#include "linuxcnc_hal_adapter.hh"
|
||||
#include "linuxcnc_tool_adapter.hh"
|
||||
|
||||
namespace {
|
||||
|
||||
void seed_hal_values()
|
||||
{
|
||||
standalone::reset_hal_adapter();
|
||||
|
||||
hal_data_u pin_bit{};
|
||||
pin_bit.b = true;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-bit", HAL_BIT,
|
||||
pin_bit);
|
||||
|
||||
hal_data_u signal_float{};
|
||||
signal_float.f = 98.25;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-float",
|
||||
HAL_FLOAT, signal_float);
|
||||
|
||||
hal_data_u param_s32{};
|
||||
param_s32.s = -17;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-s32", HAL_S32,
|
||||
param_s32);
|
||||
|
||||
hal_data_u pin_u32{};
|
||||
pin_u32.u = 123456789u;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-u32", HAL_U32,
|
||||
pin_u32);
|
||||
|
||||
hal_data_u signal_s64{};
|
||||
signal_s64.ls = -9000000000LL;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-s64", HAL_S64,
|
||||
signal_s64);
|
||||
|
||||
hal_data_u param_u64{};
|
||||
param_u64.lu = 9000000000ULL;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-u64", HAL_U64,
|
||||
param_u64);
|
||||
|
||||
hal_data_u disconnected{};
|
||||
disconnected.f = 12.5;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.disconnected-float",
|
||||
HAL_FLOAT, disconnected, false);
|
||||
}
|
||||
|
||||
void seed_tool_values()
|
||||
{
|
||||
standalone::reset_tool_adapter();
|
||||
|
||||
CANON_TOOL_TABLE tool = standalone::tool_entry_init();
|
||||
tool.toolno = 2;
|
||||
tool.pocketno = 2;
|
||||
tool.offset.tran.z = 1.25;
|
||||
tool.diameter = 0.25;
|
||||
standalone::set_tool_entry(2, tool);
|
||||
}
|
||||
|
||||
void initialize_minimal_interp(Interp &interp)
|
||||
{
|
||||
seed_hal_values();
|
||||
seed_tool_values();
|
||||
interp._setup.length_units = CANON_UNITS_MM;
|
||||
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
@@ -23,6 +79,10 @@ void initialize_minimal_interp(Interp &interp)
|
||||
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.parameters[5599] = 1.0;
|
||||
interp.load_tool_table();
|
||||
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||
}
|
||||
|
||||
@@ -80,6 +140,51 @@ int main(int argc, char **argv)
|
||||
interp._setup.sequence_number = static_cast<int>(idx + 1);
|
||||
const int execute_rc = interp.execute(program[idx].c_str());
|
||||
std::cout << "execute_line_" << (idx + 1) << "=" << execute_rc << "\n";
|
||||
if (execute_rc > INTERP_MIN_ERROR) {
|
||||
char error_buf[LINELEN] = {0};
|
||||
interp.error_text(execute_rc, error_buf, sizeof(error_buf));
|
||||
std::cout << "error_text=" << error_buf << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
int file_open_rc = INTERP_FILE_NOT_OPEN;
|
||||
int file_read_count = 0;
|
||||
int file_execute_count = 0;
|
||||
if (argc > 1) {
|
||||
Interp file_interp;
|
||||
initialize_minimal_interp(file_interp);
|
||||
file_open_rc = file_interp.open(argv[1]);
|
||||
if (file_open_rc == INTERP_OK) {
|
||||
while (true) {
|
||||
const int file_read_rc = file_interp.read();
|
||||
if (file_read_rc == INTERP_ENDFILE) {
|
||||
std::cout << "file_read_eof=" << file_read_rc << "\n";
|
||||
break;
|
||||
}
|
||||
++file_read_count;
|
||||
std::cout << "file_read_" << file_read_count << "=" << file_read_rc << "\n";
|
||||
if ((file_read_rc != INTERP_OK) && (file_read_rc != INTERP_EXECUTE_FINISH)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const int file_execute_rc = file_interp.execute();
|
||||
++file_execute_count;
|
||||
std::cout << "file_execute_" << file_execute_count << "=" << file_execute_rc << "\n";
|
||||
if (file_execute_rc > INTERP_MIN_ERROR) {
|
||||
char error_buf[LINELEN] = {0};
|
||||
file_interp.error_text(file_execute_rc, error_buf, sizeof(error_buf));
|
||||
std::cout << "file_error_text=" << error_buf << "\n";
|
||||
}
|
||||
if ((file_execute_rc != INTERP_OK) &&
|
||||
(file_execute_rc != INTERP_EXECUTE_FINISH) &&
|
||||
(file_execute_rc != INTERP_EXIT)) {
|
||||
break;
|
||||
}
|
||||
if (file_execute_rc == INTERP_EXIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block block{};
|
||||
@@ -90,6 +195,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
std::cout << "read_text=" << read_text_rc << "\n";
|
||||
std::cout << "file_open=" << file_open_rc << "\n";
|
||||
std::cout << "file_read_count=" << file_read_count << "\n";
|
||||
std::cout << "file_execute_count=" << file_execute_count << "\n";
|
||||
std::cout << "raw_line=" << raw_line << "\n";
|
||||
std::cout << "cooked_line=" << cooked_line << "\n";
|
||||
std::cout << "line_length=" << length << "\n";
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
|
||||
#include "emc/rs274ngc/rs274ngc_return.hh"
|
||||
#include "canon_event_sink.hh"
|
||||
|
||||
PythonPlugin *python_plugin = nullptr;
|
||||
#include "linuxcnc_tool_adapter.hh"
|
||||
|
||||
namespace standalone {
|
||||
|
||||
@@ -71,13 +70,45 @@ void STOP_SPEED_FEED_SYNCH() {}
|
||||
void RIGID_TAP(int, double, double, double, double) {}
|
||||
void STRAIGHT_PROBE(int, double, double, double, double, double, double, double, double, double, unsigned char) {}
|
||||
void STOP() {}
|
||||
void DWELL(double) {}
|
||||
void SET_SPINDLE_MODE(int, double) {}
|
||||
void DWELL(double seconds)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "DWELL seconds=" << seconds;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void SET_SPINDLE_MODE(int spindle, double css_max)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "SET_SPINDLE_MODE spindle=" << spindle << " css_max=" << css_max;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void SPINDLE_RETRACT_TRAVERSE() {}
|
||||
void START_SPINDLE_CLOCKWISE(int, int) {}
|
||||
void START_SPINDLE_COUNTERCLOCKWISE(int, int) {}
|
||||
void SET_SPINDLE_SPEED(int, double) {}
|
||||
void STOP_SPINDLE_TURNING(int) {}
|
||||
void START_SPINDLE_CLOCKWISE(int spindle, int wait_for_at_speed)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "START_SPINDLE_CLOCKWISE spindle=" << spindle
|
||||
<< " wait_for_at_speed=" << wait_for_at_speed;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void START_SPINDLE_COUNTERCLOCKWISE(int spindle, int wait_for_at_speed)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "START_SPINDLE_COUNTERCLOCKWISE spindle=" << spindle
|
||||
<< " wait_for_at_speed=" << wait_for_at_speed;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void SET_SPINDLE_SPEED(int spindle, double speed)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "SET_SPINDLE_SPEED spindle=" << spindle << " speed=" << speed;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void STOP_SPINDLE_TURNING(int spindle)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "STOP_SPINDLE_TURNING spindle=" << spindle;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void SPINDLE_RETRACT() {}
|
||||
void ORIENT_SPINDLE(int, double, int) {}
|
||||
void WAIT_SPINDLE_ORIENT_COMPLETE(int, double) {}
|
||||
@@ -85,10 +116,40 @@ void LOCK_SPINDLE_Z() {}
|
||||
void USE_SPINDLE_FORCE() {}
|
||||
void USE_NO_SPINDLE_FORCE() {}
|
||||
void SET_TOOL_TABLE_ENTRY(int, int, const EmcPose &, double, double, double, int) {}
|
||||
void USE_TOOL_LENGTH_OFFSET(const EmcPose &) {}
|
||||
void CHANGE_TOOL() {}
|
||||
void SELECT_TOOL(int) {}
|
||||
void CHANGE_TOOL_NUMBER(int) {}
|
||||
void USE_TOOL_LENGTH_OFFSET(const EmcPose &offset)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "USE_TOOL_LENGTH_OFFSET"
|
||||
<< " x=" << offset.tran.x
|
||||
<< " y=" << offset.tran.y
|
||||
<< " z=" << offset.tran.z
|
||||
<< " a=" << offset.a
|
||||
<< " b=" << offset.b
|
||||
<< " c=" << offset.c
|
||||
<< " u=" << offset.u
|
||||
<< " v=" << offset.v
|
||||
<< " w=" << offset.w;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void CHANGE_TOOL()
|
||||
{
|
||||
standalone::change_selected_tool();
|
||||
standalone::push_canon_event("CHANGE_TOOL");
|
||||
}
|
||||
void SELECT_TOOL(int tool)
|
||||
{
|
||||
standalone::select_tool(tool);
|
||||
std::ostringstream oss;
|
||||
oss << "SELECT_TOOL tool=" << tool;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void CHANGE_TOOL_NUMBER(int pocket)
|
||||
{
|
||||
standalone::change_tool_number(pocket);
|
||||
std::ostringstream oss;
|
||||
oss << "CHANGE_TOOL_NUMBER pocket=" << pocket;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
void RELOAD_TOOLDATA(void) {}
|
||||
void CLAMP_AXIS(CANON_AXIS) {}
|
||||
void DISABLE_ADAPTIVE_FEED() {}
|
||||
@@ -99,10 +160,10 @@ void DISABLE_SPEED_OVERRIDE(int) {}
|
||||
void ENABLE_SPEED_OVERRIDE(int) {}
|
||||
void DISABLE_FEED_HOLD() {}
|
||||
void ENABLE_FEED_HOLD() {}
|
||||
void FLOOD_OFF() {}
|
||||
void FLOOD_ON() {}
|
||||
void MIST_OFF() {}
|
||||
void MIST_ON() {}
|
||||
void FLOOD_OFF() { standalone::push_canon_event("FLOOD_OFF"); }
|
||||
void FLOOD_ON() { standalone::push_canon_event("FLOOD_ON"); }
|
||||
void MIST_OFF() { standalone::push_canon_event("MIST_OFF"); }
|
||||
void MIST_ON() { standalone::push_canon_event("MIST_ON"); }
|
||||
void PALLET_SHUTTLE() {}
|
||||
void TURN_PROBE_OFF() {}
|
||||
void TURN_PROBE_ON() {}
|
||||
@@ -144,7 +205,8 @@ void CANON_ERROR(const char *fmt, ...)
|
||||
|
||||
double GET_EXTERNAL_FEED_RATE() { return 0.0; }
|
||||
int GET_EXTERNAL_FLOOD() { return 0; }
|
||||
double GET_EXTERNAL_LENGTH_UNITS() { return CANON_UNITS_MM; }
|
||||
CANON_UNITS GET_EXTERNAL_LENGTH_UNIT_TYPE() { return CANON_UNITS_MM; }
|
||||
double GET_EXTERNAL_LENGTH_UNITS() { return 1.0; }
|
||||
double GET_EXTERNAL_ANGLE_UNITS() { return 1.0; }
|
||||
int GET_EXTERNAL_MIST() { return 0; }
|
||||
CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE() { return CANON_EXACT_STOP; }
|
||||
@@ -198,7 +260,12 @@ double GET_EXTERNAL_TOOL_LENGTH_VOFFSET() { return 0.0; }
|
||||
double GET_EXTERNAL_TOOL_LENGTH_WOFFSET() { return 0.0; }
|
||||
int GET_EXTERNAL_TOOL_SLOT() { return 0; }
|
||||
int GET_EXTERNAL_SELECTED_TOOL_SLOT() { return -1; }
|
||||
CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int) { return tooldata_entry_init(); }
|
||||
CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int index)
|
||||
{
|
||||
CANON_TOOL_TABLE tool = standalone::tool_entry_init();
|
||||
standalone::get_tool_entry(&tool, index);
|
||||
return tool;
|
||||
}
|
||||
int GET_EXTERNAL_TC_FAULT() { return 0; }
|
||||
int GET_EXTERNAL_TC_REASON() { return 0; }
|
||||
double GET_EXTERNAL_TRAVERSE_RATE() { return 0.0; }
|
||||
@@ -288,277 +355,3 @@ void SET_FEED_RATE(double rate)
|
||||
oss << "SET_FEED_RATE rate=" << rate;
|
||||
standalone::push_canon_event(oss.str());
|
||||
}
|
||||
|
||||
InterpBase::~InterpBase() {}
|
||||
|
||||
Interp::Interp()
|
||||
: log_file(stderr),
|
||||
_setup{}
|
||||
{
|
||||
_setup.init_once = 1;
|
||||
memset(_readers, 0, sizeof(_readers));
|
||||
}
|
||||
|
||||
Interp::~Interp() {
|
||||
if (log_file && log_file != stderr) {
|
||||
fclose(log_file);
|
||||
}
|
||||
log_file = nullptr;
|
||||
}
|
||||
|
||||
void Interp::doLog(unsigned int, const char *, int, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
const char *Interp::interp_status(int status)
|
||||
{
|
||||
static char statustext[64];
|
||||
snprintf(statustext, sizeof(statustext), "%d", status);
|
||||
return statustext;
|
||||
}
|
||||
|
||||
const char *Interp::getSavedError()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int Interp::setSavedError(const char *)
|
||||
{
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
void Interp::setError(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputc('\n', stderr);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int Interp::unwind_call(int status, const char *, int, const char *)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
int Interp::close() { return INTERP_OK; }
|
||||
int Interp::execute(const char *command)
|
||||
{
|
||||
int status = read(command);
|
||||
if (status != INTERP_OK) {
|
||||
if (status > INTERP_MIN_ERROR) {
|
||||
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
if (_setup.line_length != 0) {
|
||||
status = execute_block(&EXECUTING_BLOCK(_setup), &_setup);
|
||||
if (status > INTERP_MIN_ERROR) {
|
||||
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int Interp::execute() { return execute(nullptr); }
|
||||
|
||||
int Interp::execute(const char *command, int line_number)
|
||||
{
|
||||
if (command && line_number) {
|
||||
_setup.sequence_number = line_number;
|
||||
}
|
||||
int status = execute(command);
|
||||
if ((_setup.call_level == 0) &&
|
||||
(status == INTERP_EXECUTE_FINISH) &&
|
||||
(_setup.mdi_interrupt)) {
|
||||
_setup.mdi_interrupt = false;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
int Interp::exit() { return INTERP_OK; }
|
||||
int Interp::init() { return INTERP_OK; }
|
||||
void Interp::set_loop_on_main_m99(bool state) { _setup.loop_on_main_m99 = state; }
|
||||
int Interp::open(const char *) { return INTERP_ERROR; }
|
||||
|
||||
int Interp::read_inputs(setup_pointer)
|
||||
{
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int Interp::_read(const char *command)
|
||||
{
|
||||
int read_status = INTERP_OK;
|
||||
block_pointer eblock = &EXECUTING_BLOCK(_setup);
|
||||
|
||||
if ((_setup.call_state > CS_NORMAL) &&
|
||||
(eblock->call_type != CT_NGC_OWORD_SUB) &&
|
||||
(eblock->call_type != CT_NGC_M98_SUB) &&
|
||||
(eblock->call_type != CT_NONE) &&
|
||||
((eblock->o_type == O_call) ||
|
||||
(eblock->o_type == M_98) ||
|
||||
(eblock->o_type == O_return) ||
|
||||
(eblock->o_type == O_endsub) ||
|
||||
(eblock->o_type == M_99))) {
|
||||
_setup.line_length = 0;
|
||||
_setup.linetext[0] = 0;
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
_setup.call_state = CS_NORMAL;
|
||||
if (read_inputs(&_setup) != INTERP_OK) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
|
||||
if ((command == nullptr) && (_setup.file_pointer == nullptr)) {
|
||||
return INTERP_FILE_NOT_OPEN;
|
||||
}
|
||||
|
||||
_setup.parameters[5420] = _setup.current_x;
|
||||
_setup.parameters[5421] = _setup.current_y;
|
||||
_setup.parameters[5422] = _setup.current_z;
|
||||
_setup.parameters[5423] = _setup.AA_current;
|
||||
_setup.parameters[5424] = _setup.BB_current;
|
||||
_setup.parameters[5425] = _setup.CC_current;
|
||||
_setup.parameters[5426] = _setup.u_current;
|
||||
_setup.parameters[5427] = _setup.v_current;
|
||||
_setup.parameters[5428] = _setup.w_current;
|
||||
|
||||
if (_setup.file_pointer) {
|
||||
EXECUTING_BLOCK(_setup).offset = ftell(_setup.file_pointer);
|
||||
}
|
||||
|
||||
read_status = read_text(command, _setup.file_pointer, _setup.linetext,
|
||||
_setup.blocktext, &_setup.line_length);
|
||||
|
||||
if ((read_status == INTERP_EXECUTE_FINISH) || (read_status == INTERP_OK)) {
|
||||
if (_setup.line_length != 0) {
|
||||
if (parse_line(_setup.blocktext, &(EXECUTING_BLOCK(_setup)), &_setup) != INTERP_OK) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (EXECUTING_BLOCK(_setup).o_type != O_none) {
|
||||
EXECUTING_BLOCK(_setup).o_type = 0;
|
||||
}
|
||||
}
|
||||
} else if (read_status == INTERP_ENDFILE) {
|
||||
if (_setup.skipping_o != nullptr) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
} else {
|
||||
return read_status;
|
||||
}
|
||||
|
||||
return read_status;
|
||||
}
|
||||
|
||||
int Interp::read(const char *command)
|
||||
{
|
||||
int status = _read(command);
|
||||
if (status > INTERP_MIN_ERROR) {
|
||||
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int Interp::read()
|
||||
{
|
||||
return read(nullptr);
|
||||
}
|
||||
|
||||
int Interp::reset() { return INTERP_OK; }
|
||||
int Interp::synch() { return INTERP_OK; }
|
||||
void Interp::active_g_codes(int *codes) { std::memcpy(codes, _setup.active_g_codes, sizeof(_setup.active_g_codes)); }
|
||||
void Interp::active_m_codes(int *codes) { std::memcpy(codes, _setup.active_m_codes, sizeof(_setup.active_m_codes)); }
|
||||
void Interp::active_settings(double *settings) { std::memcpy(settings, _setup.active_settings, sizeof(_setup.active_settings)); }
|
||||
int Interp::active_modes(int *, int *, double *, StateTag const &) { return INTERP_ERROR; }
|
||||
void Interp::print_state_tag(StateTag const &) {}
|
||||
char *Interp::error_text(int, char *buf, size_t max_size)
|
||||
{
|
||||
if (max_size) buf[0] = '\0';
|
||||
return buf;
|
||||
}
|
||||
char *Interp::file_name(char *buf, size_t max_size)
|
||||
{
|
||||
if (max_size) {
|
||||
std::strncpy(buf, _setup.filename, max_size - 1);
|
||||
buf[max_size - 1] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
size_t Interp::line_length() { return static_cast<size_t>(_setup.line_length); }
|
||||
char *Interp::line_text(char *buf, size_t max_size)
|
||||
{
|
||||
if (max_size) {
|
||||
std::strncpy(buf, _setup.linetext, max_size - 1);
|
||||
buf[max_size - 1] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
int Interp::sequence_number() { return _setup.sequence_number; }
|
||||
char *Interp::stack_name(int idx, char *buf, size_t max_size)
|
||||
{
|
||||
if (!max_size) return buf;
|
||||
if (idx < 0 || idx >= STACK_LEN) {
|
||||
buf[0] = '\0';
|
||||
return buf;
|
||||
}
|
||||
std::strncpy(buf, _setup.stack[idx], max_size - 1);
|
||||
buf[max_size - 1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
int Interp::ini_load(const char *) { return INTERP_OK; }
|
||||
int Interp::on_abort(int, const char *) { return INTERP_OK; }
|
||||
void Interp::set_loglevel(int level) { _setup.loggingLevel = level; }
|
||||
|
||||
int Interp::find_remappings(block_pointer, setup_pointer) { return 0; }
|
||||
|
||||
int Interp::load_tool_table() { return INTERP_OK; }
|
||||
int Interp::init_tool_parameters() { return INTERP_OK; }
|
||||
int Interp::default_tool_parameters() { return INTERP_OK; }
|
||||
int Interp::set_tool_parameters() { return INTERP_OK; }
|
||||
bool Interp::is_pycallable(setup_pointer, const char *, const char *) { return false; }
|
||||
bool Interp::is_user_defined_g_code(int) { return false; }
|
||||
bool Interp::is_any_m_code_remapped(block_pointer, setup_pointer) { return false; }
|
||||
bool Interp::is_user_defined_m_code(block_pointer, setup_pointer, int) { return false; }
|
||||
void Interp::loop_to_beginning(setup_pointer) {}
|
||||
int Interp::convert_control_functions(block_pointer, setup_pointer) { return INTERP_OK; }
|
||||
int Interp::convert_remapped_code(block_pointer, setup_pointer, int, char, int) { return INTERP_ERROR; }
|
||||
int Interp::py_execute(const char *, bool) { return INTERP_OK; }
|
||||
int Interp::py_reload() { return INTERP_OK; }
|
||||
|
||||
const char *o_ops[] = {
|
||||
"O_none", "O_sub", "O_endsub", "O_call", "O_do", "O_while", "O_if",
|
||||
"O_elseif", "O_else", "O_endif", "O_break", "O_continue",
|
||||
"O_endwhile", "O_return", "O_repeat", "O_endrepeat", "M_98", "M_99", "O_"
|
||||
};
|
||||
|
||||
int Interp::read_named_parameter(char *, int *, double *double_ptr, double *, bool check_exists)
|
||||
{
|
||||
if (check_exists) {
|
||||
*double_ptr = 0.0;
|
||||
}
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
|
||||
int Interp::find_named_param(const char *, int *status, double *value)
|
||||
{
|
||||
*status = 0;
|
||||
*value = 0.0;
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int Interp::store_named_param(setup_pointer, const char *, double, int)
|
||||
{
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
|
||||
int Interp::add_named_param(const char *, int)
|
||||
{
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
@@ -4,338 +4,104 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "config.h"
|
||||
#include "emc/ini/inifile.hh"
|
||||
#include "linuxcnc_hal_adapter.hh"
|
||||
|
||||
namespace {
|
||||
|
||||
enum predefined_named_parameters {
|
||||
NP_LINE,
|
||||
NP_MOTION_MODE,
|
||||
NP_PLANE,
|
||||
NP_CCOMP,
|
||||
NP_METRIC,
|
||||
NP_IMPERIAL,
|
||||
NP_ABSOLUTE,
|
||||
NP_INCREMENTAL,
|
||||
NP_INVERSE_TIME,
|
||||
NP_UNITS_PER_MINUTE,
|
||||
NP_UNITS_PER_REV,
|
||||
NP_COORD_SYSTEM,
|
||||
NP_TOOL_OFFSET,
|
||||
NP_RETRACT_R_PLANE,
|
||||
NP_RETRACT_OLD_Z,
|
||||
NP_SPINDLE_RPM_MODE,
|
||||
NP_SPINDLE_CSS_MODE,
|
||||
NP_IJK_ABSOLUTE_MODE,
|
||||
NP_LATHE_DIAMETER_MODE,
|
||||
NP_LATHE_RADIUS_MODE,
|
||||
NP_SPINDLE_ON,
|
||||
NP_SPINDLE_CW,
|
||||
NP_MIST,
|
||||
NP_FLOOD,
|
||||
NP_SPEED_OVERRIDE,
|
||||
NP_FEED_OVERRIDE,
|
||||
NP_ADAPTIVE_FEED,
|
||||
NP_FEED_HOLD,
|
||||
NP_FEED,
|
||||
NP_RPM,
|
||||
NP_CURRENT_TOOL,
|
||||
NP_SELECTED_POCKET,
|
||||
NP_CURRENT_POCKET,
|
||||
NP_X,
|
||||
NP_Y,
|
||||
NP_Z,
|
||||
NP_A,
|
||||
NP_B,
|
||||
NP_C,
|
||||
NP_U,
|
||||
NP_V,
|
||||
NP_W,
|
||||
NP_ABS_X,
|
||||
NP_ABS_Y,
|
||||
NP_ABS_Z,
|
||||
NP_ABS_A,
|
||||
NP_ABS_B,
|
||||
NP_ABS_C,
|
||||
NP_VALUE,
|
||||
NP_CALL_LEVEL,
|
||||
NP_REMAP_LEVEL,
|
||||
NP_SELECTED_TOOL,
|
||||
NP_VALUE_RETURNED,
|
||||
NP_TASK,
|
||||
};
|
||||
void seed_hal_values()
|
||||
{
|
||||
standalone::reset_hal_adapter();
|
||||
|
||||
struct NamedParamRuntime {
|
||||
setup state;
|
||||
hal_data_u pin_bit{};
|
||||
pin_bit.b = true;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-bit", HAL_BIT,
|
||||
pin_bit);
|
||||
|
||||
int fetch_ini_param(const char *nameBuf, int *status, double *value) {
|
||||
*status = 0;
|
||||
const int n = static_cast<int>(strlen(nameBuf));
|
||||
if (n < 8) {
|
||||
return INTERP_OK;
|
||||
}
|
||||
hal_data_u signal_float{};
|
||||
signal_float.f = 98.25;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-float",
|
||||
HAL_FLOAT, signal_float);
|
||||
|
||||
std::string sect = nameBuf + 5;
|
||||
for (auto &c : sect) {
|
||||
c = static_cast<char>(toupper(c));
|
||||
}
|
||||
const size_t i = sect.find(']');
|
||||
if (i == std::string::npos) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
std::string var = sect.substr(i + 1);
|
||||
sect.erase(i);
|
||||
hal_data_u param_s32{};
|
||||
param_s32.s = -17;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-s32", HAL_S32,
|
||||
param_s32);
|
||||
|
||||
const char *iniFileName = getenv("INI_FILE_NAME");
|
||||
if (!iniFileName) {
|
||||
return INTERP_OK;
|
||||
}
|
||||
linuxcnc::IniFile inifile(iniFileName);
|
||||
if (!inifile) {
|
||||
return INTERP_OK;
|
||||
}
|
||||
hal_data_u pin_u32{};
|
||||
pin_u32.u = 123456789u;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-u32", HAL_U32,
|
||||
pin_u32);
|
||||
|
||||
if (auto inival = inifile.findReal(var, sect)) {
|
||||
*value = *inival;
|
||||
*status = 1;
|
||||
}
|
||||
return INTERP_OK;
|
||||
}
|
||||
hal_data_u signal_s64{};
|
||||
signal_s64.ls = -9000000000LL;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-s64", HAL_S64,
|
||||
signal_s64);
|
||||
|
||||
int lookup_named_param(const char *nameBuf, double index, double *value) {
|
||||
const int cmd = round_to_int(index);
|
||||
switch (cmd) {
|
||||
case NP_LINE:
|
||||
*value = state.sequence_number;
|
||||
break;
|
||||
case NP_MOTION_MODE:
|
||||
*value = state.motion_mode;
|
||||
break;
|
||||
case NP_METRIC:
|
||||
*value = (state.length_units == CANON_UNITS_MM);
|
||||
break;
|
||||
case NP_IMPERIAL:
|
||||
*value = (state.length_units == CANON_UNITS_INCHES);
|
||||
break;
|
||||
case NP_ABSOLUTE:
|
||||
*value = (state.distance_mode == DISTANCE_MODE::ABSOLUTE);
|
||||
break;
|
||||
case NP_INCREMENTAL:
|
||||
*value = (state.distance_mode == DISTANCE_MODE::INCREMENTAL);
|
||||
break;
|
||||
case NP_FEED:
|
||||
*value = state.feed_rate;
|
||||
break;
|
||||
case NP_RPM:
|
||||
*value = state.speed[0];
|
||||
break;
|
||||
case NP_X:
|
||||
*value = state.current_x;
|
||||
break;
|
||||
case NP_Y:
|
||||
*value = state.current_y;
|
||||
break;
|
||||
case NP_Z:
|
||||
*value = state.current_z;
|
||||
break;
|
||||
case NP_CURRENT_TOOL:
|
||||
*value = state.parameters[interp_param_global::TOOL_NUMBER];
|
||||
break;
|
||||
case NP_CALL_LEVEL:
|
||||
*value = state.call_level;
|
||||
break;
|
||||
default:
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
return INTERP_OK;
|
||||
}
|
||||
hal_data_u param_u64{};
|
||||
param_u64.lu = 9000000000ULL;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-u64", HAL_U64,
|
||||
param_u64);
|
||||
|
||||
int find_named_param(const char *nameBuf, int *status, double *value) {
|
||||
const int level = (nameBuf[0] == '_') ? 0 : state.call_level;
|
||||
context_pointer frame = &state.sub_context[level];
|
||||
*status = 0;
|
||||
hal_data_u disconnected{};
|
||||
disconnected.f = 12.5;
|
||||
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.disconnected-float",
|
||||
HAL_FLOAT, disconnected, false);
|
||||
}
|
||||
|
||||
auto pi = frame->named_params.find(nameBuf);
|
||||
if (pi == frame->named_params.end()) {
|
||||
int exists = 0;
|
||||
double inivalue = 0.0;
|
||||
if ((state.feature_set & FEATURE_INI_VARS) && (strncasecmp(nameBuf, "_ini[", 5) == 0)) {
|
||||
fetch_ini_param(nameBuf, &exists, &inivalue);
|
||||
if (exists) {
|
||||
*value = inivalue;
|
||||
*status = 1;
|
||||
parameter_value param;
|
||||
param.value = inivalue;
|
||||
param.attr = PA_GLOBAL | PA_READONLY | PA_FROM_INI;
|
||||
state.sub_context[0].named_params[strstore(nameBuf)] = param;
|
||||
return INTERP_OK;
|
||||
}
|
||||
}
|
||||
*value = 0.0;
|
||||
*status = 0;
|
||||
} else {
|
||||
parameter_pointer pv = &pi->second;
|
||||
if (pv->attr & PA_USE_LOOKUP) {
|
||||
if (lookup_named_param(nameBuf, pv->value, value) != INTERP_OK) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
*status = 1;
|
||||
} else {
|
||||
*value = pv->value;
|
||||
*status = 1;
|
||||
}
|
||||
}
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int store_named_param(const char *nameBuf, double value, bool override_readonly) {
|
||||
const int level = (nameBuf[0] == '_') ? 0 : state.call_level;
|
||||
context_pointer frame = &state.sub_context[level];
|
||||
auto pi = frame->named_params.find(nameBuf);
|
||||
if (pi == frame->named_params.end()) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
parameter_pointer pv = &pi->second;
|
||||
if ((pv->attr & PA_READONLY) && !override_readonly) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
pv->value = value;
|
||||
pv->attr &= ~PA_UNSET;
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int add_named_param(const char *nameBuf, int attr) {
|
||||
int findStatus = 0;
|
||||
double value = 0.0;
|
||||
find_named_param(nameBuf, &findStatus, &value);
|
||||
if (findStatus) {
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int level = 0;
|
||||
if (nameBuf[0] != '_') {
|
||||
level = state.call_level;
|
||||
} else {
|
||||
level = 0;
|
||||
attr |= PA_GLOBAL;
|
||||
}
|
||||
attr |= PA_UNSET;
|
||||
|
||||
parameter_value param;
|
||||
param.value = 0.0;
|
||||
param.attr = attr;
|
||||
state.sub_context[level].named_params[strstore(nameBuf)] = param;
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
int init_readonly_param(const char *nameBuf, double value, int attr) {
|
||||
if (add_named_param(nameBuf, PA_READONLY | attr) != INTERP_OK) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
if (store_named_param(nameBuf, value, true) != INTERP_OK) {
|
||||
return INTERP_ERROR;
|
||||
}
|
||||
return INTERP_OK;
|
||||
}
|
||||
|
||||
double inicheck() {
|
||||
const char *filename = getenv("INI_FILE_NAME");
|
||||
if (!filename) {
|
||||
return -1.0;
|
||||
}
|
||||
linuxcnc::IniFile inifile(filename);
|
||||
if (!inifile) {
|
||||
return -1.0;
|
||||
}
|
||||
if (auto inistring = inifile.findString("LINEAR_UNITS", "TRAJ")) {
|
||||
if ((strcasecmp("mm", inistring->c_str()) == 0) ||
|
||||
(strcasecmp("metric", inistring->c_str()) == 0)) {
|
||||
return 1.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
int init_named_parameters() {
|
||||
const char *pkgversion = PACKAGE_VERSION;
|
||||
const char *version_major = "_vmajor";
|
||||
const char *version_minor = "_vminor";
|
||||
const char *metric_machine = "_metric_machine";
|
||||
double vmajor = 0.0;
|
||||
double vminor = 0.0;
|
||||
double munits = 1.0;
|
||||
sscanf(pkgversion, "%lf%lf", &vmajor, &vminor);
|
||||
|
||||
if (init_readonly_param(version_major, vmajor, 0) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param(version_minor, vminor, 0) != INTERP_OK) return INTERP_ERROR;
|
||||
|
||||
munits = inicheck();
|
||||
if (init_readonly_param(metric_machine, munits, 0) != INTERP_OK) return INTERP_ERROR;
|
||||
|
||||
if (init_readonly_param("_line", NP_LINE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_motion_mode", NP_MOTION_MODE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_metric", NP_METRIC, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_imperial", NP_IMPERIAL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_absolute", NP_ABSOLUTE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_incremental", NP_INCREMENTAL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_feed", NP_FEED, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_rpm", NP_RPM, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_x", NP_X, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_y", NP_Y, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_z", NP_Z, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_current_tool", NP_CURRENT_TOOL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
if (init_readonly_param("_call_level", NP_CALL_LEVEL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
|
||||
|
||||
return INTERP_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void print_named_value(NamedParamRuntime &runtime, const char *name) {
|
||||
void print_named_value(Interp &interp, const char *name)
|
||||
{
|
||||
int status = 0;
|
||||
double value = 0.0;
|
||||
const int rc = runtime.find_named_param(name, &status, &value);
|
||||
const int rc = interp.find_named_param(name, &status, &value);
|
||||
std::cout << name << ": rc=" << rc << " found=" << status << " value=" << value << "\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
setenv("INI_FILE_NAME", argv[1], 1);
|
||||
}
|
||||
|
||||
NamedParamRuntime runtime;
|
||||
runtime.state.feature_set = FEATURE_INI_VARS;
|
||||
runtime.state.length_units = CANON_UNITS_MM;
|
||||
runtime.state.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
runtime.state.motion_mode = G_1;
|
||||
runtime.state.feed_rate = 123.45;
|
||||
runtime.state.speed[0] = 678.9;
|
||||
runtime.state.current_x = 1.25;
|
||||
runtime.state.current_y = 2.5;
|
||||
runtime.state.current_z = 3.75;
|
||||
runtime.state.parameters[interp_param_global::TOOL_NUMBER] = 12.0;
|
||||
Interp interp;
|
||||
seed_hal_values();
|
||||
interp._setup.feature_set = FEATURE_INI_VARS | FEATURE_HAL_PIN_VARS;
|
||||
interp._setup.length_units = CANON_UNITS_MM;
|
||||
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.motion_mode = G_1;
|
||||
interp._setup.feed_rate = 123.45;
|
||||
interp._setup.speed[0] = 678.9;
|
||||
interp._setup.current_x = 1.25;
|
||||
interp._setup.current_y = 2.5;
|
||||
interp._setup.current_z = 3.75;
|
||||
interp._setup.parameters[interp_param_global::TOOL_NUMBER] = 12.0;
|
||||
|
||||
const int rc = runtime.init_named_parameters();
|
||||
const int rc = interp.init_named_parameters();
|
||||
std::cout << "init_named_parameters=" << rc << "\n";
|
||||
std::cout << "global_named_count=" << runtime.state.sub_context[0].named_params.size() << "\n";
|
||||
std::cout << "global_named_count=" << interp._setup.sub_context[0].named_params.size() << "\n";
|
||||
std::cout << "required_parameter_first=" << interp_param_global::G28_X << "\n";
|
||||
std::cout << "readonly_tool_number_index=" << interp_param_global::TOOL_NUMBER << "\n";
|
||||
|
||||
print_named_value(runtime, "_vmajor");
|
||||
print_named_value(runtime, "_vminor");
|
||||
print_named_value(runtime, "_metric_machine");
|
||||
print_named_value(runtime, "_motion_mode");
|
||||
print_named_value(runtime, "_metric");
|
||||
print_named_value(runtime, "_feed");
|
||||
print_named_value(runtime, "_rpm");
|
||||
print_named_value(runtime, "_x");
|
||||
print_named_value(runtime, "_current_tool");
|
||||
print_named_value(runtime, "_ini[traj]max_linear_velocity");
|
||||
print_named_value(interp, "_vmajor");
|
||||
print_named_value(interp, "_vminor");
|
||||
print_named_value(interp, "_metric_machine");
|
||||
print_named_value(interp, "_motion_mode");
|
||||
print_named_value(interp, "_metric");
|
||||
print_named_value(interp, "_feed");
|
||||
print_named_value(interp, "_rpm");
|
||||
print_named_value(interp, "_x");
|
||||
print_named_value(interp, "_current_tool");
|
||||
print_named_value(interp, "_ini[traj]max_linear_velocity");
|
||||
print_named_value(interp, "_hal[standalone.pin-bit]");
|
||||
print_named_value(interp, "_hal[standalone.signal-float]");
|
||||
print_named_value(interp, "_hal[standalone.param-s32]");
|
||||
print_named_value(interp, "_hal[standalone.pin-u32]");
|
||||
print_named_value(interp, "_hal[standalone.signal-s64]");
|
||||
print_named_value(interp, "_hal[standalone.param-u64]");
|
||||
print_named_value(interp, "_hal[standalone.disconnected-float]");
|
||||
print_named_value(interp, "_hal[standalone.missing]");
|
||||
|
||||
return rc == INTERP_OK ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#include <unordered_set>
|
||||
|
||||
#include "emc/rs274ngc/interp_internal.hh"
|
||||
|
||||
struct pycontext_impl {};
|
||||
#include "interp_python.hh"
|
||||
|
||||
pycontext::pycontext() : impl(new pycontext_impl) {}
|
||||
pycontext::~pycontext() { delete impl; }
|
||||
@@ -20,6 +19,7 @@ pycontext &pycontext::operator=(const pycontext &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef LINUXCNC_STANDALONE_USE_RS274_PRE_STATE
|
||||
const char *strstore(const char *s)
|
||||
{
|
||||
static std::unordered_set<std::string> stringtable;
|
||||
@@ -45,6 +45,7 @@ void context_struct::clear()
|
||||
{
|
||||
new (this) context_struct();
|
||||
}
|
||||
#endif
|
||||
|
||||
setup::setup()
|
||||
: AA_axis_offset(0.0),
|
||||
|
||||
101
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tool_adapter.cpp
Normal file
101
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tool_adapter.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "linuxcnc_tool_adapter.hh"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace {
|
||||
|
||||
std::array<CANON_TOOL_TABLE, CANON_POCKETS_MAX> &tool_table()
|
||||
{
|
||||
static std::array<CANON_TOOL_TABLE, CANON_POCKETS_MAX> tools{};
|
||||
return tools;
|
||||
}
|
||||
|
||||
int &selected_tool_index()
|
||||
{
|
||||
static int index = -1;
|
||||
return index;
|
||||
}
|
||||
|
||||
CANON_TOOL_TABLE empty_tool()
|
||||
{
|
||||
CANON_TOOL_TABLE tool{};
|
||||
tool.toolno = 0;
|
||||
tool.pocketno = 0;
|
||||
return tool;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace standalone {
|
||||
|
||||
void reset_tool_adapter()
|
||||
{
|
||||
selected_tool_index() = -1;
|
||||
auto &tools = tool_table();
|
||||
for (int index = 0; index < CANON_POCKETS_MAX; ++index) {
|
||||
tools[index] = empty_tool();
|
||||
tools[index].pocketno = index;
|
||||
}
|
||||
tools[0].pocketno = 0;
|
||||
}
|
||||
|
||||
void set_tool_entry(int index, const CANON_TOOL_TABLE &tool)
|
||||
{
|
||||
if ((index < 0) || (index >= CANON_POCKETS_MAX)) {
|
||||
return;
|
||||
}
|
||||
tool_table()[index] = tool;
|
||||
}
|
||||
|
||||
CANON_TOOL_TABLE tool_entry_init()
|
||||
{
|
||||
return empty_tool();
|
||||
}
|
||||
|
||||
int find_tool_index_for_tool(int toolno)
|
||||
{
|
||||
if (toolno == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto &tools = tool_table();
|
||||
for (int index = 0; index < CANON_POCKETS_MAX; ++index) {
|
||||
if (tools[index].toolno == toolno) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_tool_entry(CANON_TOOL_TABLE *tool, int index)
|
||||
{
|
||||
if ((tool == nullptr) || (index < 0) || (index >= CANON_POCKETS_MAX)) {
|
||||
return -1;
|
||||
}
|
||||
*tool = tool_table()[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void select_tool(int toolno)
|
||||
{
|
||||
selected_tool_index() = find_tool_index_for_tool(toolno);
|
||||
}
|
||||
|
||||
void change_tool_number(int index)
|
||||
{
|
||||
if ((index < 0) || (index >= CANON_POCKETS_MAX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &tools = tool_table();
|
||||
CANON_TOOL_TABLE spindle_tool = tools[index];
|
||||
spindle_tool.pocketno = 0;
|
||||
tools[0] = spindle_tool;
|
||||
}
|
||||
|
||||
void change_selected_tool()
|
||||
{
|
||||
change_tool_number(selected_tool_index());
|
||||
}
|
||||
|
||||
} // namespace standalone
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "emc/nml_intf/emctool.h"
|
||||
|
||||
namespace standalone {
|
||||
|
||||
void reset_tool_adapter();
|
||||
void set_tool_entry(int index, const CANON_TOOL_TABLE &tool);
|
||||
CANON_TOOL_TABLE tool_entry_init();
|
||||
int find_tool_index_for_tool(int toolno);
|
||||
int get_tool_entry(CANON_TOOL_TABLE *tool, int index);
|
||||
void select_tool(int toolno);
|
||||
void change_selected_tool();
|
||||
void change_tool_number(int index);
|
||||
|
||||
} // namespace standalone
|
||||
3
wasm-port/runtime/core/shims/boost/python/dict.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/dict.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
3
wasm-port/runtime/core/shims/boost/python/extract.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/extract.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
3
wasm-port/runtime/core/shims/boost/python/import.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/import.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
3
wasm-port/runtime/core/shims/boost/python/list.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/list.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
@@ -1,9 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct _typeobject {
|
||||
const char *tp_name = "standalone-python-shim";
|
||||
};
|
||||
|
||||
struct _object {
|
||||
_typeobject *ob_type = nullptr;
|
||||
};
|
||||
typedef _object PyObject;
|
||||
|
||||
inline int PyCallable_Check(PyObject *) { return 0; }
|
||||
inline int PyErr_ExceptionMatches(PyObject *) { return 0; }
|
||||
inline void PyErr_Clear() {}
|
||||
inline int PyUnicode_Check(PyObject *) { return 0; }
|
||||
inline int PyLong_Check(PyObject *) { return 0; }
|
||||
inline int PyFloat_Check(PyObject *) { return 0; }
|
||||
inline PyObject *PyObject_Str(PyObject *) { return nullptr; }
|
||||
inline void Py_XDECREF(PyObject *) {}
|
||||
inline const char *PyUnicode_AsUTF8(PyObject *) { return ""; }
|
||||
|
||||
inline PyObject *PyExc_KeyError = nullptr;
|
||||
inline PyObject *Py_None = nullptr;
|
||||
|
||||
namespace boost {
|
||||
namespace python {
|
||||
|
||||
class object {};
|
||||
class error_already_set {};
|
||||
|
||||
class object {
|
||||
public:
|
||||
object() = default;
|
||||
|
||||
template <typename T>
|
||||
explicit object(const T &) {}
|
||||
|
||||
object attr(const char *) const { return object(); }
|
||||
object operator[](const char *) const { return object(); }
|
||||
object operator[](const std::string &) const { return object(); }
|
||||
object operator[](int) const { return object(); }
|
||||
PyObject *ptr() const { return nullptr; }
|
||||
};
|
||||
|
||||
class list : public object {
|
||||
public:
|
||||
using object::object;
|
||||
list() = default;
|
||||
explicit list(const object &) {}
|
||||
|
||||
template <typename T>
|
||||
void append(const T &) {}
|
||||
};
|
||||
|
||||
class tuple : public object {
|
||||
public:
|
||||
tuple() = default;
|
||||
explicit tuple(const list &) {}
|
||||
};
|
||||
|
||||
class dict : public object {
|
||||
public:
|
||||
object keys() const { return object(); }
|
||||
};
|
||||
|
||||
class scope {
|
||||
public:
|
||||
explicit scope(const object &) {}
|
||||
object attr(const char *) const { return object(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
object import(const T &) { return object(); }
|
||||
|
||||
template <typename T>
|
||||
class extract {
|
||||
public:
|
||||
explicit extract(const object &) {}
|
||||
|
||||
operator T() const { return T(); }
|
||||
};
|
||||
|
||||
inline int len(const object &) { return 0; }
|
||||
inline void handle_exception() {}
|
||||
|
||||
} // namespace python
|
||||
} // namespace boost
|
||||
|
||||
3
wasm-port/runtime/core/shims/boost/python/scope.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/scope.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
3
wasm-port/runtime/core/shims/boost/python/tuple.hpp
Normal file
3
wasm-port/runtime/core/shims/boost/python/tuple.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
30
wasm-port/runtime/core/shims/hal.h
Normal file
30
wasm-port/runtime/core/shims/hal.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define HAL_NAME_LEN 64
|
||||
|
||||
typedef enum {
|
||||
HAL_TYPE_UNINITIALIZED = 0,
|
||||
HAL_BIT,
|
||||
HAL_FLOAT,
|
||||
HAL_S32,
|
||||
HAL_U32,
|
||||
HAL_S64,
|
||||
HAL_U64
|
||||
} hal_type_t;
|
||||
|
||||
typedef union {
|
||||
bool b;
|
||||
double f;
|
||||
int s;
|
||||
unsigned int u;
|
||||
long long ls;
|
||||
unsigned long long lu;
|
||||
} hal_data_u;
|
||||
|
||||
int hal_init(const char *);
|
||||
int hal_ready(int);
|
||||
int hal_get_pin_value_by_name(const char *, hal_type_t *, hal_data_u **, bool *);
|
||||
int hal_get_signal_value_by_name(const char *, hal_type_t *, hal_data_u **, bool *);
|
||||
int hal_get_param_value_by_name(const char *, hal_type_t *, hal_data_u **);
|
||||
16
wasm-port/runtime/core/shims/interp_python.hh
Normal file
16
wasm-port/runtime/core/shims/interp_python.hh
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
|
||||
struct pycontext_impl {
|
||||
boost::python::object tupleargs;
|
||||
boost::python::object kwargs;
|
||||
int py_return_type = 0;
|
||||
double py_returned_double = 0.0;
|
||||
int py_returned_int = 0;
|
||||
boost::python::object generator_next;
|
||||
};
|
||||
|
||||
std::string handle_pyerror();
|
||||
@@ -2,12 +2,37 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "boost/python/object_fwd.hpp"
|
||||
|
||||
enum pp_status {
|
||||
PLUGIN_NO_SECTION = -1,
|
||||
PLUGIN_OK = 0,
|
||||
PLUGIN_NO_CALLABLE = 1,
|
||||
PLUGIN_EXCEPTION = 2
|
||||
};
|
||||
|
||||
std::string handle_pyerror();
|
||||
|
||||
class PythonPlugin {
|
||||
public:
|
||||
static PythonPlugin *instantiate(struct _inittab * = nullptr);
|
||||
int configure(const char * = nullptr, const char * = nullptr) { return PLUGIN_NO_SECTION; }
|
||||
bool is_callable(const char *, const char *) { return false; }
|
||||
int call(const char *, const char *, boost::python::object, boost::python::object,
|
||||
boost::python::object &) { return PLUGIN_NO_CALLABLE; }
|
||||
int run_string(const char *, boost::python::object &, bool = false) { return PLUGIN_NO_CALLABLE; }
|
||||
int call_method(boost::python::object, boost::python::object &) { return PLUGIN_NO_CALLABLE; }
|
||||
int plugin_status() const { return PLUGIN_NO_SECTION; }
|
||||
bool usable() const { return false; }
|
||||
int plugin_status() const { return 0; }
|
||||
int initialize() { return PLUGIN_NO_SECTION; }
|
||||
const std::string &last_exception() const {
|
||||
static std::string empty;
|
||||
return empty;
|
||||
}
|
||||
const std::string &last_errmsg() const {
|
||||
static std::string empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
boost::python::object main_namespace;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "emc/nml_intf/emctool.h"
|
||||
#include "linuxcnc_tool_adapter.hh"
|
||||
|
||||
enum {
|
||||
IDX_OK = 0,
|
||||
@@ -8,22 +9,15 @@ enum {
|
||||
|
||||
inline CANON_TOOL_TABLE tooldata_entry_init()
|
||||
{
|
||||
CANON_TOOL_TABLE tool{};
|
||||
tool.toolno = 0;
|
||||
tool.pocketno = 0;
|
||||
return tool;
|
||||
return standalone::tool_entry_init();
|
||||
}
|
||||
|
||||
inline int tooldata_find_index_for_tool(int toolno)
|
||||
{
|
||||
return toolno == 0 ? 0 : -1;
|
||||
return standalone::find_tool_index_for_tool(toolno);
|
||||
}
|
||||
|
||||
inline int tooldata_get(CANON_TOOL_TABLE *tool, int index)
|
||||
{
|
||||
if ((tool == nullptr) || (index != 0)) {
|
||||
return -1;
|
||||
}
|
||||
*tool = tooldata_entry_init();
|
||||
return IDX_OK;
|
||||
return standalone::get_tool_entry(tool, index) == 0 ? IDX_OK : -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user