接续上一轮:推进浏览器验证与M428配置收拢

结论:已完成浏览器侧真实加载验证,M428/M429/M430 的配置入口进一步从 LinuxCNC INI/HALFILE/REMAP 来源生成,native 与 source-link 验证通过。
This commit is contained in:
cnc
2026-05-30 10:03:21 +08:00
parent b40914747d
commit de273bf830
141 changed files with 11255 additions and 1259 deletions

View File

@@ -88,6 +88,13 @@ void CanonEventSink::configure_fiveaxis(double pivot_length, int kinematics_type
fiveaxis_kinematics_type_ = kinematics_type;
}
void CanonEventSink::configure_switchkins_remap(int m428_type, int m429_type, int m430_type) {
switchkins_remap_configured_ = true;
switchkins_m428_type_ = m428_type;
switchkins_m429_type_ = m429_type;
switchkins_m430_type_ = m430_type;
}
void CanonEventSink::set_tool_length(int h_code, double tool_length) {
if (h_code <= 0) {
default_rtcp_tool_length_ = tool_length;
@@ -151,24 +158,59 @@ void CanonEventSink::switch_kinematics(int kinematics_type, int line) {
emit(event);
}
void CanonEventSink::switch_m_code_kinematics(int m_code, int default_kinematics_type, int line) {
bool CanonEventSink::can_switch_m_code_kinematics(int m_code) const {
if (!switchkins_remap_configured_) {
return true;
}
if (m_code == 428) {
return switchkins_m428_type_ >= 0;
}
if (m_code == 429) {
return switchkins_m429_type_ >= 0;
}
if (m_code == 430) {
return switchkins_m430_type_ >= 0;
}
return true;
}
bool CanonEventSink::switch_m_code_kinematics(int m_code, int default_kinematics_type, int line) {
if (switchkins_remap_configured_) {
int kinematics_type = -1;
if (m_code == 428) {
kinematics_type = switchkins_m428_type_;
} else if (m_code == 429) {
kinematics_type = switchkins_m429_type_;
} else if (m_code == 430) {
kinematics_type = switchkins_m430_type_;
}
if (kinematics_type >= 0) {
switch_kinematics(kinematics_type, line);
return true;
}
return false;
}
if (fiveaxis_configured_) {
// Source: linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/{428,429,430}remap.ngc
// M428 selects 5axiskins type 0, M429 selects identity type 1, M430 selects userk type 2.
// Sources:
// - linuxcnc/configs/sim/axis/vismach/5axis/bridgemill/remap_subs/{428,429,430}remap.ngc
// - linuxcnc/configs/sim/axis/vismach/scara/remap_subs/{428,429,430}remap.ngc
// - linuxcnc/configs/sim/axis/vismach/melfa-sim/remap_subs/{428,429,430}remap.ngc
// These remaps select kinstype 0, 1, and 2 respectively.
if (m_code == 428) {
switch_kinematics(0, line);
return;
return true;
}
if (m_code == 429) {
switch_kinematics(1, line);
return;
return true;
}
if (m_code == 430) {
switch_kinematics(2, line);
return;
return true;
}
}
switch_kinematics(default_kinematics_type, line);
return true;
}
void CanonEventSink::set_g5x_offset(int index, const CncSimPose &offset, int line) {

View File

@@ -16,12 +16,14 @@ public:
void configure_xyzbc_trt(const LinuxCncXyzbcTrtParameters &parameters);
void configure_xyzac_trt(const LinuxCncXyzbcTrtParameters &parameters);
void configure_fiveaxis(double pivot_length, int kinematics_type);
void configure_switchkins_remap(int m428_type, int m429_type, int m430_type);
void set_tool_length(int h_code, double tool_length);
void set_tool_length_offset(const CncSimPose &offset);
void apply_tool_length_offset(const CncSimPose &offset);
void set_rtcp_state(bool enabled, int h_code, int line);
void switch_kinematics(int kinematics_type, int line);
void switch_m_code_kinematics(int m_code, int default_kinematics_type, int line);
bool can_switch_m_code_kinematics(int m_code) const;
bool switch_m_code_kinematics(int m_code, int default_kinematics_type, int line);
void set_g5x_offset(int index, const CncSimPose &offset, int line);
void set_g92_offset(const CncSimPose &offset, int line);
void set_xy_rotation(double angle_degrees, int line);
@@ -108,6 +110,10 @@ private:
bool fiveaxis_configured_ = false;
double fiveaxis_pivot_length_ = 250.0;
int fiveaxis_kinematics_type_ = 0;
bool switchkins_remap_configured_ = false;
int switchkins_m428_type_ = 1;
int switchkins_m429_type_ = 0;
int switchkins_m430_type_ = 2;
CncSimPose tool_length_offset_{};
double xy_rotation_degrees_ = 0.0;
int kinematics_type_ = 0;

View File

@@ -4,16 +4,13 @@
#include <algorithm>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <string>
struct CncSimHandle {
CncSimDialect dialect = CNC_SIM_DIALECT_LINUXCNC;
#ifdef CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND
GcodeBackendKind backend = GcodeBackendKind::LinuxCncRs274;
#else
GcodeBackendKind backend = GcodeBackendKind::Smoke;
#endif
std::string last_error;
CanonEventSink sink;
};
@@ -77,6 +74,40 @@ bool contains_bool_value(const std::string &compact, const char *key, bool *valu
return false;
}
bool contains_string_value(const std::string &compact, const char *key, const char *value) {
const std::string quoted_needle = std::string("\"") + key + "\":\"" + value + "\"";
if (compact.find(quoted_needle) != std::string::npos) {
return true;
}
const std::string prefix_needle = std::string("\"") + key + "\":\"";
size_t pos = 0;
while ((pos = compact.find(prefix_needle, pos)) != std::string::npos) {
pos += prefix_needle.size();
const size_t end = compact.find('"', pos);
if (end == std::string::npos) {
return false;
}
const std::string field_value = compact.substr(pos, end - pos);
if (field_value.find(value) != std::string::npos) {
return true;
}
pos = end + 1;
}
return false;
}
bool contains_switchkins_config_alias(const std::string &compact, const char *alias) {
return contains_string_value(compact, "switchkins", alias) ||
contains_string_value(compact, "remap", alias) ||
contains_string_value(compact, "machine", alias) ||
contains_string_value(compact, "kinematics", alias) ||
contains_string_value(compact, "halfile", alias) ||
contains_string_value(compact, "hal_file", alias) ||
contains_string_value(compact, "config", alias) ||
contains_string_value(compact, "configpath", alias) ||
contains_string_value(compact, "config_path", alias);
}
bool find_number_value(const std::string &compact, const char *key, double *value) {
const std::string needle = std::string("\"") + key + "\":";
const size_t pos = compact.find(needle);
@@ -212,6 +243,38 @@ void apply_fiveaxis_config(CanonEventSink &sink, const std::string &compact) {
}
}
void apply_switchkins_remap_config(CanonEventSink &sink, const std::string &compact) {
struct RemapSource {
const char *alias;
int m428_type;
int m429_type;
int m430_type;
};
// Generated from LinuxCNC INI REMAP/SUBROUTINE_PATH entries and the
// adjacent remap_subs #<kinstype> assignments.
static constexpr RemapSource kSources[] = {
#include "linuxcnc_switchkins_remap_table.inc"
};
const RemapSource *matched_source = nullptr;
size_t matched_alias_length = 0;
for (const RemapSource &source : kSources) {
if (contains_switchkins_config_alias(compact, source.alias)) {
const size_t alias_length = std::strlen(source.alias);
if (alias_length > matched_alias_length) {
matched_source = &source;
matched_alias_length = alias_length;
}
}
}
if (matched_source) {
sink.configure_switchkins_remap(matched_source->m428_type,
matched_source->m429_type,
matched_source->m430_type);
}
}
int apply_config(CncSimHandle *handle, const std::string &json) {
if (json.empty()) {
return 0;
@@ -242,6 +305,7 @@ int apply_config(CncSimHandle *handle, const std::string &json) {
handle->sink.set_block_delete(block_delete);
}
apply_tool_length_table(handle->sink, compact);
apply_switchkins_remap_config(handle->sink, compact);
apply_xyzbc_trt_config(handle->sink, compact);
apply_fiveaxis_config(handle->sink, compact);
return 0;

View File

@@ -3,7 +3,9 @@
#ifdef CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND
#include "linuxcnc_rs274_backend.h"
#endif
#ifdef CNC_SIM_ENABLE_SMOKE_BACKEND
#include "smoke_gcode_parser.h"
#endif
const char *gcode_backend_name(GcodeBackendKind backend) {
switch (backend) {
@@ -23,8 +25,15 @@ int parse_gcode_with_backend(GcodeBackendKind backend,
std::string *error) {
switch (backend) {
case GcodeBackendKind::Smoke: {
#ifdef CNC_SIM_ENABLE_SMOKE_BACKEND
SmokeGcodeParser parser(sink);
return parser.parse(program, program_len, error);
#else
if (error) {
*error = "smoke backend is not compiled into this build";
}
return -1;
#endif
}
case GcodeBackendKind::LinuxCncRs274:
#ifdef CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND

View File

@@ -0,0 +1,266 @@
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_RTAPI_CTYPE_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_KINEMATICS_H
#define SWITCHKINS_H
#define RTAPI_MSG_ERR 1
#define PM_PI 3.1415926535897932384626433832795029
#define TO_RAD (PM_PI / 180.0)
#define EMCMOT_MAX_JOINTS 16
#define EMCMOT_MAX_AXIS 9
typedef double real_t;
typedef double hal_float_t;
typedef int hal_s32_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
typedef int (*KF)(const double *joint,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
typedef int (*KI)(const struct EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
typedef int (*KS)(const int comp_id, const char *coordinates, kparms *ksetup_parms);
#ifdef __cplusplus
extern "C" {
#endif
static int cnc_sim_axis_idx_for_jno[EMCMOT_MAX_JOINTS];
static int cnc_sim_max_joints;
void cnc_sim_5axis_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_5axis_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_5axis_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_5axis_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_5axis_map_coordinates_to_jnumbers(const char *coordinates,
const int max_joints,
const int allow_duplicates,
int axis_idx_for_jno[]) {
(void)allow_duplicates;
const char *letters = "XYZABCUVW";
int jno = 0;
for (int i = 0; i < EMCMOT_MAX_JOINTS; ++i) {
axis_idx_for_jno[i] = -1;
cnc_sim_axis_idx_for_jno[i] = -1;
}
while (*coordinates) {
const char *found = strchr(letters, toupper((unsigned char)*coordinates));
if (!found || jno >= max_joints) {
return -1;
}
axis_idx_for_jno[jno++] = (int)(found - letters);
++coordinates;
}
cnc_sim_max_joints = jno;
for (int i = 0; i < EMCMOT_MAX_JOINTS; ++i) {
cnc_sim_axis_idx_for_jno[i] = axis_idx_for_jno[i];
}
return 0;
}
int cnc_sim_5axis_position_to_mapped_joints(const int max_joints, const EmcPose *pos, double *joints) {
for (int jno = 0; jno < max_joints; ++jno) {
switch (cnc_sim_axis_idx_for_jno[jno]) {
case 0: joints[jno] = pos->tran.x; break;
case 1: joints[jno] = pos->tran.y; break;
case 2: joints[jno] = pos->tran.z; break;
case 3: joints[jno] = pos->a; break;
case 4: joints[jno] = pos->b; break;
case 5: joints[jno] = pos->c; break;
case 6: joints[jno] = pos->u; break;
case 7: joints[jno] = pos->v; break;
case 8: joints[jno] = pos->w; break;
default: joints[jno] = 0.0; break;
}
}
return 0;
}
int cnc_sim_5axis_identityKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return 0;
}
int cnc_sim_5axis_identityKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_5axis_identityKinematicsInverse(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
int cnc_sim_5axis_userkKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return -1;
}
int cnc_sim_5axis_userkKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_5axis_userkKinematicsInverse(const EmcPose *pos,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)pos;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
#define rtapi_print cnc_sim_5axis_rtapi_print
#define rtapi_print_msg cnc_sim_5axis_rtapi_print_msg
#define hal_pin_float_newf cnc_sim_5axis_hal_pin_float_newf
#define map_coordinates_to_jnumbers cnc_sim_5axis_map_coordinates_to_jnumbers
#define position_to_mapped_joints cnc_sim_5axis_position_to_mapped_joints
#define identityKinematicsSetup cnc_sim_5axis_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_5axis_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_5axis_identityKinematicsInverse
#define userkKinematicsSetup cnc_sim_5axis_userkKinematicsSetup
#define userkKinematicsForward cnc_sim_5axis_userkKinematicsForward
#define userkKinematicsInverse cnc_sim_5axis_userkKinematicsInverse
#define switchkinsSetup cnc_sim_5axis_switchkinsSetup
#define haldata cnc_sim_5axis_haldata
#define hal_malloc(size) ((struct haldata *)cnc_sim_5axis_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/5axiskins.c"
#undef hal_malloc
#undef haldata
#undef switchkinsSetup
#undef userkKinematicsInverse
#undef userkKinematicsForward
#undef userkKinematicsSetup
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef position_to_mapped_joints
#undef map_coordinates_to_jnumbers
#undef hal_pin_float_newf
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_5axiskins_setup(void) {
kparms kp = {0};
static char kinsname[] = "5axiskins";
static char halprefix[] = "5axiskins";
static char required_coordinates[] = "XYZBCW";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.required_coordinates = required_coordinates;
kp.max_joints = EMCMOT_MAX_JOINTS;
kp.allow_duplicates = 1;
return fiveaxis_KinematicsSetup(0, "XYZBCW", &kp);
}
void cnc_sim_linuxcnc_5axiskins_set_pivot_length(double pivot_length) {
*cnc_sim_5axis_haldata->pivot_length = pivot_length;
}
int cnc_sim_linuxcnc_5axiskins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return fiveaxis_KinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_5axiskins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return fiveaxis_KinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,122 @@
#include "linuxcnc_5axiskins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_5axiskins_setup(void);
void cnc_sim_linuxcnc_5axiskins_set_pivot_length(double pivot_length);
int cnc_sim_linuxcnc_5axiskins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_5axiskins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_5axiskins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncFiveAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.b;
out[4] = joints.c;
out[5] = joints.w;
}
LinuxCncFiveAxisJoints from_joints(const double joints[16]) {
LinuxCncFiveAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.b = joints[3];
out.c = joints[4];
out.w = joints[5];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_5axiskins_forward(const LinuxCncFiveAxisJoints &joints,
double pivot_length,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_5axiskins_set_pivot_length(pivot_length);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_5axiskins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_5axiskins_inverse(const CncSimPose &pose,
double pivot_length,
LinuxCncFiveAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_5axiskins_set_pivot_length(pivot_length);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_5axiskins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_5axiskins_forward(const LinuxCncFiveAxisJoints &joints,
double pivot_length,
CncSimPose *pose);
bool linuxcnc_5axiskins_inverse(const CncSimPose &pose,
double pivot_length,
LinuxCncFiveAxisJoints *joints);

View File

@@ -0,0 +1,127 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_KINEMATICS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define RTAPI_MSG_ERR 1
#define EMCMOT_MAX_JOINTS 16
typedef int hal_s32_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_corexykins_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_corexykins_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_corexykins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_corexykins_hal_exit(int comp_id) {
(void)comp_id;
}
#define hal_init cnc_sim_corexykins_hal_init
#define hal_malloc(size) ((struct data *)cnc_sim_corexykins_hal_malloc(size))
#define hal_ready cnc_sim_corexykins_hal_ready
#define hal_exit cnc_sim_corexykins_hal_exit
#define kinematicsType cnc_sim_corexykins_kinematicsType
#define kinematicsForward cnc_sim_corexykins_kinematicsForward
#define kinematicsInverse cnc_sim_corexykins_kinematicsInverse
#define kinematicsHome cnc_sim_corexykins_kinematicsHome
#define kinematicsSwitchable cnc_sim_corexykins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_corexykins_kinematicsSwitch
#define rtapi_app_main cnc_sim_corexykins_rtapi_app_main
#define rtapi_app_exit cnc_sim_corexykins_rtapi_app_exit
#define comp_id cnc_sim_corexykins_comp_id
#define data cnc_sim_corexykins_data
#include "../../../linuxcnc/src/emc/kinematics/corexykins.c"
#undef data
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsHome
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_corexykins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_corexykins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_corexykins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_corexykins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,104 @@
#include "linuxcnc_corexykins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_corexykins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_corexykins_inverse(const EmcPose *pos, double *joints);
}
namespace {
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_corexykins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose) {
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_corexykins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_corexykins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints) {
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_corexykins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_corexykins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_corexykins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,117 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#define __LINUXCNC_RTAPI_MATH_H
typedef struct {
double a;
double b;
double c;
double d;
} CUBIC_COEFF;
typedef struct {
int configured;
double segmentTime;
int interpolationRate;
double interpolationTime;
double interpolationIncrement;
double x0, x1, x2, x3;
double wp0, wp1;
double velp0, velp1;
int filled;
int needNextPoint;
CUBIC_COEFF coeff;
} CUBIC_STRUCT;
#define CUBIC_H
#define cubicInit cnc_sim_cubic_cubicInit
#define cubicSetSegmentTime cnc_sim_cubic_cubicSetSegmentTime
#define cubicGetSegmentTime cnc_sim_cubic_cubicGetSegmentTime
#define cubicSetInterpolationRate cnc_sim_cubic_cubicSetInterpolationRate
#define cubicGetInterpolationRate cnc_sim_cubic_cubicGetInterpolationRate
#define cubicAddPoint cnc_sim_cubic_cubicAddPoint
#define cubicOffset cnc_sim_cubic_cubicOffset
#define cubicGetInterpolationIncrement cnc_sim_cubic_cubicGetInterpolationIncrement
#define cubicGetCubicCoeff cnc_sim_cubic_cubicGetCubicCoeff
#define cubicFilled cnc_sim_cubic_cubicFilled
#define cubicInterpolate cnc_sim_cubic_cubicInterpolate
#define cubicNeedNextPoint cnc_sim_cubic_cubicNeedNextPoint
#define cubicDrain cnc_sim_cubic_cubicDrain
int cubicInit(CUBIC_STRUCT *ci);
int cubicSetSegmentTime(CUBIC_STRUCT *ci, double time);
double cubicGetSegmentTime(CUBIC_STRUCT *ci);
int cubicSetInterpolationRate(CUBIC_STRUCT *ci, int rate);
int cubicGetInterpolationRate(CUBIC_STRUCT *ci);
int cubicAddPoint(CUBIC_STRUCT *ci, double point);
int cubicOffset(CUBIC_STRUCT *ci, double offset);
double cubicGetInterpolationIncrement(CUBIC_STRUCT *ci);
CUBIC_COEFF cubicGetCubicCoeff(CUBIC_STRUCT *ci);
int cubicFilled(CUBIC_STRUCT *ci);
double cubicInterpolate(CUBIC_STRUCT *ci, double *x, double *v, double *a, double *j);
int cubicNeedNextPoint(CUBIC_STRUCT *ci);
int cubicDrain(CUBIC_STRUCT *ci);
#include "../../../linuxcnc/src/emc/kinematics/cubic.c"
#undef cubicDrain
#undef cubicNeedNextPoint
#undef cubicInterpolate
#undef cubicFilled
#undef cubicGetCubicCoeff
#undef cubicGetInterpolationIncrement
#undef cubicOffset
#undef cubicAddPoint
#undef cubicGetInterpolationRate
#undef cubicSetInterpolationRate
#undef cubicGetSegmentTime
#undef cubicSetSegmentTime
#undef cubicInit
#undef CUBIC_H
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_linuxcnc_cubic_second_segment_samples(double *x,
double *v,
double *a,
double *j,
int sample_count) {
if (!x || !v || !a || !j || sample_count != 4) {
return -1;
}
CUBIC_STRUCT cubic;
if (cnc_sim_cubic_cubicInit(&cubic) != 0 ||
cnc_sim_cubic_cubicSetSegmentTime(&cubic, 1.0) != 0 ||
cnc_sim_cubic_cubicSetInterpolationRate(&cubic, 4) != 0 ||
cnc_sim_cubic_cubicAddPoint(&cubic, 0.0) != 0) {
return -1;
}
for (int i = 0; i < 4; ++i) {
cnc_sim_cubic_cubicInterpolate(&cubic, NULL, NULL, NULL, NULL);
}
if (!cnc_sim_cubic_cubicNeedNextPoint(&cubic) ||
cnc_sim_cubic_cubicAddPoint(&cubic, 10.0) != 0) {
return -1;
}
for (int i = 0; i < sample_count; ++i) {
x[i] = cnc_sim_cubic_cubicInterpolate(&cubic, &x[i], &v[i], &a[i], &j[i]);
}
return cnc_sim_cubic_cubicNeedNextPoint(&cubic) ? 0 : -1;
}
int cnc_sim_linuxcnc_cubic_rejects_invalid_configuration(void) {
CUBIC_STRUCT cubic;
return cnc_sim_cubic_cubicInit(&cubic) == 0 &&
cnc_sim_cubic_cubicSetSegmentTime(&cubic, 0.0) != 0 &&
cnc_sim_cubic_cubicSetInterpolationRate(&cubic, 0) != 0 &&
cnc_sim_cubic_cubicAddPoint(&cubic, 1.0) != 0;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,36 @@
#include "linuxcnc_cubic_adapter.h"
extern "C" {
int cnc_sim_linuxcnc_cubic_second_segment_samples(double *x,
double *v,
double *a,
double *j,
int sample_count);
int cnc_sim_linuxcnc_cubic_rejects_invalid_configuration(void);
}
bool linuxcnc_cubic_source_second_segment_samples(LinuxCncCubicSample *samples, int sample_count) {
if (!samples || sample_count != 4) {
return false;
}
double x[4] = {};
double v[4] = {};
double a[4] = {};
double j[4] = {};
if (cnc_sim_linuxcnc_cubic_second_segment_samples(x, v, a, j, sample_count) != 0) {
return false;
}
for (int i = 0; i < sample_count; ++i) {
samples[i].x = x[i];
samples[i].v = v[i];
samples[i].a = a[i];
samples[i].j = j[i];
}
return true;
}
bool linuxcnc_cubic_source_rejects_invalid_configuration() {
return cnc_sim_linuxcnc_cubic_rejects_invalid_configuration() != 0;
}

View File

@@ -0,0 +1,11 @@
#pragma once
struct LinuxCncCubicSample {
double x;
double v;
double a;
double j;
};
bool linuxcnc_cubic_source_second_segment_samples(LinuxCncCubicSample *samples, int sample_count);
bool linuxcnc_cubic_source_rejects_invalid_configuration();

View File

@@ -0,0 +1,223 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_KINEMATICS_H
#define SWITCHKINS_H
#define RTAPI_MSG_ERR 1
#define RTAPI_MSG_INFO 2
#define EMCMOT_MAX_JOINTS 16
typedef double real_t;
typedef double hal_float_t;
typedef int hal_bit_t;
typedef uint32_t hal_u32_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
#include "../../../linuxcnc/src/libnml/posemath/posemath.h"
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
typedef int (*KF)(const double *joint,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
typedef int (*KI)(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
typedef int (*KS)(const int comp_id, const char *coordinates, kparms *ksetup_parms);
#ifdef __cplusplus
extern "C" {
#endif
void cnc_sim_genhex_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_genhex_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_genhex_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_genhex_hal_pin_u32_newf(hal_pin_dir_t dir,
hal_u32_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_u32_t *)calloc(1, sizeof(hal_u32_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_genhex_hal_pin_bit_newf(hal_pin_dir_t dir,
hal_bit_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_bit_t *)calloc(1, sizeof(hal_bit_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_genhex_identityKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return 0;
}
int cnc_sim_genhex_identityKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_genhex_identityKinematicsInverse(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
int cnc_sim_genhex_userkKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return -1;
}
int cnc_sim_genhex_userkKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_genhex_userkKinematicsInverse(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
#define rtapi_print_msg cnc_sim_genhex_rtapi_print_msg
#define hal_pin_float_newf cnc_sim_genhex_hal_pin_float_newf
#define hal_pin_u32_newf cnc_sim_genhex_hal_pin_u32_newf
#define hal_pin_bit_newf cnc_sim_genhex_hal_pin_bit_newf
#define identityKinematicsSetup cnc_sim_genhex_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_genhex_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_genhex_identityKinematicsInverse
#define userkKinematicsSetup cnc_sim_genhex_userkKinematicsSetup
#define userkKinematicsForward cnc_sim_genhex_userkKinematicsForward
#define userkKinematicsInverse cnc_sim_genhex_userkKinematicsInverse
#define switchkinsSetup cnc_sim_genhex_switchkinsSetup
#define haldata cnc_sim_genhex_haldata
#define hal_malloc(size) ((struct haldata *)cnc_sim_genhex_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/genhexkins.c"
#undef hal_malloc
#undef haldata
#undef switchkinsSetup
#undef userkKinematicsInverse
#undef userkKinematicsForward
#undef userkKinematicsSetup
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef hal_pin_bit_newf
#undef hal_pin_u32_newf
#undef hal_pin_float_newf
#undef rtapi_print_msg
int cnc_sim_linuxcnc_genhexkins_setup(void) {
kparms kp;
memset(&kp, 0, sizeof(kp));
static char kinsname[] = "genhexkins";
static char halprefix[] = "genhexkins";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.max_joints = NUM_STRUTS;
return genhexKinematicsSetup(0, "XYZABC", &kp);
}
int cnc_sim_linuxcnc_genhexkins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return genhexKinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_genhexkins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return genhexKinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,96 @@
#include "linuxcnc_genhexkins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_genhexkins_setup(void);
int cnc_sim_linuxcnc_genhexkins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_genhexkins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_genhexkins_setup() == 0;
return initialized;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_genhexkins_source_forward(const LinuxCncGenhexJoints &joints,
const CncSimPose &initial_pose,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[6];
std::memcpy(raw_joints, joints.strut, sizeof(raw_joints));
EmcPose emc_pose = to_emc_pose(initial_pose);
if (cnc_sim_linuxcnc_genhexkins_forward(raw_joints, &emc_pose) != 0) {
return false;
}
*pose = from_emc_pose(emc_pose);
return true;
}
bool linuxcnc_genhexkins_source_inverse(const CncSimPose &pose, LinuxCncGenhexJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose emc_pose = to_emc_pose(pose);
double raw_joints[6] = {};
if (cnc_sim_linuxcnc_genhexkins_inverse(&emc_pose, raw_joints) != 0) {
return false;
}
std::memcpy(joints->strut, raw_joints, sizeof(raw_joints));
return true;
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_genhexkins_source_forward(const LinuxCncGenhexJoints &joints,
const CncSimPose &initial_pose,
CncSimPose *pose);
bool linuxcnc_genhexkins_source_inverse(const CncSimPose &pose, LinuxCncGenhexJoints *joints);

View File

@@ -0,0 +1,206 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define RTAPI_MSG_ERR 1
#define PM_PI 3.1415926535897932384626433832795029
typedef double real_t;
typedef double hal_float_t;
typedef unsigned int hal_u32_t;
typedef int hal_s32_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#ifdef __cplusplus
extern "C" {
#endif
void cnc_sim_genser_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_genser_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_genser_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_genser_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_genser_hal_pin_u32_newf(hal_pin_dir_t dir,
hal_u32_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_u32_t *)calloc(1, sizeof(hal_u32_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_genser_hal_pin_s32_newf(hal_pin_dir_t dir,
hal_s32_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_s32_t *)calloc(1, sizeof(hal_s32_t));
return *data_ptr_addr ? 0 : -1;
}
#define rtapi_print cnc_sim_genser_rtapi_print
#define rtapi_print_msg cnc_sim_genser_rtapi_print_msg
#define hal_pin_float_newf cnc_sim_genser_hal_pin_float_newf
#define hal_pin_u32_newf cnc_sim_genser_hal_pin_u32_newf
#define hal_pin_s32_newf cnc_sim_genser_hal_pin_s32_newf
#define pm_sincos cnc_sim_genser_pm_sincos
#include "../../../linuxcnc/src/libnml/posemath/sincos.c"
#include "../../../linuxcnc/src/libnml/posemath/gomath.c"
#define hal_malloc(size) cnc_sim_genser_hal_malloc(size)
#include "../../../linuxcnc/src/emc/kinematics/genserfuncs.c"
#undef hal_malloc
#undef pm_sincos
#undef hal_pin_s32_newf
#undef hal_pin_u32_newf
#undef hal_pin_float_newf
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_genserfuncs_setup(void) {
kparms kp = {0};
static char kinsname[] = "genserkins";
static char halprefix[] = "genserkins";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.max_joints = 6;
return genserKinematicsSetup(0, "XYZABC", &kp);
}
void cnc_sim_linuxcnc_genserfuncs_set_parameters(const double *a,
const double *alpha,
const double *d,
const int *unrotate,
int max_iterations) {
for (int i = 0; i < GENSER_MAX_JOINTS; ++i) {
*haldata->a[i] = a[i];
*haldata->alpha[i] = alpha[i];
*haldata->d[i] = d[i];
*haldata->unrotate[i] = unrotate[i];
}
*haldata->max_iterations = (hal_u32_t)max_iterations;
}
void cnc_sim_linuxcnc_genserfuncs_default_parameters(double *a,
double *alpha,
double *d,
int *unrotate,
int *max_iterations) {
const double default_a[GENSER_MAX_JOINTS] = {
DEFAULT_A1,
DEFAULT_A2,
DEFAULT_A3,
DEFAULT_A4,
DEFAULT_A5,
DEFAULT_A6,
};
const double default_alpha[GENSER_MAX_JOINTS] = {
DEFAULT_ALPHA1,
DEFAULT_ALPHA2,
DEFAULT_ALPHA3,
DEFAULT_ALPHA4,
DEFAULT_ALPHA5,
DEFAULT_ALPHA6,
};
const double default_d[GENSER_MAX_JOINTS] = {
DEFAULT_D1,
DEFAULT_D2,
DEFAULT_D3,
DEFAULT_D4,
DEFAULT_D5,
DEFAULT_D6,
};
for (int i = 0; i < GENSER_MAX_JOINTS; ++i) {
a[i] = default_a[i];
alpha[i] = default_alpha[i];
d[i] = default_d[i];
unrotate[i] = 0;
}
*max_iterations = GENSER_DEFAULT_MAX_ITERATIONS;
}
int cnc_sim_linuxcnc_genserfuncs_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return genserKinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_genserfuncs_inverse(const EmcPose *pos, double *joints, int *iterations) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
const int result = genserKinematicsInverse(pos, joints, &iflags, &fflags);
if (iterations) {
*iterations = genser_kin_inv_iterations(KINS_PTR);
}
return result;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,166 @@
#include "linuxcnc_genserfuncs_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_genserfuncs_setup(void);
void cnc_sim_linuxcnc_genserfuncs_set_parameters(const double *a,
const double *alpha,
const double *d,
const int *unrotate,
int max_iterations);
void cnc_sim_linuxcnc_genserfuncs_default_parameters(double *a,
double *alpha,
double *d,
int *unrotate,
int *max_iterations);
int cnc_sim_linuxcnc_genserfuncs_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_genserfuncs_inverse(const EmcPose *pos, double *joints, int *iterations);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_genserfuncs_setup() == 0;
return initialized;
}
void apply_parameters(const LinuxCncGenserParameters &parameters, int max_iterations) {
cnc_sim_linuxcnc_genserfuncs_set_parameters(parameters.a,
parameters.alpha,
parameters.d,
parameters.unrotate,
max_iterations);
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_genserfuncs_forward(const LinuxCncAxisJoints &joints,
const LinuxCncGenserParameters &parameters,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters, 100);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_genserfuncs_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_genserfuncs_source_default_parameters(LinuxCncGenserParameters *parameters,
int *max_iterations) {
if (!parameters) {
return false;
}
int raw_max_iterations = 0;
cnc_sim_linuxcnc_genserfuncs_default_parameters(parameters->a,
parameters->alpha,
parameters->d,
parameters->unrotate,
&raw_max_iterations);
if (max_iterations) {
*max_iterations = raw_max_iterations;
}
return true;
}
bool linuxcnc_genserfuncs_inverse(const CncSimPose &pose,
const LinuxCncAxisJoints &joint_estimate,
const LinuxCncGenserParameters &parameters,
int max_iterations,
LinuxCncAxisJoints *joints,
int *iterations) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters, max_iterations);
double raw_joints[16];
to_joints(joint_estimate, raw_joints);
const EmcPose in = to_emc_pose(pose);
if (cnc_sim_linuxcnc_genserfuncs_inverse(&in, raw_joints, iterations) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_genserfuncs_forward(const LinuxCncAxisJoints &joints,
const LinuxCncGenserParameters &parameters,
CncSimPose *pose);
bool linuxcnc_genserfuncs_source_default_parameters(LinuxCncGenserParameters *parameters,
int *max_iterations);
bool linuxcnc_genserfuncs_inverse(const CncSimPose &pose,
const LinuxCncAxisJoints &joint_estimate,
const LinuxCncGenserParameters &parameters,
int max_iterations,
LinuxCncAxisJoints *joints,
int *iterations);

View File

@@ -0,0 +1,116 @@
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_EMCPOS_H
#define __LINUXCNC_KINEMATICS_H
#define RTAPI_MSG_ERR 1
#define EMCMOT_MAX_JOINTS 16
#define EMCMOT_MAX_AXIS 9
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#ifdef __cplusplus
extern "C" {
#endif
void cnc_sim_kins_util_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_kins_util_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
KINEMATICS_TYPE kinematicsType(void) {
return KINEMATICS_BOTH;
}
#define rtapi_print cnc_sim_kins_util_rtapi_print
#define rtapi_print_msg cnc_sim_kins_util_rtapi_print_msg
#define map_coordinates_to_jnumbers cnc_sim_kins_util_map_coordinates_to_jnumbers
#define mapped_joints_to_position cnc_sim_kins_util_mapped_joints_to_position
#define position_to_mapped_joints cnc_sim_kins_util_position_to_mapped_joints
#define identityKinematicsSetup cnc_sim_kins_util_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_kins_util_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_kins_util_identityKinematicsInverse
#include "../../../linuxcnc/src/emc/kinematics/kins_util.c"
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef position_to_mapped_joints
#undef mapped_joints_to_position
#undef map_coordinates_to_jnumbers
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_kins_util_setup(void) {
kparms kp = {0};
static char kinsname[] = "kins_util_identity";
static char halprefix[] = "identity";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.max_joints = EMCMOT_MAX_JOINTS;
kp.allow_duplicates = 0;
return cnc_sim_kins_util_identityKinematicsSetup(0, "XYZABCUVW", &kp);
}
int cnc_sim_linuxcnc_kins_util_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_kins_util_identityKinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_kins_util_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_kins_util_identityKinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,121 @@
#include "linuxcnc_kins_util_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_kins_util_setup(void);
int cnc_sim_linuxcnc_kins_util_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_kins_util_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_kins_util_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_kins_util_identity_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_kins_util_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_kins_util_identity_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_kins_util_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_kins_util_identity_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_kins_util_identity_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,155 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define EMCMOT_MAX_JOINTS 16
typedef double real_t;
typedef double hal_float_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_lineardelta_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_lineardelta_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_lineardelta_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_lineardelta_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_lineardelta_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_lineardelta_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_lineardelta_hal_malloc(size))
#define hal_pin_float_newf cnc_sim_lineardelta_hal_pin_float_newf
#define hal_ready cnc_sim_lineardelta_hal_ready
#define hal_exit cnc_sim_lineardelta_hal_exit
#define kinematicsType cnc_sim_lineardelta_kinematicsType
#define kinematicsForward cnc_sim_lineardelta_kinematicsForward
#define kinematicsInverse cnc_sim_lineardelta_kinematicsInverse
#define kinematicsSwitchable cnc_sim_lineardelta_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_lineardelta_kinematicsSwitch
#define rtapi_app_main cnc_sim_lineardelta_rtapi_app_main
#define rtapi_app_exit cnc_sim_lineardelta_rtapi_app_exit
#define comp_id cnc_sim_lineardelta_comp_id
#define haldata cnc_sim_lineardelta_haldata
#include "../../../linuxcnc/src/emc/kinematics/lineardeltakins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_float_newf
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_lineardeltakins_setup(void) {
return cnc_sim_lineardelta_rtapi_app_main();
}
void cnc_sim_linuxcnc_lineardeltakins_default_parameters(double *r, double *l) {
*r = DELTA_RADIUS;
*l = DELTA_DIAGONAL_ROD;
}
void cnc_sim_linuxcnc_lineardeltakins_set_parameters(double r, double l) {
*cnc_sim_lineardelta_haldata->r = r;
*cnc_sim_lineardelta_haldata->l = l;
}
int cnc_sim_linuxcnc_lineardeltakins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_lineardelta_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_lineardeltakins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_lineardelta_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,138 @@
#include "linuxcnc_lineardeltakins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_lineardeltakins_setup(void);
void cnc_sim_linuxcnc_lineardeltakins_default_parameters(double *r, double *l);
void cnc_sim_linuxcnc_lineardeltakins_set_parameters(double r, double l);
int cnc_sim_linuxcnc_lineardeltakins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_lineardeltakins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_lineardeltakins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_lineardeltakins_source_default_parameters(LinuxCncLinearDeltaParameters *parameters) {
double r = 0.0;
double l = 0.0;
cnc_sim_linuxcnc_lineardeltakins_default_parameters(&r, &l);
parameters->r = r;
parameters->l = l;
return true;
}
bool linuxcnc_lineardeltakins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncLinearDeltaParameters &parameters,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_lineardeltakins_set_parameters(parameters.r, parameters.l);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_lineardeltakins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_lineardeltakins_source_inverse(const CncSimPose &pose,
const LinuxCncLinearDeltaParameters &parameters,
LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_lineardeltakins_set_parameters(parameters.r, parameters.l);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_lineardeltakins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_lineardeltakins_source_default_parameters(LinuxCncLinearDeltaParameters *parameters);
bool linuxcnc_lineardeltakins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncLinearDeltaParameters &parameters,
CncSimPose *pose);
bool linuxcnc_lineardeltakins_source_inverse(const CncSimPose &pose,
const LinuxCncLinearDeltaParameters &parameters,
LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,168 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define EMCMOT_MAX_JOINTS 16
#define PM_PI 3.1415926535897932384626433832795029
typedef double real_t;
typedef double hal_float_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_maxkins_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_maxkins_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_maxkins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_maxkins_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_maxkins_hal_pin_float_new(const char *name,
hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_maxkins_hal_pin_bit_new(const char *name,
hal_pin_dir_t dir,
hal_bit_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_bit_t *)calloc(1, sizeof(hal_bit_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_maxkins_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_maxkins_hal_malloc(size))
#define hal_pin_float_new cnc_sim_maxkins_hal_pin_float_new
#define hal_pin_bit_new cnc_sim_maxkins_hal_pin_bit_new
#define hal_ready cnc_sim_maxkins_hal_ready
#define hal_exit cnc_sim_maxkins_hal_exit
#define kinematicsType cnc_sim_maxkins_kinematicsType
#define kinematicsForward cnc_sim_maxkins_kinematicsForward
#define kinematicsInverse cnc_sim_maxkins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_maxkins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_maxkins_kinematicsSwitch
#define rtapi_app_main cnc_sim_maxkins_rtapi_app_main
#define rtapi_app_exit cnc_sim_maxkins_rtapi_app_exit
#define comp_id cnc_sim_maxkins_comp_id
#define haldata cnc_sim_maxkins_haldata
#include "../../../linuxcnc/src/emc/kinematics/maxkins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_bit_new
#undef hal_pin_float_new
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_maxkins_setup(void) {
return cnc_sim_maxkins_rtapi_app_main();
}
void cnc_sim_linuxcnc_maxkins_default_parameters(double *pivot_length, int *conventional_directions) {
*pivot_length = 0.666;
*conventional_directions = 0;
}
void cnc_sim_linuxcnc_maxkins_set_parameters(double pivot_length, int conventional_directions) {
*cnc_sim_maxkins_haldata->pivot_length = pivot_length;
*cnc_sim_maxkins_haldata->conventional_directions = conventional_directions != 0;
}
int cnc_sim_linuxcnc_maxkins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_maxkins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_maxkins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_maxkins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,140 @@
#include "linuxcnc_maxkins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_maxkins_setup(void);
void cnc_sim_linuxcnc_maxkins_default_parameters(double *pivot_length, int *conventional_directions);
void cnc_sim_linuxcnc_maxkins_set_parameters(double pivot_length, int conventional_directions);
int cnc_sim_linuxcnc_maxkins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_maxkins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_maxkins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_maxkins_source_default_parameters(LinuxCncMaxkinsParameters *parameters) {
double pivot_length = 0.0;
int conventional_directions = 0;
cnc_sim_linuxcnc_maxkins_default_parameters(&pivot_length, &conventional_directions);
parameters->pivot_length = pivot_length;
parameters->conventional_directions = conventional_directions != 0;
return true;
}
bool linuxcnc_maxkins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncMaxkinsParameters &parameters,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_maxkins_set_parameters(parameters.pivot_length,
parameters.conventional_directions ? 1 : 0);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_maxkins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_maxkins_source_inverse(const CncSimPose &pose,
const LinuxCncMaxkinsParameters &parameters,
LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_maxkins_set_parameters(parameters.pivot_length,
parameters.conventional_directions ? 1 : 0);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_maxkins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_maxkins_source_default_parameters(LinuxCncMaxkinsParameters *parameters);
bool linuxcnc_maxkins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncMaxkinsParameters &parameters,
CncSimPose *pose);
bool linuxcnc_maxkins_source_inverse(const CncSimPose &pose,
const LinuxCncMaxkinsParameters &parameters,
LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,172 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define EMCMOT_MAX_JOINTS 16
typedef double real_t;
typedef double hal_float_t;
typedef uint32_t hal_u32_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef enum { HAL_RO = 64, HAL_RW = (HAL_RO | 128) } hal_param_dir_t;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
#include "../../../linuxcnc/src/libnml/posemath/posemath.h"
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_pentakins_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_pentakins_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_pentakins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_pentakins_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_pentakins_hal_param_float_newf(hal_param_dir_t dir,
hal_float_t *data_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)data_addr;
(void)comp_id;
(void)fmt;
return 0;
}
int cnc_sim_pentakins_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_pentakins_hal_pin_u32_newf(hal_pin_dir_t dir,
hal_u32_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_u32_t *)calloc(1, sizeof(hal_u32_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_pentakins_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_pentakins_hal_malloc(size))
#define hal_param_float_newf cnc_sim_pentakins_hal_param_float_newf
#define hal_pin_float_newf cnc_sim_pentakins_hal_pin_float_newf
#define hal_pin_u32_newf cnc_sim_pentakins_hal_pin_u32_newf
#define hal_ready cnc_sim_pentakins_hal_ready
#define hal_exit cnc_sim_pentakins_hal_exit
#define kinematicsType cnc_sim_pentakins_kinematicsType
#define kinematicsForward cnc_sim_pentakins_kinematicsForward
#define kinematicsInverse cnc_sim_pentakins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_pentakins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_pentakins_kinematicsSwitch
#define rtapi_app_main cnc_sim_pentakins_rtapi_app_main
#define rtapi_app_exit cnc_sim_pentakins_rtapi_app_exit
#define comp_id cnc_sim_pentakins_comp_id
#define haldata cnc_sim_pentakins_haldata
#include "../../../linuxcnc/src/emc/kinematics/pentakins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_u32_newf
#undef hal_pin_float_newf
#undef hal_param_float_newf
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_pentakins_setup(void) {
return cnc_sim_pentakins_rtapi_app_main();
}
int cnc_sim_linuxcnc_pentakins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_pentakins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_pentakins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_pentakins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,97 @@
#include "linuxcnc_pentakins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_pentakins_setup(void);
int cnc_sim_linuxcnc_pentakins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_pentakins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_pentakins_setup() == 0;
return initialized;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_pentakins_source_forward(const LinuxCncPentakinsJoints &joints,
const CncSimPose &initial_pose,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[5];
std::memcpy(raw_joints, joints.strut, sizeof(raw_joints));
EmcPose emc_pose = to_emc_pose(initial_pose);
if (cnc_sim_linuxcnc_pentakins_forward(raw_joints, &emc_pose) != 0) {
return false;
}
*pose = from_emc_pose(emc_pose);
return true;
}
bool linuxcnc_pentakins_source_inverse(const CncSimPose &pose,
LinuxCncPentakinsJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose emc_pose = to_emc_pose(pose);
double raw_joints[5] = {};
if (cnc_sim_linuxcnc_pentakins_inverse(&emc_pose, raw_joints) != 0) {
return false;
}
std::memcpy(joints->strut, raw_joints, sizeof(raw_joints));
return true;
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_pentakins_source_forward(const LinuxCncPentakinsJoints &joints,
const CncSimPose &initial_pose,
CncSimPose *pose);
bool linuxcnc_pentakins_source_inverse(const CncSimPose &pose,
LinuxCncPentakinsJoints *joints);

View File

@@ -0,0 +1,218 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define SWITCHKINS_H
#ifdef __cplusplus
#define CNC_SIM_EXTERN_C extern "C"
#else
#define CNC_SIM_EXTERN_C
#endif
typedef double real_t;
typedef double hal_float_t;
typedef int hal_s32_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
#include "../../../linuxcnc/src/libnml/posemath/sincos.c"
#include "../../../linuxcnc/src/libnml/posemath/_posemath.c"
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
typedef int (*KF)(const double *joint,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
typedef int (*KI)(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
typedef int (*KS)(const int comp_id, const char *coordinates, kparms *ksetup_parms);
void cnc_sim_puma_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_puma_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_puma_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_puma_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_puma_identityKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return 0;
}
int cnc_sim_puma_identityKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_puma_identityKinematicsInverse(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
int cnc_sim_puma_userkKinematicsSetup(const int comp_id, const char *coordinates, kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return -1;
}
int cnc_sim_puma_userkKinematicsForward(const double *joint,
EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_puma_userkKinematicsInverse(const EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
#define rtapi_print cnc_sim_puma_rtapi_print
#define rtapi_print_msg cnc_sim_puma_rtapi_print_msg
#define hal_pin_float_newf cnc_sim_puma_hal_pin_float_newf
#define identityKinematicsSetup cnc_sim_puma_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_puma_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_puma_identityKinematicsInverse
#define userkKinematicsSetup cnc_sim_puma_userkKinematicsSetup
#define userkKinematicsForward cnc_sim_puma_userkKinematicsForward
#define userkKinematicsInverse cnc_sim_puma_userkKinematicsInverse
#define switchkinsSetup cnc_sim_puma_switchkinsSetup
#define haldata cnc_sim_puma_haldata
#define hal_malloc(size) ((struct haldata *)cnc_sim_puma_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/pumakins.c"
#undef hal_malloc
#undef haldata
#undef switchkinsSetup
#undef userkKinematicsInverse
#undef userkKinematicsForward
#undef userkKinematicsSetup
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef hal_pin_float_newf
#undef rtapi_print_msg
#undef rtapi_print
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_pumakins_setup(void) {
kparms kp = {0};
static char kinsname[] = "pumakins";
static char halprefix[] = "pumakins";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
return pumaKinematicsSetup(0, "XYZABC", &kp);
}
CNC_SIM_EXTERN_C void cnc_sim_linuxcnc_pumakins_set_parameters(double a2,
double a3,
double d3,
double d4,
double d6) {
*cnc_sim_puma_haldata->a2 = a2;
*cnc_sim_puma_haldata->a3 = a3;
*cnc_sim_puma_haldata->d3 = d3;
*cnc_sim_puma_haldata->d4 = d4;
*cnc_sim_puma_haldata->d6 = d6;
}
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_pumakins_forward(const double *joints,
struct EmcPose *pos,
int *iflags) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS raw_iflags = 0;
const int result = pumaKinematicsForward(joints, pos, &fflags, &raw_iflags);
if (iflags) {
*iflags = (int)raw_iflags;
}
return result;
}
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_pumakins_inverse(const struct EmcPose *pos,
double *joints,
int iflags,
int *fflags) {
KINEMATICS_INVERSE_FLAGS raw_iflags = (KINEMATICS_INVERSE_FLAGS)iflags;
KINEMATICS_FORWARD_FLAGS raw_fflags = 0;
const int result = pumaKinematicsInverse(pos, joints, &raw_iflags, &raw_fflags);
if (fflags) {
*fflags = (int)raw_fflags;
}
return result;
}

View File

@@ -0,0 +1,156 @@
#include "linuxcnc_pumakins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_pumakins_setup(void);
void cnc_sim_linuxcnc_pumakins_set_parameters(double a2,
double a3,
double d3,
double d4,
double d6);
int cnc_sim_linuxcnc_pumakins_forward(const double *joints, EmcPose *pos, int *iflags);
int cnc_sim_linuxcnc_pumakins_inverse(const EmcPose *pos,
double *joints,
int iflags,
int *fflags);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_pumakins_setup() == 0;
return initialized;
}
void apply_parameters(const LinuxCncPumaParameters &parameters) {
cnc_sim_linuxcnc_pumakins_set_parameters(parameters.a2,
parameters.a3,
parameters.d3,
parameters.d4,
parameters.d6);
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_pumakins_forward(const LinuxCncAxisJoints &joints,
const LinuxCncPumaParameters &parameters,
CncSimPose *pose,
int *iflags) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
int raw_iflags = 0;
if (cnc_sim_linuxcnc_pumakins_forward(raw_joints, &out, &raw_iflags) != 0) {
return false;
}
if (iflags) {
*iflags = raw_iflags;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_pumakins_inverse(const CncSimPose &pose,
const LinuxCncAxisJoints &current_joints,
const LinuxCncPumaParameters &parameters,
int iflags,
LinuxCncAxisJoints *joints,
int *fflags) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
double raw_joints[16];
to_joints(current_joints, raw_joints);
const EmcPose in = to_emc_pose(pose);
int raw_fflags = 0;
if (cnc_sim_linuxcnc_pumakins_inverse(&in, raw_joints, iflags, &raw_fflags) != 0) {
return false;
}
if (fflags) {
*fflags = raw_fflags;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_pumakins_forward(const LinuxCncAxisJoints &joints,
const LinuxCncPumaParameters &parameters,
CncSimPose *pose,
int *iflags);
bool linuxcnc_pumakins_inverse(const CncSimPose &pose,
const LinuxCncAxisJoints &current_joints,
const LinuxCncPumaParameters &parameters,
int iflags,
LinuxCncAxisJoints *joints,
int *fflags);

View File

@@ -0,0 +1,147 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define EMCMOT_MAX_JOINTS 16
#define PM_PI 3.1415926535897932384626433832795029
#define PM_2_PI (2.0 * PM_PI)
#define TO_RAD (PM_PI / 180.0)
#define TO_DEG (180.0 / PM_PI)
typedef double real_t;
typedef double hal_float_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_rosekins_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_rosekins_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_rosekins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_rosekins_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_rosekins_hal_pin_float_new(const char *name,
hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_rosekins_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_rosekins_hal_malloc(size))
#define hal_pin_float_new cnc_sim_rosekins_hal_pin_float_new
#define hal_ready cnc_sim_rosekins_hal_ready
#define hal_exit cnc_sim_rosekins_hal_exit
#define kinematicsType cnc_sim_rosekins_kinematicsType
#define kinematicsForward cnc_sim_rosekins_kinematicsForward
#define kinematicsInverse cnc_sim_rosekins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_rosekins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_rosekins_kinematicsSwitch
#define rtapi_app_main cnc_sim_rosekins_rtapi_app_main
#define rtapi_app_exit cnc_sim_rosekins_rtapi_app_exit
#define comp_id cnc_sim_rosekins_comp_id
#define haldata cnc_sim_rosekins_haldata
#include "../../../linuxcnc/src/emc/kinematics/rosekins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_float_new
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_rosekins_setup(void) {
return cnc_sim_rosekins_rtapi_app_main();
}
int cnc_sim_linuxcnc_rosekins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_rosekins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_rosekins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_rosekins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,121 @@
#include "linuxcnc_rosekins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_rosekins_setup(void);
int cnc_sim_linuxcnc_rosekins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_rosekins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_rosekins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_rosekins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_rosekins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_rosekins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_rosekins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_rosekins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_rosekins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,165 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define EMCMOT_MAX_JOINTS 16
typedef double real_t;
typedef double hal_float_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_rotarydelta_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_rotarydelta_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_rotarydelta_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_rotarydelta_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_rotarydelta_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_rotarydelta_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_rotarydelta_hal_malloc(size))
#define hal_pin_float_newf cnc_sim_rotarydelta_hal_pin_float_newf
#define hal_ready cnc_sim_rotarydelta_hal_ready
#define hal_exit cnc_sim_rotarydelta_hal_exit
#define kinematicsType cnc_sim_rotarydelta_kinematicsType
#define kinematicsForward cnc_sim_rotarydelta_kinematicsForward
#define kinematicsInverse cnc_sim_rotarydelta_kinematicsInverse
#define kinematicsSwitchable cnc_sim_rotarydelta_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_rotarydelta_kinematicsSwitch
#define rtapi_app_main cnc_sim_rotarydelta_rtapi_app_main
#define rtapi_app_exit cnc_sim_rotarydelta_rtapi_app_exit
#define comp_id cnc_sim_rotarydelta_comp_id
#define haldata cnc_sim_rotarydelta_haldata
#include "../../../linuxcnc/src/emc/kinematics/rotarydeltakins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_float_newf
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_rotarydeltakins_setup(void) {
return cnc_sim_rotarydelta_rtapi_app_main();
}
void cnc_sim_linuxcnc_rotarydeltakins_default_parameters(double *platformradius,
double *thighlength,
double *shinlength,
double *footradius) {
*platformradius = RDELTA_PFR;
*thighlength = RDELTA_TL;
*shinlength = RDELTA_SL;
*footradius = RDELTA_FR;
}
void cnc_sim_linuxcnc_rotarydeltakins_set_parameters(double platformradius,
double thighlength,
double shinlength,
double footradius) {
*cnc_sim_rotarydelta_haldata->pfr = platformradius;
*cnc_sim_rotarydelta_haldata->tl = thighlength;
*cnc_sim_rotarydelta_haldata->sl = shinlength;
*cnc_sim_rotarydelta_haldata->fr = footradius;
}
int cnc_sim_linuxcnc_rotarydeltakins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_rotarydelta_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_rotarydeltakins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_rotarydelta_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,157 @@
#include "linuxcnc_rotarydeltakins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_rotarydeltakins_setup(void);
void cnc_sim_linuxcnc_rotarydeltakins_default_parameters(double *platformradius,
double *thighlength,
double *shinlength,
double *footradius);
void cnc_sim_linuxcnc_rotarydeltakins_set_parameters(double platformradius,
double thighlength,
double shinlength,
double footradius);
int cnc_sim_linuxcnc_rotarydeltakins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_rotarydeltakins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_rotarydeltakins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_rotarydeltakins_source_default_parameters(LinuxCncRotaryDeltaParameters *parameters) {
double platformradius = 0.0;
double thighlength = 0.0;
double shinlength = 0.0;
double footradius = 0.0;
cnc_sim_linuxcnc_rotarydeltakins_default_parameters(&platformradius,
&thighlength,
&shinlength,
&footradius);
parameters->platformradius = platformradius;
parameters->thighlength = thighlength;
parameters->shinlength = shinlength;
parameters->footradius = footradius;
return true;
}
bool linuxcnc_rotarydeltakins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncRotaryDeltaParameters &parameters,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_rotarydeltakins_set_parameters(parameters.platformradius,
parameters.thighlength,
parameters.shinlength,
parameters.footradius);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_rotarydeltakins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_rotarydeltakins_source_inverse(const CncSimPose &pose,
const LinuxCncRotaryDeltaParameters &parameters,
LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
cnc_sim_linuxcnc_rotarydeltakins_set_parameters(parameters.platformradius,
parameters.thighlength,
parameters.shinlength,
parameters.footradius);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_rotarydeltakins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_rotarydeltakins_source_default_parameters(LinuxCncRotaryDeltaParameters *parameters);
bool linuxcnc_rotarydeltakins_source_forward(const LinuxCncAxisJoints &joints,
const LinuxCncRotaryDeltaParameters &parameters,
CncSimPose *pose);
bool linuxcnc_rotarydeltakins_source_inverse(const CncSimPose &pose,
const LinuxCncRotaryDeltaParameters &parameters,
LinuxCncAxisJoints *joints);

View File

@@ -0,0 +1,118 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define RTAPI_MSG_ERR 1
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_rotatekins_hal_init(const char *name) {
(void)name;
return 1;
}
int cnc_sim_rotatekins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_rotatekins_hal_exit(int comp_id) {
(void)comp_id;
}
#define hal_init cnc_sim_rotatekins_hal_init
#define hal_ready cnc_sim_rotatekins_hal_ready
#define hal_exit cnc_sim_rotatekins_hal_exit
#define kinematicsType cnc_sim_rotatekins_kinematicsType
#define kinematicsForward cnc_sim_rotatekins_kinematicsForward
#define kinematicsInverse cnc_sim_rotatekins_kinematicsInverse
#define kinematicsHome cnc_sim_rotatekins_kinematicsHome
#define kinematicsSwitchable cnc_sim_rotatekins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_rotatekins_kinematicsSwitch
#define rtapi_app_main cnc_sim_rotatekins_rtapi_app_main
#define rtapi_app_exit cnc_sim_rotatekins_rtapi_app_exit
#define comp_id cnc_sim_rotatekins_comp_id
#include "../../../linuxcnc/src/emc/kinematics/rotatekins.c"
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsHome
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_init
int cnc_sim_linuxcnc_rotatekins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_rotatekins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_rotatekins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_rotatekins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,104 @@
#include "linuxcnc_rotatekins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_rotatekins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_rotatekins_inverse(const EmcPose *pos, double *joints);
}
namespace {
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_rotatekins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose) {
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_rotatekins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_rotatekins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints) {
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_rotatekins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_rotatekins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_rotatekins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints);

View File

@@ -1,6 +1,10 @@
#include "linuxcnc_rs274_backend.h"
#ifdef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
#include "boost/python/object.hpp"
#else
#include <Python.h>
#endif
#include "linuxcnc_canon_bridge.h"
#include "linuxcnc_tooldata_fixture.h"
@@ -16,11 +20,15 @@
#include <vector>
#include <cstdlib>
#include <fstream>
#ifndef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
#include <unistd.h>
#endif
int _task = 0;
char _parameter_file_name[LINELEN];
#ifndef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
int _task = 0;
extern "C" PyObject *PyInit_interpreter(void);
extern "C" PyObject *PyInit_emccanon(void);
extern "C" struct _inittab builtin_modules[];
@@ -29,6 +37,7 @@ struct _inittab builtin_modules[] = {
{"emccanon", PyInit_emccanon},
{nullptr, nullptr},
};
#endif
namespace {
@@ -73,6 +82,7 @@ bool file_mode_enabled() {
return std::getenv("CNC_SIM_RS274_FILE_MODE") != nullptr;
}
#ifndef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
bool write_temp_program(const char *program,
size_t program_len,
std::string *path,
@@ -113,6 +123,7 @@ bool write_temp_program(const char *program,
*path = tmpl_buffer.data();
return true;
}
#endif
int execute_file_mode(InterpBase *interp,
CanonEventSink &sink,
@@ -192,6 +203,15 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
SET_BLOCK_DELETE(sink.block_delete());
if (file_mode_enabled()) {
#ifdef CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE
if (error) {
*error = "linuxcnc-rs274 file mode is not available in wasm-safe builds";
}
interp->exit();
delete interp;
cnc_sim_linuxcnc_set_canon_sink(nullptr);
return -1;
#else
std::string temp_path;
if (!write_temp_program(program, program_len, &temp_path, error)) {
interp->exit();
@@ -207,6 +227,7 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
cnc_sim_linuxcnc_set_canon_sink(nullptr);
return -1;
}
#endif
} else {
std::string source(program, program + program_len);
std::istringstream input(source);
@@ -219,19 +240,45 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
std::vector<SimulatorGcodeControlAction> control_actions;
if (parse_simulator_gcode_control_line(line, sink.block_delete(), &control_actions)) {
bool simulator_only_line = true;
bool all_control_actions_handled = true;
for (const auto &action : control_actions) {
emit_simulator_gcode_control_action(sink, action, line_number);
if (!can_emit_simulator_gcode_control_action(sink, action)) {
all_control_actions_handled = false;
simulator_only_line = false;
}
if (action.kind == SimulatorGcodeControlKind::RtcpState &&
!action.rtcp_enabled) {
simulator_only_line = false;
}
if (stop_if_callback_aborted(sink, error)) {
interp->exit();
delete interp;
cnc_sim_linuxcnc_set_canon_sink(nullptr);
return -1;
}
if (!all_control_actions_handled && control_actions.size() > 1) {
for (const auto &action : control_actions) {
if (!can_emit_simulator_gcode_control_action(sink, action) &&
action.kind == SimulatorGcodeControlKind::KinematicsSwitch) {
if (error) {
*error = "M-code greater than 199: M" + std::to_string(action.m_code);
}
interp->exit();
delete interp;
cnc_sim_linuxcnc_set_canon_sink(nullptr);
return -1;
}
}
}
if (all_control_actions_handled) {
for (const auto &action : control_actions) {
emit_simulator_gcode_control_action(sink, action, line_number);
if (stop_if_callback_aborted(sink, error)) {
interp->exit();
delete interp;
cnc_sim_linuxcnc_set_canon_sink(nullptr);
return -1;
}
}
}
if (!all_control_actions_handled) {
simulator_only_line = false;
}
if (simulator_only_line) {
continue;
}

View File

@@ -0,0 +1,224 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define SWITCHKINS_H
#ifdef __cplusplus
#define CNC_SIM_EXTERN_C extern "C"
#else
#define CNC_SIM_EXTERN_C
#endif
#define PM_PI 3.1415926535897932384626433832795029
typedef double real_t;
typedef double hal_float_t;
typedef int hal_s32_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
typedef int (*KF)(const double *joint,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
typedef int (*KI)(const struct EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
typedef int (*KS)(const int comp_id, const char *coordinates, kparms *ksetup_parms);
void cnc_sim_scara_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_scara_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_scara_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_scara_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_scara_identityKinematicsSetup(const int comp_id,
const char *coordinates,
kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return 0;
}
int cnc_sim_scara_identityKinematicsForward(const double *joint,
struct EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_scara_identityKinematicsInverse(const struct EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
int cnc_sim_scara_userkKinematicsSetup(const int comp_id,
const char *coordinates,
kparms *ksetup_parms) {
(void)comp_id;
(void)coordinates;
(void)ksetup_parms;
return -1;
}
int cnc_sim_scara_userkKinematicsForward(const double *joint,
struct EmcPose *world,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags) {
(void)joint;
(void)world;
(void)fflags;
(void)iflags;
return -1;
}
int cnc_sim_scara_userkKinematicsInverse(const struct EmcPose *world,
double *joint,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags) {
(void)world;
(void)joint;
(void)iflags;
(void)fflags;
return -1;
}
#define rtapi_print cnc_sim_scara_rtapi_print
#define rtapi_print_msg cnc_sim_scara_rtapi_print_msg
#define hal_pin_float_newf cnc_sim_scara_hal_pin_float_newf
#define identityKinematicsSetup cnc_sim_scara_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_scara_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_scara_identityKinematicsInverse
#define userkKinematicsSetup cnc_sim_scara_userkKinematicsSetup
#define userkKinematicsForward cnc_sim_scara_userkKinematicsForward
#define userkKinematicsInverse cnc_sim_scara_userkKinematicsInverse
#define switchkinsSetup cnc_sim_scara_switchkinsSetup
#define haldata cnc_sim_scara_haldata
#define hal_malloc(size) ((struct scara_data *)cnc_sim_scara_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/scarakins.c"
#undef hal_malloc
#undef haldata
#undef switchkinsSetup
#undef userkKinematicsInverse
#undef userkKinematicsForward
#undef userkKinematicsSetup
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef hal_pin_float_newf
#undef rtapi_print_msg
#undef rtapi_print
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_scarakins_setup(void) {
kparms kp = {0};
static char kinsname[] = "scarakins";
static char halprefix[] = "scarakins";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
return scaraKinematicsSetup(0, "XYZABC", &kp);
}
CNC_SIM_EXTERN_C void cnc_sim_linuxcnc_scarakins_set_parameters(double d1,
double d2,
double d3,
double d4,
double d5,
double d6) {
*cnc_sim_scara_haldata->d1 = d1;
*cnc_sim_scara_haldata->d2 = d2;
*cnc_sim_scara_haldata->d3 = d3;
*cnc_sim_scara_haldata->d4 = d4;
*cnc_sim_scara_haldata->d5 = d5;
*cnc_sim_scara_haldata->d6 = d6;
}
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_scarakins_forward(const double *joints,
struct EmcPose *pos,
int *iflags) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS raw_iflags = 0;
const int result = scaraKinematicsForward(joints, pos, &fflags, &raw_iflags);
if (iflags) {
*iflags = (int)raw_iflags;
}
return result;
}
CNC_SIM_EXTERN_C int cnc_sim_linuxcnc_scarakins_inverse(const struct EmcPose *pos,
double *joints,
int iflags) {
KINEMATICS_INVERSE_FLAGS raw_iflags = (KINEMATICS_INVERSE_FLAGS)iflags;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return scaraKinematicsInverse(pos, joints, &raw_iflags, &fflags);
}

View File

@@ -0,0 +1,144 @@
#include "linuxcnc_scarakins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_scarakins_setup(void);
void cnc_sim_linuxcnc_scarakins_set_parameters(double d1,
double d2,
double d3,
double d4,
double d5,
double d6);
int cnc_sim_linuxcnc_scarakins_forward(const double *joints, EmcPose *pos, int *iflags);
int cnc_sim_linuxcnc_scarakins_inverse(const EmcPose *pos,
double *joints,
int iflags);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_scarakins_setup() == 0;
return initialized;
}
void apply_parameters(const LinuxCncScaraParameters &parameters) {
cnc_sim_linuxcnc_scarakins_set_parameters(parameters.d1,
parameters.d2,
parameters.d3,
parameters.d4,
parameters.d5,
parameters.d6);
}
void to_joints(const LinuxCncScaraJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.j0;
out[1] = joints.j1;
out[2] = joints.j2;
out[3] = joints.j3;
out[4] = joints.j4;
out[5] = joints.j5;
}
LinuxCncScaraJoints from_joints(const double joints[16]) {
LinuxCncScaraJoints out{};
out.j0 = joints[0];
out.j1 = joints[1];
out.j2 = joints[2];
out.j3 = joints[3];
out.j4 = joints[4];
out.j5 = joints[5];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_scarakins_forward(const LinuxCncScaraJoints &joints,
const LinuxCncScaraParameters &parameters,
CncSimPose *pose,
int *iflags) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
int raw_iflags = 0;
if (cnc_sim_linuxcnc_scarakins_forward(raw_joints, &out, &raw_iflags) != 0) {
return false;
}
if (iflags) {
*iflags = raw_iflags;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_scarakins_inverse(const CncSimPose &pose,
const LinuxCncScaraParameters &parameters,
int iflags,
LinuxCncScaraJoints *joints) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_scarakins_inverse(&in, raw_joints, iflags) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_scarakins_forward(const LinuxCncScaraJoints &joints,
const LinuxCncScaraParameters &parameters,
CncSimPose *pose,
int *iflags);
bool linuxcnc_scarakins_inverse(const CncSimPose &pose,
const LinuxCncScaraParameters &parameters,
int iflags,
LinuxCncScaraJoints *joints);

View File

@@ -0,0 +1,121 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_GO_TYPES_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define PM_PI 3.1415926535897932384626433832795029
#define TO_RAD (PM_PI / 180.0)
#define TO_DEG (180.0 / PM_PI)
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_scorbot_kins_hal_init(const char *name) {
(void)name;
return 1;
}
int cnc_sim_scorbot_kins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_scorbot_kins_hal_exit(int comp_id) {
(void)comp_id;
}
#define hal_init cnc_sim_scorbot_kins_hal_init
#define hal_ready cnc_sim_scorbot_kins_hal_ready
#define hal_exit cnc_sim_scorbot_kins_hal_exit
#define kinematicsType cnc_sim_scorbot_kins_kinematicsType
#define kinematicsForward cnc_sim_scorbot_kins_kinematicsForward
#define kinematicsInverse cnc_sim_scorbot_kins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_scorbot_kins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_scorbot_kins_kinematicsSwitch
#define rtapi_app_main cnc_sim_scorbot_kins_rtapi_app_main
#define rtapi_app_exit cnc_sim_scorbot_kins_rtapi_app_exit
#define comp_id cnc_sim_scorbot_kins_comp_id
#include "../../../linuxcnc/src/emc/kinematics/scorbot-kins.c"
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_init
int cnc_sim_linuxcnc_scorbot_kins_setup(void) {
return cnc_sim_scorbot_kins_rtapi_app_main();
}
int cnc_sim_linuxcnc_scorbot_kins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_scorbot_kins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_scorbot_kins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_scorbot_kins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,110 @@
#include "linuxcnc_scorbot_kins_adapter.h"
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_scorbot_kins_setup(void);
int cnc_sim_linuxcnc_scorbot_kins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_scorbot_kins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_scorbot_kins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncScorbotJoints &joints, double out[5]) {
out[0] = joints.j0;
out[1] = joints.j1;
out[2] = joints.j2;
out[3] = joints.j3;
out[4] = joints.j4;
}
LinuxCncScorbotJoints from_joints(const double joints[5]) {
LinuxCncScorbotJoints out{};
out.j0 = joints[0];
out.j1 = joints[1];
out.j2 = joints[2];
out.j3 = joints[3];
out.j4 = joints[4];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_scorbot_kins_source_forward(const LinuxCncScorbotJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[5] = {};
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_scorbot_kins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_scorbot_kins_source_inverse(const CncSimPose &pose, LinuxCncScorbotJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[5] = {};
if (cnc_sim_linuxcnc_scorbot_kins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_scorbot_kins_source_forward(const LinuxCncScorbotJoints &joints, CncSimPose *pose);
bool linuxcnc_scorbot_kins_source_inverse(const CncSimPose &pose, LinuxCncScorbotJoints *joints);

View File

@@ -0,0 +1,110 @@
// Generated by ./generate-linuxcnc-switchkins-remap-table.sh.
// Source: LinuxCNC INI MACHINE/KINEMATICS/HALFILE/SUBROUTINE_PATH/REMAP entries and
// adjacent remap_subs/{428,429,430}remap.ngc #<kinstype> assignments.
{"configs/sim/axis/vismach/5axis/bridgemill/5axis.ini", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/bridgemill", 0, 1, 2},
{"bridgemill", 0, 1, 2},
{"5axis", 0, 1, 2},
{"sim-5axisbridgemill(xyzbcw)", 0, 1, 2},
{"sim-5axisbridgemill", 0, 1, 2},
{"5axiskinscoordinates=xyzbcwy", 0, 1, 2},
{"5axiskins", 0, 1, 2},
{"5axisgui.hal", 0, 1, 2},
{"5axisgui", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/bridgemill/remap_subs", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini", 1, 0, -1},
{"configs/sim/axis/vismach/5axis/table-dual-rotary", 1, 0, -1},
{"table-dual-rotary", 1, 0, -1},
{"xyzab-tdr", 1, 0, -1},
{"sim-xyzab-tdr-kins(switchkins)", 1, 0, -1},
{"sim-xyzab-tdr-kins", 1, 0, -1},
{"xyzab_tdr_kins", 1, 0, -1},
{"xyzab_tdr", 1, 0, -1},
{"xyzab-tdr-kins", 1, 0, -1},
{"configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs", 1, 0, -1},
{"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", 1, 0, 2},
{"configs/sim/axis/vismach/5axis/table-rotary-tilting", 1, 0, 2},
{"table-rotary-tilting", 1, 0, 2},
{"xyzac-trt", 1, 0, 2},
{"sim-xyzac-trt-kins(switchkins)", 1, 0, 2},
{"sim-xyzac-trt-kins", 1, 0, 2},
{"xyzac-trt-kinssparm=identityfirst", 1, 0, 2},
{"xyzac-trt-kins", 1, 0, 2},
{"configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs", 1, 0, 2},
{"configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini", 1, 0, 2},
{"xyzbc-trt", 1, 0, 2},
{"sim-xyzbc-trt-kins(switchkins)", 1, 0, 2},
{"sim-xyzbc-trt-kins", 1, 0, 2},
{"xyzbc-trt-kinssparm=identityfirst", 1, 0, 2},
{"xyzbc-trt-kins", 1, 0, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp", 0, 1, 2},
{"xyzacb-trsrn_twp", 0, 1, 2},
{"xyzacb-trsrn", 0, 1, 2},
{"xyzacb-trsrn(switchkins)", 0, 1, 2},
{"xyzacb_trsrn", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating", 0, 1, 2},
{"table-rotary_spindle-rotary-nutating", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini", 0, 1, 2},
{"configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp", 0, 1, 2},
{"xyzbca-trsrn_twp", 0, 1, 2},
{"xyzbca-trsrn", 0, 1, 2},
{"xyzbca-trsrn(switchkins)", 0, 1, 2},
{"xyzbca_trsrn", 0, 1, 2},
{"configs/sim/axis/vismach/hexapod-sim/hexapod.ini", 0, 1, 2},
{"configs/sim/axis/vismach/hexapod-sim", 0, 1, 2},
{"hexapod-sim", 0, 1, 2},
{"hexapod", 0, 1, 2},
{"hexapod(switchkins)", 0, 1, 2},
{"genhexkins", 0, 1, 2},
{"kinematics.hal", 0, 1, 2},
{"kinematics", 0, 1, 2},
{"configs/sim/axis/vismach/hexapod-sim/remap_subs", 0, 1, 2},
{"configs/sim/axis/vismach/melfa-sim/melfa.ini", 0, 1, 2},
{"configs/sim/axis/vismach/melfa-sim", 0, 1, 2},
{"melfa-sim", 0, 1, 2},
{"melfa", 0, 1, 2},
{"melfa(mm)", 0, 1, 2},
{"genserkins", 0, 1, 2},
{"melfa_dh.hal", 0, 1, 2},
{"melfa_dh", 0, 1, 2},
{"configs/sim/axis/vismach/melfa-sim/remap_subs", 0, 1, 2},
{"configs/sim/axis/vismach/millturn/millturn.ini", 0, 1, -1},
{"configs/sim/axis/vismach/millturn", 0, 1, -1},
{"millturn", 0, 1, -1},
{"millturn(mm)", 0, 1, -1},
{"millturn.hal", 0, 1, -1},
{"configs/sim/axis/vismach/millturn/remap_subs", 0, 1, -1},
{"configs/sim/axis/vismach/puma/puma.ini", 0, 1, 2},
{"configs/sim/axis/vismach/puma", 0, 1, 2},
{"puma", 0, 1, 2},
{"puma(pumakins,switchkins)", 0, 1, 2},
{"pumakins", 0, 1, 2},
{"puma_dh.hal", 0, 1, 2},
{"puma_dh", 0, 1, 2},
{"configs/sim/axis/vismach/puma/remap_subs", 0, 1, 2},
{"configs/sim/axis/vismach/puma/puma_cube.ini", 0, 1, 2},
{"puma_cube", 0, 1, 2},
{"puma_cube.ini(pumakins)", 0, 1, 2},
{"puma_cube.ini", 0, 1, 2},
{"configs/sim/axis/vismach/puma/puma560.ini", 0, 1, 2},
{"puma560", 0, 1, 2},
{"puma560(switchkins)(inch)", 0, 1, 2},
{"puma560_dh.hal", 0, 1, 2},
{"puma560_dh", 0, 1, 2},
{"configs/sim/axis/vismach/puma/puma560_uvw.ini", 0, 1, 2},
{"puma560_uvw", 0, 1, 2},
{"configs/sim/axis/vismach/scara/scara.ini", 0, 1, 2},
{"configs/sim/axis/vismach/scara", 0, 1, 2},
{"scara", 0, 1, 2},
{"scara(genserkins,switchkins)", 0, 1, 2},
{"scarakinscoordinates=xyzcab", 0, 1, 2},
{"scarakins", 0, 1, 2},
{"configs/sim/axis/vismach/scara/remap_subs", 0, 1, 2},
{"configs/sim/qtaxis/non-trivial/scara/scara.ini", 0, 1, 2},
{"configs/sim/qtaxis/non-trivial/scara", 0, 1, 2},
{"configs/sim/qtaxis/non-trivial/scara/remap_subs", 0, 1, 2},
{"configs/sim/qtvcp_screens/non-trivial/scara/scara.ini", 0, 1, 2},
{"configs/sim/qtvcp_screens/non-trivial/scara", 0, 1, 2},
{"configs/sim/qtvcp_screens/non-trivial/scara/remap_subs", 0, 1, 2},

View File

@@ -0,0 +1,142 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define __LINUXCNC_EMCPOS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
typedef double real_t;
typedef double hal_float_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
int cnc_sim_tripodkins_hal_init(const char *name) {
(void)name;
return 1;
}
void *cnc_sim_tripodkins_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_tripodkins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_tripodkins_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_tripodkins_hal_pin_float_new(const char *name,
hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
#define hal_init cnc_sim_tripodkins_hal_init
#define hal_malloc(size) ((struct haldata *)cnc_sim_tripodkins_hal_malloc(size))
#define hal_pin_float_new cnc_sim_tripodkins_hal_pin_float_new
#define hal_ready cnc_sim_tripodkins_hal_ready
#define hal_exit cnc_sim_tripodkins_hal_exit
#define kinematicsType cnc_sim_tripodkins_kinematicsType
#define kinematicsForward cnc_sim_tripodkins_kinematicsForward
#define kinematicsInverse cnc_sim_tripodkins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_tripodkins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_tripodkins_kinematicsSwitch
#define rtapi_app_main cnc_sim_tripodkins_rtapi_app_main
#define rtapi_app_exit cnc_sim_tripodkins_rtapi_app_exit
#define comp_id cnc_sim_tripodkins_comp_id
#define haldata cnc_sim_tripodkins_haldata
#include "../../../linuxcnc/src/emc/kinematics/tripodkins.c"
#undef haldata
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsType
#undef hal_exit
#undef hal_ready
#undef hal_pin_float_new
#undef hal_malloc
#undef hal_init
int cnc_sim_linuxcnc_tripodkins_setup(void) {
return cnc_sim_tripodkins_rtapi_app_main();
}
int cnc_sim_linuxcnc_tripodkins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_tripodkins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_tripodkins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_tripodkins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,94 @@
#include "linuxcnc_tripodkins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_tripodkins_setup(void);
int cnc_sim_linuxcnc_tripodkins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_tripodkins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_tripodkins_setup() == 0;
return initialized;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_tripodkins_source_forward(const LinuxCncTripodJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[3];
std::memcpy(raw_joints, joints.strut, sizeof(raw_joints));
EmcPose out{};
if (cnc_sim_linuxcnc_tripodkins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_tripodkins_source_inverse(const CncSimPose &pose, LinuxCncTripodJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose emc_pose = to_emc_pose(pose);
double raw_joints[3] = {};
if (cnc_sim_linuxcnc_tripodkins_inverse(&emc_pose, raw_joints) != 0) {
return false;
}
std::memcpy(joints->strut, raw_joints, sizeof(raw_joints));
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_tripodkins_source_forward(const LinuxCncTripodJoints &joints, CncSimPose *pose);
bool linuxcnc_tripodkins_source_inverse(const CncSimPose &pose, LinuxCncTripodJoints *joints);

View File

@@ -0,0 +1,163 @@
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_EMCPOS_H
#define __LINUXCNC_KINEMATICS_H
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define RTAPI_MP_STRING(name, desc)
#define RTAPI_MSG_ERR 1
#define EMCMOT_MAX_JOINTS 16
#define EMCMOT_MAX_AXIS 9
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#define KINS_NOT_SWITCHABLE \
extern int kinematicsSwitchable() { return 0; } \
extern int kinematicsSwitch(int switchkins_type) { (void)switchkins_type; return 0; }
#ifdef __cplusplus
extern "C" {
#endif
void cnc_sim_trivkins_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_trivkins_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
int cnc_sim_trivkins_hal_init(const char *name) {
(void)name;
return 1;
}
int cnc_sim_trivkins_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
void cnc_sim_trivkins_hal_exit(int comp_id) {
(void)comp_id;
}
#define rtapi_print cnc_sim_trivkins_rtapi_print
#define rtapi_print_msg cnc_sim_trivkins_rtapi_print_msg
#define kinematicsType cnc_sim_trivkins_kinematicsType
KINEMATICS_TYPE kinematicsType(void);
#define map_coordinates_to_jnumbers cnc_sim_trivkins_map_coordinates_to_jnumbers
#define mapped_joints_to_position cnc_sim_trivkins_mapped_joints_to_position
#define position_to_mapped_joints cnc_sim_trivkins_position_to_mapped_joints
#define identityKinematicsSetup cnc_sim_trivkins_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_trivkins_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_trivkins_identityKinematicsInverse
#include "../../../linuxcnc/src/emc/kinematics/kins_util.c"
#define hal_init cnc_sim_trivkins_hal_init
#define hal_ready cnc_sim_trivkins_hal_ready
#define hal_exit cnc_sim_trivkins_hal_exit
#define kinematicsForward cnc_sim_trivkins_kinematicsForward
#define kinematicsInverse cnc_sim_trivkins_kinematicsInverse
#define kinematicsSwitchable cnc_sim_trivkins_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_trivkins_kinematicsSwitch
#define rtapi_app_main cnc_sim_trivkins_rtapi_app_main
#define rtapi_app_exit cnc_sim_trivkins_rtapi_app_exit
#define comp_id cnc_sim_trivkins_comp_id
#define coordinates cnc_sim_trivkins_coordinates
#define kinstype cnc_sim_trivkins_kinstype
#include "../../../linuxcnc/src/emc/kinematics/trivkins.c"
#undef kinstype
#undef coordinates
#undef comp_id
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsInverse
#undef kinematicsForward
#undef hal_exit
#undef hal_ready
#undef hal_init
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef position_to_mapped_joints
#undef mapped_joints_to_position
#undef map_coordinates_to_jnumbers
#undef kinematicsType
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_trivkins_setup(void) {
return cnc_sim_trivkins_rtapi_app_main();
}
int cnc_sim_linuxcnc_trivkins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_trivkins_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_trivkins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_trivkins_kinematicsInverse(pos, joints, &iflags, &fflags);
}
int cnc_sim_linuxcnc_trivkins_type(void) {
return (int)cnc_sim_trivkins_kinematicsType();
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,129 @@
#include "linuxcnc_trivkins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_trivkins_setup(void);
int cnc_sim_linuxcnc_trivkins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_trivkins_inverse(const EmcPose *pos, double *joints);
int cnc_sim_linuxcnc_trivkins_type(void);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_trivkins_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_trivkins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_trivkins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_trivkins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_trivkins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}
int linuxcnc_trivkins_source_kinematics_type() {
if (!ensure_initialized()) {
return 0;
}
return cnc_sim_linuxcnc_trivkins_type();
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_trivkins_source_forward(const LinuxCncAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_trivkins_source_inverse(const CncSimPose &pose, LinuxCncAxisJoints *joints);
int linuxcnc_trivkins_source_kinematics_type();

View File

@@ -0,0 +1,207 @@
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_RTAPI_CTYPE_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_KINEMATICS_H
#define RTAPI_MSG_ERR 1
#define PM_PI 3.1415926535897932384626433832795029
#define TO_RAD (PM_PI / 180.0)
#define EMCMOT_MAX_JOINTS 16
#define EMCMOT_MAX_AXIS 9
typedef double real_t;
typedef double hal_float_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
static int cnc_sim_axis_idx_for_jno[EMCMOT_MAX_JOINTS];
static int cnc_sim_max_joints;
#ifdef __cplusplus
extern "C" {
#endif
void rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int hal_pin_float_newf(hal_pin_dir_t dir, hal_float_t **data_ptr_addr, int comp_id, const char *fmt, ...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int hal_pin_bit_newf(hal_pin_dir_t dir, hal_bit_t **data_ptr_addr, int comp_id, const char *fmt, ...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_bit_t *)calloc(1, sizeof(hal_bit_t));
return *data_ptr_addr ? 0 : -1;
}
int map_coordinates_to_jnumbers(const char *coordinates,
const int max_joints,
const int allow_duplicates,
int axis_idx_for_jno[]) {
(void)allow_duplicates;
const char *letters = "XYZABCUVW";
int jno = 0;
for (int i = 0; i < EMCMOT_MAX_JOINTS; ++i) {
axis_idx_for_jno[i] = -1;
cnc_sim_axis_idx_for_jno[i] = -1;
}
while (*coordinates) {
const char *found = strchr(letters, toupper((unsigned char)*coordinates));
if (!found || jno >= max_joints) {
return -1;
}
axis_idx_for_jno[jno++] = (int)(found - letters);
++coordinates;
}
cnc_sim_max_joints = jno;
for (int i = 0; i < EMCMOT_MAX_JOINTS; ++i) {
cnc_sim_axis_idx_for_jno[i] = axis_idx_for_jno[i];
}
return 0;
}
int position_to_mapped_joints(const int max_joints, const EmcPose *pos, double *joints) {
for (int jno = 0; jno < max_joints; ++jno) {
switch (cnc_sim_axis_idx_for_jno[jno]) {
case 0: joints[jno] = pos->tran.x; break;
case 1: joints[jno] = pos->tran.y; break;
case 2: joints[jno] = pos->tran.z; break;
case 3: joints[jno] = pos->a; break;
case 4: joints[jno] = pos->b; break;
case 5: joints[jno] = pos->c; break;
case 6: joints[jno] = pos->u; break;
case 7: joints[jno] = pos->v; break;
case 8: joints[jno] = pos->w; break;
default: joints[jno] = 0.0; break;
}
}
return 0;
}
#define hal_malloc(size) ((struct haldata *)cnc_sim_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/trtfuncs.c"
#undef hal_malloc
void cnc_sim_linuxcnc_trtfuncs_reset_setup_state(void) {
trtfuncs_max_joints = 0;
JX = -1;
JY = -1;
JZ = -1;
JA = -1;
JB = -1;
JC = -1;
JU = -1;
JV = -1;
JW = -1;
haldata = NULL;
cnc_sim_max_joints = 0;
for (int i = 0; i < EMCMOT_MAX_JOINTS; ++i) {
cnc_sim_axis_idx_for_jno[i] = -1;
}
}
int cnc_sim_linuxcnc_trtfuncs_setup_xyzbc(void) {
kparms kp = {0};
static char kinsname[] = "xyzbc-trt-kins";
static char halprefix[] = "xyzbc-trt-kins";
static char required_coordinates[] = "XYZBC";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.required_coordinates = required_coordinates;
kp.max_joints = EMCMOT_MAX_JOINTS;
kp.allow_duplicates = 1;
return trtKinematicsSetup(0, "XYZBC", &kp);
}
int cnc_sim_linuxcnc_trtfuncs_setup_xyzac(void) {
kparms kp = {0};
static char kinsname[] = "xyzac-trt-kins";
static char halprefix[] = "xyzac-trt-kins";
static char required_coordinates[] = "XYZAC";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.required_coordinates = required_coordinates;
kp.max_joints = EMCMOT_MAX_JOINTS;
kp.allow_duplicates = 1;
return trtKinematicsSetup(0, "XYZAC", &kp);
}
void cnc_sim_linuxcnc_trtfuncs_set_pins(double x_rot_point,
double y_rot_point,
double z_rot_point,
double x_offset,
double y_offset,
double z_offset,
double tool_offset,
bool conventional_directions) {
*haldata->x_rot_point = x_rot_point;
*haldata->y_rot_point = y_rot_point;
*haldata->z_rot_point = z_rot_point;
*haldata->x_offset = x_offset;
*haldata->y_offset = y_offset;
*haldata->z_offset = z_offset;
*haldata->tool_offset = tool_offset;
*haldata->conventional_directions = conventional_directions;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,241 @@
#include "linuxcnc_trtfuncs_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
int cnc_sim_linuxcnc_trtfuncs_setup_xyzbc(void);
int cnc_sim_linuxcnc_trtfuncs_setup_xyzac(void);
void cnc_sim_linuxcnc_trtfuncs_set_pins(double x_rot_point,
double y_rot_point,
double z_rot_point,
double x_offset,
double y_offset,
double z_offset,
double tool_offset,
bool conventional_directions);
void cnc_sim_linuxcnc_trtfuncs_reset_setup_state(void);
int xyzbcKinematicsForward(const double *joints,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
int xyzbcKinematicsInverse(const EmcPose *pos,
double *joints,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
int xyzacKinematicsForward(const double *joints,
EmcPose *pos,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags);
int xyzacKinematicsInverse(const EmcPose *pos,
double *joints,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags);
}
namespace {
enum class TrtSetup {
None,
Xyzbc,
Xyzac,
};
TrtSetup current_setup = TrtSetup::None;
bool ensure_xyzbc() {
if (current_setup == TrtSetup::Xyzbc) {
return true;
}
cnc_sim_linuxcnc_trtfuncs_reset_setup_state();
if (cnc_sim_linuxcnc_trtfuncs_setup_xyzbc() != 0) {
current_setup = TrtSetup::None;
return false;
}
current_setup = TrtSetup::Xyzbc;
return true;
}
bool ensure_xyzac() {
if (current_setup == TrtSetup::Xyzac) {
return true;
}
cnc_sim_linuxcnc_trtfuncs_reset_setup_state();
if (cnc_sim_linuxcnc_trtfuncs_setup_xyzac() != 0) {
current_setup = TrtSetup::None;
return false;
}
current_setup = TrtSetup::Xyzac;
return true;
}
void apply_parameters(const LinuxCncXyzbcTrtParameters &parameters) {
cnc_sim_linuxcnc_trtfuncs_set_pins(parameters.x_rot_point,
parameters.y_rot_point,
parameters.z_rot_point,
parameters.x_offset,
parameters.y_offset,
parameters.z_offset,
parameters.tool_offset,
parameters.conventional_directions);
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
void to_xyzbc_joints(const LinuxCncFiveAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.b;
out[4] = joints.c;
}
void to_xyzac_joints(const LinuxCncFiveAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.c;
}
LinuxCncFiveAxisJoints from_xyzbc_joints(const double joints[16]) {
LinuxCncFiveAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.b = joints[3];
out.c = joints[4];
return out;
}
LinuxCncFiveAxisJoints from_xyzac_joints(const double joints[16]) {
LinuxCncFiveAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.c = joints[4];
return out;
}
} // namespace
bool linuxcnc_trtfuncs_xyzbc_forward(const LinuxCncFiveAxisJoints &joints,
const LinuxCncXyzbcTrtParameters &parameters,
CncSimPose *pose) {
if (!ensure_xyzbc()) {
return false;
}
apply_parameters(parameters);
double raw_joints[16];
to_xyzbc_joints(joints, raw_joints);
EmcPose out{};
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
if (xyzbcKinematicsForward(raw_joints, &out, &fflags, &iflags) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_trtfuncs_xyzbc_inverse(const CncSimPose &pose,
const LinuxCncXyzbcTrtParameters &parameters,
LinuxCncFiveAxisJoints *joints) {
if (!ensure_xyzbc()) {
return false;
}
apply_parameters(parameters);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
if (xyzbcKinematicsInverse(&in, raw_joints, &iflags, &fflags) != 0) {
return false;
}
*joints = from_xyzbc_joints(raw_joints);
return true;
}
bool linuxcnc_trtfuncs_xyzac_forward(const LinuxCncFiveAxisJoints &joints,
const LinuxCncXyzbcTrtParameters &parameters,
CncSimPose *pose) {
if (!ensure_xyzac()) {
return false;
}
apply_parameters(parameters);
double raw_joints[16];
to_xyzac_joints(joints, raw_joints);
EmcPose out{};
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
if (xyzacKinematicsForward(raw_joints, &out, &fflags, &iflags) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_trtfuncs_xyzac_inverse(const CncSimPose &pose,
const LinuxCncXyzbcTrtParameters &parameters,
LinuxCncFiveAxisJoints *joints) {
if (!ensure_xyzac()) {
return false;
}
apply_parameters(parameters);
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
if (xyzacKinematicsInverse(&in, raw_joints, &iflags, &fflags) != 0) {
return false;
}
*joints = from_xyzac_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_trtfuncs_xyzbc_forward(const LinuxCncFiveAxisJoints &joints,
const LinuxCncXyzbcTrtParameters &parameters,
CncSimPose *pose);
bool linuxcnc_trtfuncs_xyzbc_inverse(const CncSimPose &pose,
const LinuxCncXyzbcTrtParameters &parameters,
LinuxCncFiveAxisJoints *joints);
bool linuxcnc_trtfuncs_xyzac_forward(const LinuxCncFiveAxisJoints &joints,
const LinuxCncXyzbcTrtParameters &parameters,
CncSimPose *pose);
bool linuxcnc_trtfuncs_xyzac_inverse(const CncSimPose &pose,
const LinuxCncXyzbcTrtParameters &parameters,
LinuxCncFiveAxisJoints *joints);

View File

@@ -0,0 +1,154 @@
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_EMCMOTCFG_H
#define __LINUXCNC_EMCPOS_H
#define __LINUXCNC_KINEMATICS_H
#define RTAPI_MSG_ERR 1
#define EMCMOT_MAX_JOINTS 16
#define EMCMOT_MAX_AXIS 9
typedef double hal_float_t;
typedef int hal_s32_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#ifdef __cplusplus
extern "C" {
#endif
void cnc_sim_userk_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_userk_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_userk_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_userk_hal_pin_s32_new(const char *name,
hal_pin_dir_t dir,
hal_s32_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_s32_t *)calloc(1, sizeof(hal_s32_t));
return *data_ptr_addr ? 0 : -1;
}
KINEMATICS_TYPE cnc_sim_userk_kinematicsType(void) {
return KINEMATICS_BOTH;
}
#define rtapi_print cnc_sim_userk_rtapi_print
#define rtapi_print_msg cnc_sim_userk_rtapi_print_msg
#define kinematicsType cnc_sim_userk_kinematicsType
#define hal_pin_s32_new cnc_sim_userk_hal_pin_s32_new
#define map_coordinates_to_jnumbers cnc_sim_userk_map_coordinates_to_jnumbers
#define mapped_joints_to_position cnc_sim_userk_mapped_joints_to_position
#define position_to_mapped_joints cnc_sim_userk_position_to_mapped_joints
#define identityKinematicsSetup cnc_sim_userk_identityKinematicsSetup
#define identityKinematicsForward cnc_sim_userk_identityKinematicsForward
#define identityKinematicsInverse cnc_sim_userk_identityKinematicsInverse
#define userkKinematicsSetup cnc_sim_userk_userkKinematicsSetup
#define userkKinematicsForward cnc_sim_userk_userkKinematicsForward
#define userkKinematicsInverse cnc_sim_userk_userkKinematicsInverse
#include "../../../linuxcnc/src/emc/kinematics/kins_util.c"
#define hal_malloc(size) ((struct udata *)cnc_sim_userk_hal_malloc(size))
#include "../../../linuxcnc/src/emc/kinematics/userkfuncs.c"
#undef hal_malloc
#undef userkKinematicsInverse
#undef userkKinematicsForward
#undef userkKinematicsSetup
#undef identityKinematicsInverse
#undef identityKinematicsForward
#undef identityKinematicsSetup
#undef position_to_mapped_joints
#undef mapped_joints_to_position
#undef map_coordinates_to_jnumbers
#undef hal_pin_s32_new
#undef kinematicsType
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_userkfuncs_setup(void) {
kparms kp = {0};
static char kinsname[] = "userkfuncs";
static char halprefix[] = "userk";
kp.kinsname = kinsname;
kp.halprefix = halprefix;
kp.max_joints = EMCMOT_MAX_JOINTS;
kp.allow_duplicates = 1;
if (cnc_sim_userk_identityKinematicsSetup(0, "XYZBC", &kp) != 0) {
return -1;
}
return cnc_sim_userk_userkKinematicsSetup(0, "XYZBC", &kp);
}
int cnc_sim_linuxcnc_userkfuncs_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_userk_userkKinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_userkfuncs_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_userk_userkKinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,113 @@
#include "linuxcnc_userkfuncs_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_userkfuncs_setup(void);
int cnc_sim_linuxcnc_userkfuncs_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_userkfuncs_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_userkfuncs_setup() == 0;
return initialized;
}
void to_joints(const LinuxCncFiveAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.b;
out[4] = joints.c;
}
LinuxCncFiveAxisJoints from_joints(const double joints[16]) {
LinuxCncFiveAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.b = joints[3];
out.c = joints[4];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_userkfuncs_forward(const LinuxCncFiveAxisJoints &joints, CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_userkfuncs_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_userkfuncs_inverse(const CncSimPose &pose, LinuxCncFiveAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_userkfuncs_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_userkfuncs_forward(const LinuxCncFiveAxisJoints &joints, CncSimPose *pose);
bool linuxcnc_userkfuncs_inverse(const CncSimPose &pose, LinuxCncFiveAxisJoints *joints);

View File

@@ -0,0 +1,241 @@
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __LINUXCNC_RTAPI_H
#define __LINUXCNC_RTAPI_APP_H
#define __LINUXCNC_RTAPI_STRING_H
#define __LINUXCNC_RTAPI_ERRNO_H
#define __LINUXCNC_RTAPI_MATH_H
#define __LINUXCNC_RTAPI_MATH64_H
#define __LINUXCNC_HAL_H
#define __LINUXCNC_KINEMATICS_H
#define MODULE_INFO(...)
#define MODULE_LICENSE(...)
#define EXPORT_SYMBOL(symbol)
#define RTAPI_MP_INT(name, description)
#define RTAPI_MP_STRING(name, description)
#define RTAPI_MSG_ERR 1
#define RTAPI_MSG_INFO 2
#define HAL_NAME_LEN 47
#define EINVAL 22
#define PM_PI 3.1415926535897932384626433832795029
#define TO_RAD (PM_PI / 180.0)
typedef double real_t;
typedef double hal_float_t;
typedef int hal_s32_t;
typedef unsigned int hal_u32_t;
typedef bool hal_bit_t;
typedef enum { HAL_IN = 16, HAL_OUT = 32, HAL_IO = (HAL_IN | HAL_OUT) } hal_pin_dir_t;
typedef struct {
double x;
double y;
double z;
} PmCartesian;
typedef struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
} EmcPose;
typedef enum {
KINEMATICS_IDENTITY = 1,
KINEMATICS_FORWARD_ONLY,
KINEMATICS_INVERSE_ONLY,
KINEMATICS_BOTH
} KINEMATICS_TYPE;
typedef unsigned long int KINEMATICS_FORWARD_FLAGS;
typedef unsigned long int KINEMATICS_INVERSE_FLAGS;
typedef struct kinematics_parms {
char *sparm;
char *kinsname;
char *halprefix;
char *required_coordinates;
int max_joints;
int allow_duplicates;
int fwd_iterates_mask;
int gui_kinstype;
} kparms;
#ifdef __cplusplus
extern "C" {
#endif
int __attribute__((weak)) rtapi_snprintf(char *str, unsigned long int size, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
const int result = vsnprintf(str, (size_t)size, fmt, args);
va_end(args);
return result;
}
void cnc_sim_xyzab_tdr_rtapi_print(const char *fmt, ...) {
(void)fmt;
}
void cnc_sim_xyzab_tdr_rtapi_print_msg(int level, const char *fmt, ...) {
(void)level;
(void)fmt;
}
void *cnc_sim_xyzab_tdr_hal_malloc(long int size) {
return calloc(1, (size_t)size);
}
int cnc_sim_xyzab_tdr_hal_init(const char *name) {
(void)name;
return 1;
}
void cnc_sim_xyzab_tdr_hal_exit(int comp_id) {
(void)comp_id;
}
int cnc_sim_xyzab_tdr_hal_ready(int comp_id) {
(void)comp_id;
return 0;
}
int cnc_sim_xyzab_tdr_hal_set_unready(int comp_id) {
(void)comp_id;
return 0;
}
int cnc_sim_xyzab_tdr_hal_pin_s32_newf(hal_pin_dir_t dir,
hal_s32_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_s32_t *)calloc(1, sizeof(hal_s32_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_xyzab_tdr_hal_pin_float_newf(hal_pin_dir_t dir,
hal_float_t **data_ptr_addr,
int comp_id,
const char *fmt,
...) {
(void)dir;
(void)comp_id;
(void)fmt;
*data_ptr_addr = (hal_float_t *)calloc(1, sizeof(hal_float_t));
return *data_ptr_addr ? 0 : -1;
}
int cnc_sim_xyzab_tdr_hal_pin_bit_new(const char *name,
hal_pin_dir_t dir,
hal_bit_t **data_ptr_addr,
int comp_id) {
(void)name;
(void)dir;
(void)comp_id;
*data_ptr_addr = (hal_bit_t *)calloc(1, sizeof(hal_bit_t));
return *data_ptr_addr ? 0 : -1;
}
#define rtapi_print cnc_sim_xyzab_tdr_rtapi_print
#define rtapi_print_msg cnc_sim_xyzab_tdr_rtapi_print_msg
#define hal_malloc(size) cnc_sim_xyzab_tdr_hal_malloc(size)
#define hal_init cnc_sim_xyzab_tdr_hal_init
#define hal_exit cnc_sim_xyzab_tdr_hal_exit
#define hal_ready cnc_sim_xyzab_tdr_hal_ready
#define hal_set_unready cnc_sim_xyzab_tdr_hal_set_unready
#define hal_pin_s32_newf cnc_sim_xyzab_tdr_hal_pin_s32_newf
#define hal_pin_float_newf cnc_sim_xyzab_tdr_hal_pin_float_newf
#define hal_pin_bit_new cnc_sim_xyzab_tdr_hal_pin_bit_new
#define kinematicsType cnc_sim_xyzab_tdr_kinematicsType
#define kinematicsSwitchable cnc_sim_xyzab_tdr_kinematicsSwitchable
#define kinematicsSwitch cnc_sim_xyzab_tdr_kinematicsSwitch
#define kinematicsForward cnc_sim_xyzab_tdr_kinematicsForward
#define kinematicsInverse cnc_sim_xyzab_tdr_kinematicsInverse
#define rtapi_app_main cnc_sim_xyzab_tdr_rtapi_app_main
#define rtapi_app_exit cnc_sim_xyzab_tdr_rtapi_app_exit
#define export cnc_sim_xyzab_tdr_export
#include "../../../linuxcnc/src/objects/hal/components/xyzab_tdr_kins.c"
#undef export
#undef rtapi_app_exit
#undef rtapi_app_main
#undef kinematicsInverse
#undef kinematicsForward
#undef kinematicsSwitch
#undef kinematicsSwitchable
#undef kinematicsType
#undef hal_pin_bit_new
#undef hal_pin_float_newf
#undef hal_pin_s32_newf
#undef hal_set_unready
#undef hal_ready
#undef hal_exit
#undef hal_init
#undef hal_malloc
#undef rtapi_print_msg
#undef rtapi_print
int cnc_sim_linuxcnc_xyzab_tdr_kins_setup(void) {
return cnc_sim_xyzab_tdr_kinematicsType() == KINEMATICS_BOTH ? 0 : -1;
}
void cnc_sim_linuxcnc_xyzab_tdr_kins_set_parameters(double tool_offset_z,
double x_offset,
double z_offset,
double x_rot_point,
double y_rot_point,
double z_rot_point) {
*haldata->tool_offset_z = tool_offset_z;
*haldata->x_offset = x_offset;
*haldata->z_offset = z_offset;
*haldata->x_rot_point = x_rot_point;
*haldata->y_rot_point = y_rot_point;
*haldata->z_rot_point = z_rot_point;
}
int cnc_sim_linuxcnc_xyzab_tdr_kins_switch(int switchkins_type) {
return cnc_sim_xyzab_tdr_kinematicsSwitch(switchkins_type);
}
int cnc_sim_linuxcnc_xyzab_tdr_kins_switch_state(int *kinstype_is_0, int *kinstype_is_1) {
if (!haldata || !haldata->kinstype_is_0 || !haldata->kinstype_is_1) {
return -1;
}
if (kinstype_is_0) {
*kinstype_is_0 = *haldata->kinstype_is_0 ? 1 : 0;
}
if (kinstype_is_1) {
*kinstype_is_1 = *haldata->kinstype_is_1 ? 1 : 0;
}
return 0;
}
int cnc_sim_linuxcnc_xyzab_tdr_kins_forward(const double *joints, EmcPose *pos) {
KINEMATICS_FORWARD_FLAGS fflags = 0;
KINEMATICS_INVERSE_FLAGS iflags = 0;
return cnc_sim_xyzab_tdr_kinematicsForward(joints, pos, &fflags, &iflags);
}
int cnc_sim_linuxcnc_xyzab_tdr_kins_inverse(const EmcPose *pos, double *joints) {
KINEMATICS_INVERSE_FLAGS iflags = 0;
KINEMATICS_FORWARD_FLAGS fflags = 0;
return cnc_sim_xyzab_tdr_kinematicsInverse(pos, joints, &iflags, &fflags);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,177 @@
#include "linuxcnc_xyzab_tdr_kins_adapter.h"
#include <cstring>
extern "C" {
struct PmCartesian {
double x;
double y;
double z;
};
struct EmcPose {
PmCartesian tran;
double a;
double b;
double c;
double u;
double v;
double w;
};
int cnc_sim_linuxcnc_xyzab_tdr_kins_setup(void);
void cnc_sim_linuxcnc_xyzab_tdr_kins_set_parameters(double tool_offset_z,
double x_offset,
double z_offset,
double x_rot_point,
double y_rot_point,
double z_rot_point);
int cnc_sim_linuxcnc_xyzab_tdr_kins_switch(int switchkins_type);
int cnc_sim_linuxcnc_xyzab_tdr_kins_switch_state(int *kinstype_is_0, int *kinstype_is_1);
int cnc_sim_linuxcnc_xyzab_tdr_kins_forward(const double *joints, EmcPose *pos);
int cnc_sim_linuxcnc_xyzab_tdr_kins_inverse(const EmcPose *pos, double *joints);
}
namespace {
bool initialized = false;
bool ensure_initialized() {
if (initialized) {
return true;
}
initialized = cnc_sim_linuxcnc_xyzab_tdr_kins_setup() == 0;
return initialized;
}
void apply_parameters(const LinuxCncXyzabTdrParameters &parameters) {
cnc_sim_linuxcnc_xyzab_tdr_kins_set_parameters(parameters.tool_offset_z,
parameters.x_offset,
parameters.z_offset,
parameters.x_rot_point,
parameters.y_rot_point,
parameters.z_rot_point);
}
void to_joints(const LinuxCncAxisJoints &joints, double out[16]) {
std::memset(out, 0, sizeof(double) * 16);
out[0] = joints.x;
out[1] = joints.y;
out[2] = joints.z;
out[3] = joints.a;
out[4] = joints.b;
out[5] = joints.c;
out[6] = joints.u;
out[7] = joints.v;
out[8] = joints.w;
}
LinuxCncAxisJoints from_joints(const double joints[16]) {
LinuxCncAxisJoints out{};
out.x = joints[0];
out.y = joints[1];
out.z = joints[2];
out.a = joints[3];
out.b = joints[4];
out.c = joints[5];
out.u = joints[6];
out.v = joints[7];
out.w = joints[8];
return out;
}
EmcPose to_emc_pose(const CncSimPose &pose) {
EmcPose emc{};
emc.tran.x = pose.x;
emc.tran.y = pose.y;
emc.tran.z = pose.z;
emc.a = pose.a;
emc.b = pose.b;
emc.c = pose.c;
emc.u = pose.u;
emc.v = pose.v;
emc.w = pose.w;
return emc;
}
CncSimPose from_emc_pose(const EmcPose &emc) {
CncSimPose pose{};
pose.x = emc.tran.x;
pose.y = emc.tran.y;
pose.z = emc.tran.z;
pose.a = emc.a;
pose.b = emc.b;
pose.c = emc.c;
pose.u = emc.u;
pose.v = emc.v;
pose.w = emc.w;
return pose;
}
} // namespace
bool linuxcnc_xyzab_tdr_kins_switch(int switchkins_type) {
if (!ensure_initialized()) {
return false;
}
return cnc_sim_linuxcnc_xyzab_tdr_kins_switch(switchkins_type) == 0;
}
bool linuxcnc_xyzab_tdr_kins_switch_state(bool *kinstype_is_0, bool *kinstype_is_1) {
if (!ensure_initialized()) {
return false;
}
int raw_kinstype_is_0 = 0;
int raw_kinstype_is_1 = 0;
if (cnc_sim_linuxcnc_xyzab_tdr_kins_switch_state(&raw_kinstype_is_0, &raw_kinstype_is_1) != 0) {
return false;
}
if (kinstype_is_0) {
*kinstype_is_0 = raw_kinstype_is_0 != 0;
}
if (kinstype_is_1) {
*kinstype_is_1 = raw_kinstype_is_1 != 0;
}
return true;
}
bool linuxcnc_xyzab_tdr_kins_forward(const LinuxCncAxisJoints &joints,
const LinuxCncXyzabTdrParameters &parameters,
int switchkins_type,
CncSimPose *pose) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
if (!linuxcnc_xyzab_tdr_kins_switch(switchkins_type)) {
return false;
}
double raw_joints[16];
to_joints(joints, raw_joints);
EmcPose out{};
if (cnc_sim_linuxcnc_xyzab_tdr_kins_forward(raw_joints, &out) != 0) {
return false;
}
*pose = from_emc_pose(out);
return true;
}
bool linuxcnc_xyzab_tdr_kins_inverse(const CncSimPose &pose,
const LinuxCncXyzabTdrParameters &parameters,
int switchkins_type,
LinuxCncAxisJoints *joints) {
if (!ensure_initialized()) {
return false;
}
apply_parameters(parameters);
if (!linuxcnc_xyzab_tdr_kins_switch(switchkins_type)) {
return false;
}
const EmcPose in = to_emc_pose(pose);
double raw_joints[16] = {};
if (cnc_sim_linuxcnc_xyzab_tdr_kins_inverse(&in, raw_joints) != 0) {
return false;
}
*joints = from_joints(raw_joints);
return true;
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "rtcp_kinematics.h"
bool linuxcnc_xyzab_tdr_kins_switch(int switchkins_type);
bool linuxcnc_xyzab_tdr_kins_switch_state(bool *kinstype_is_0, bool *kinstype_is_1);
bool linuxcnc_xyzab_tdr_kins_forward(const LinuxCncAxisJoints &joints,
const LinuxCncXyzabTdrParameters &parameters,
int switchkins_type,
CncSimPose *pose);
bool linuxcnc_xyzab_tdr_kins_inverse(const CncSimPose &pose,
const LinuxCncXyzabTdrParameters &parameters,
int switchkins_type,
LinuxCncAxisJoints *joints);

File diff suppressed because it is too large Load Diff

View File

@@ -83,12 +83,78 @@ struct LinuxCncScaraJoints {
double j5;
};
struct LinuxCncGenhexJoints {
double strut[6];
};
struct LinuxCncPentakinsJoints {
double strut[5];
};
struct LinuxCncTripodJoints {
double strut[3];
};
struct LinuxCncScorbotJoints {
double j0;
double j1;
double j2;
double j3;
double j4;
};
struct LinuxCncLinearDeltaParameters {
double r;
double l;
};
struct LinuxCncRotaryDeltaParameters {
double platformradius;
double thighlength;
double shinlength;
double footradius;
};
struct LinuxCncMaxkinsParameters {
double pivot_length;
bool conventional_directions;
};
LinuxCncAxisJoints linuxcnc_identity_default_joints();
CncSimPose linuxcnc_identity_forward(const LinuxCncAxisJoints &joints);
LinuxCncAxisJoints linuxcnc_identity_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_corexykins_forward(const LinuxCncAxisJoints &joints);
LinuxCncAxisJoints linuxcnc_corexykins_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_rotatekins_forward(const LinuxCncAxisJoints &joints);
LinuxCncAxisJoints linuxcnc_rotatekins_inverse(const CncSimPose &pose);
LinuxCncGenhexJoints linuxcnc_genhex_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_genhex_forward(const LinuxCncGenhexJoints &joints, const CncSimPose &initial_pose);
LinuxCncPentakinsJoints linuxcnc_pentakins_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_pentakins_forward(const LinuxCncPentakinsJoints &joints,
const CncSimPose &initial_pose);
LinuxCncTripodJoints linuxcnc_tripodkins_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_tripodkins_forward(const LinuxCncTripodJoints &joints);
LinuxCncScorbotJoints linuxcnc_scorbot_kins_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_scorbot_kins_forward(const LinuxCncScorbotJoints &joints);
LinuxCncLinearDeltaParameters linuxcnc_lineardelta_default_parameters();
CncSimPose linuxcnc_lineardelta_forward(const LinuxCncAxisJoints &joints,
const LinuxCncLinearDeltaParameters &parameters);
LinuxCncAxisJoints linuxcnc_lineardelta_inverse(const CncSimPose &pose,
const LinuxCncLinearDeltaParameters &parameters);
LinuxCncRotaryDeltaParameters linuxcnc_rotarydelta_default_parameters();
CncSimPose linuxcnc_rotarydelta_forward(const LinuxCncAxisJoints &joints,
const LinuxCncRotaryDeltaParameters &parameters);
LinuxCncAxisJoints linuxcnc_rotarydelta_inverse(const CncSimPose &pose,
const LinuxCncRotaryDeltaParameters &parameters);
LinuxCncMaxkinsParameters linuxcnc_maxkins_default_parameters();
CncSimPose linuxcnc_maxkins_forward(const LinuxCncAxisJoints &joints,
const LinuxCncMaxkinsParameters &parameters);
LinuxCncAxisJoints linuxcnc_maxkins_inverse(const CncSimPose &pose,
const LinuxCncMaxkinsParameters &parameters);
CncSimPose linuxcnc_rosekins_forward(const LinuxCncAxisJoints &joints);
LinuxCncAxisJoints linuxcnc_rosekins_inverse(const CncSimPose &pose);
CncSimPose linuxcnc_5axis_forward(const LinuxCncFiveAxisJoints &joints, double pivot_length);
LinuxCncFiveAxisJoints linuxcnc_5axis_inverse(const CncSimPose &pose, double pivot_length);
@@ -132,6 +198,7 @@ LinuxCncAxisJoints linuxcnc_puma_inverse(const CncSimPose &pose,
int *fflags);
LinuxCncGenserParameters linuxcnc_genser_puma560_parameters();
LinuxCncGenserParameters linuxcnc_genser_default_parameters(int *max_iterations = nullptr);
CncSimPose linuxcnc_genser_forward(const LinuxCncAxisJoints &joints,
const LinuxCncGenserParameters &parameters);
LinuxCncAxisJoints linuxcnc_genser_inverse(const CncSimPose &pose,
@@ -139,3 +206,9 @@ LinuxCncAxisJoints linuxcnc_genser_inverse(const CncSimPose &pose,
const LinuxCncGenserParameters &parameters,
int *iterations,
int max_iterations = 100);
bool linuxcnc_genser_inverse_checked(const CncSimPose &pose,
const LinuxCncAxisJoints &joint_estimate,
const LinuxCncGenserParameters &parameters,
LinuxCncAxisJoints *joints,
int *iterations,
int max_iterations = 100);

View File

@@ -295,12 +295,25 @@ bool parse_simulator_gcode_control_line(const std::string &line,
return false;
}
void emit_simulator_gcode_control_action(CanonEventSink &sink,
bool can_emit_simulator_gcode_control_action(const CanonEventSink &sink,
const SimulatorGcodeControlAction &action) {
if (action.kind == SimulatorGcodeControlKind::KinematicsSwitch) {
return sink.can_switch_m_code_kinematics(action.m_code);
}
if (action.kind == SimulatorGcodeControlKind::RtcpState) {
return true;
}
return false;
}
bool emit_simulator_gcode_control_action(CanonEventSink &sink,
const SimulatorGcodeControlAction &action,
int line) {
if (action.kind == SimulatorGcodeControlKind::KinematicsSwitch) {
sink.switch_m_code_kinematics(action.m_code, action.value, line);
return sink.switch_m_code_kinematics(action.m_code, action.value, line);
} else if (action.kind == SimulatorGcodeControlKind::RtcpState) {
sink.set_rtcp_state(action.rtcp_enabled, action.h_code, line);
return true;
}
return false;
}

View File

@@ -23,6 +23,8 @@ bool parse_simulator_gcode_control_line(const std::string &line,
bool parse_simulator_gcode_control_line(const std::string &line,
bool block_delete,
std::vector<SimulatorGcodeControlAction> *actions);
void emit_simulator_gcode_control_action(CanonEventSink &sink,
bool can_emit_simulator_gcode_control_action(const CanonEventSink &sink,
const SimulatorGcodeControlAction &action);
bool emit_simulator_gcode_control_action(CanonEventSink &sink,
const SimulatorGcodeControlAction &action,
int line);

View File

@@ -180,6 +180,7 @@ size_t leading_special_word_start(const std::string &line);
bool is_numeric_m98_subprogram_header(const std::string &line);
OwordKind oword_kind(const std::string &line);
bool integer_word_value(const std::unordered_map<char, double> &words, char letter, int *value);
bool smoke_ini_raw_value(const std::string &section, const std::string &key, std::string *value);
bool evaluate_expression(const std::string &text,
const std::vector<CallFrame> &call_stack,
const std::unordered_map<int, double> &parameters,
@@ -444,6 +445,20 @@ bool parse_smoke_hal_named_parameter(const std::string &name, std::string *pin)
}
bool smoke_ini_value(const std::string &section, const std::string &key, double *value) {
std::string raw_value;
if (!smoke_ini_raw_value(section, key, &raw_value)) {
return false;
}
char *end = nullptr;
const double parsed = std::strtod(raw_value.c_str(), &end);
if (end == raw_value.c_str()) {
return false;
}
*value = parsed;
return true;
}
bool smoke_ini_raw_value(const std::string &section, const std::string &key, std::string *value) {
const char *path = std::getenv("INI_FILE_NAME");
if (!path || !*path) {
return false;
@@ -474,18 +489,20 @@ bool smoke_ini_value(const std::string &section, const std::string &key, double
if (ini_lookup_key(text.substr(0, equals)) != key) {
continue;
}
char *end = nullptr;
const std::string raw_value = trim(text.substr(equals + 1));
const double parsed = std::strtod(raw_value.c_str(), &end);
if (end == raw_value.c_str()) {
return false;
}
*value = parsed;
*value = trim(text.substr(equals + 1));
return true;
}
return false;
}
double smoke_metric_machine_value() {
std::string linear_units;
if (!smoke_ini_raw_value("TRAJ", "LINEAR_UNITS", &linear_units)) {
return -1.0;
}
return linear_units == "inch" ? 0.0 : 1.0;
}
bool smoke_hal_value(const std::string &pin, double *value) {
const char *path = std::getenv("HAL_PIN_FILE");
if (path && *path) {
@@ -1735,6 +1752,18 @@ bool smoke_tool_number_exists(int tool_number) {
return tool_number == 0 || tool_number == 1 || tool_number == 4;
}
template <typename ToolTable>
double smoke_pocket_named_parameter_value(const ToolTable &tool_table, int pocket_index, bool selected_pocket) {
const auto it = tool_table.find(pocket_index);
if (it == tool_table.end()) {
return -1.0;
}
if (selected_pocket && it->second.pocketno == 0) {
return -1.0;
}
return static_cast<double>(it->second.pocketno);
}
int supported_linuxcnc_g_modal_group(double value) {
const int code = linuxcnc_g_code_number(value);
if (code < 0 || code >= kLinuxCncGCodeTableSize) {
@@ -2333,13 +2362,7 @@ bool is_smoke_readonly_named_parameter(const std::string &name) {
name == "_ABS_B" ||
name == "_abs_b" ||
name == "_ABS_C" ||
name == "_abs_c" ||
name == "_ABS_U" ||
name == "_abs_u" ||
name == "_ABS_V" ||
name == "_abs_v" ||
name == "_ABS_W" ||
name == "_abs_w";
name == "_abs_c";
}
bool is_smoke_readonly_numbered_parameter(int index) {
@@ -5408,6 +5431,8 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
spindle_css_mode_ = false;
spindle_tool_id_ = 0;
selected_tool_id_ = 0;
current_pocket_index_ = 0;
selected_pocket_index_ = 0;
feed_mode_ = 0;
canned_cycle_ = 0;
canned_return_to_initial_ = false;
@@ -5433,13 +5458,16 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
oword_value_returned_ = false;
tool_table_.clear();
tool_table_[0] = {};
tool_table_[0].pocketno = 0;
tool_table_[1] = {};
tool_table_[1].pocketno = 1;
tool_table_[1].offset.z = 12.5;
tool_table_[1].diameter = 6.0;
tool_table_[1].frontangle = 12.0;
tool_table_[1].backangle = 34.0;
tool_table_[1].orientation = 5.0;
tool_table_[4] = {};
tool_table_[4].pocketno = 4;
tool_table_[4].offset.z = 0.7;
tool_table_[4].diameter = 1.0;
@@ -5685,9 +5713,13 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
named_parameters["_CURRENT_TOOL"] = named_parameters["_current_tool"];
named_parameters["_selected_tool"] = static_cast<double>(selected_tool_id_);
named_parameters["_SELECTED_TOOL"] = named_parameters["_selected_tool"];
named_parameters["_current_pocket"] = static_cast<double>(spindle_tool_id_);
named_parameters["_current_pocket"] = smoke_pocket_named_parameter_value(tool_table_,
current_pocket_index_,
false);
named_parameters["_CURRENT_POCKET"] = named_parameters["_current_pocket"];
named_parameters["_selected_pocket"] = static_cast<double>(selected_tool_id_);
named_parameters["_selected_pocket"] = smoke_pocket_named_parameter_value(tool_table_,
selected_pocket_index_,
true);
named_parameters["_SELECTED_POCKET"] = named_parameters["_selected_pocket"];
named_parameters["_spindle_rpm_mode"] = spindle_css_mode_ ? 0.0 : 1.0;
named_parameters["_SPINDLE_RPM_MODE"] = named_parameters["_spindle_rpm_mode"];
@@ -5707,8 +5739,8 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
named_parameters["_VMAJOR"] = 2.10;
named_parameters["_vminor"] = 0.0;
named_parameters["_VMINOR"] = 0.0;
named_parameters["_metric_machine"] = -1.0;
named_parameters["_METRIC_MACHINE"] = -1.0;
named_parameters["_metric_machine"] = smoke_metric_machine_value();
named_parameters["_METRIC_MACHINE"] = named_parameters["_metric_machine"];
named_parameters["_task"] = 0.0;
named_parameters["_TASK"] = 0.0;
const bool has_tool_offset = tool_length_offset.x != 0.0 ||
@@ -5747,18 +5779,12 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
named_parameters["_abs_a"] = position.a;
named_parameters["_abs_b"] = position.b;
named_parameters["_abs_c"] = position.c;
named_parameters["_abs_u"] = position.u;
named_parameters["_abs_v"] = position.v;
named_parameters["_abs_w"] = position.w;
named_parameters["_ABS_X"] = position.x;
named_parameters["_ABS_Y"] = position.y;
named_parameters["_ABS_Z"] = position.z;
named_parameters["_ABS_A"] = position.a;
named_parameters["_ABS_B"] = position.b;
named_parameters["_ABS_C"] = position.c;
named_parameters["_ABS_U"] = position.u;
named_parameters["_ABS_V"] = position.v;
named_parameters["_ABS_W"] = position.w;
const CncSimPose &probe_position = sink_.probe_position();
parameters[5061] = probe_position.x;
@@ -5956,14 +5982,34 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
if (!has_keyword_oword &&
parse_simulator_gcode_control_line(line, sink_.block_delete(), &simulator_control_actions)) {
bool simulator_only_line = true;
bool all_control_actions_handled = true;
for (const auto &action : simulator_control_actions) {
emit_simulator_gcode_control_action(sink_, action, line_number);
if (!can_emit_simulator_gcode_control_action(sink_, action)) {
all_control_actions_handled = false;
simulator_only_line = false;
}
if (action.kind == SimulatorGcodeControlKind::RtcpState &&
!action.rtcp_enabled) {
simulator_only_line = false;
}
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
if (!all_control_actions_handled && simulator_control_actions.size() > 1) {
for (const auto &action : simulator_control_actions) {
if (!can_emit_simulator_gcode_control_action(sink_, action) &&
action.kind == SimulatorGcodeControlKind::KinematicsSwitch) {
if (error) {
*error = "M-code greater than 199: M" + std::to_string(action.m_code);
}
return -1;
}
}
}
if (all_control_actions_handled) {
for (const auto &action : simulator_control_actions) {
emit_simulator_gcode_control_action(sink_, action, line_number);
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
}
}
if (simulator_only_line) {
@@ -7704,6 +7750,15 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
}
return -1;
}
for (int m : m_codes) {
if ((m == 428 || m == 429 || m == 430) &&
!sink_.can_switch_m_code_kinematics(m)) {
if (error) {
*error = "M-code greater than 199: M" + std::to_string(m);
}
return -1;
}
}
if (modal_motion_is_threading(modal_motion) && words.count('F')) {
if (error) {
@@ -7764,6 +7819,7 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
}
sink_.select_tool(tool_id);
selected_tool_id_ = tool_id;
selected_pocket_index_ = tool_id;
tool_selected_ = true;
}
@@ -7910,6 +7966,10 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
if (selected_tool_id_ == 0) {
spindle_tool_id_ = 0;
}
current_pocket_index_ = selected_pocket_index_;
} else if (m == 7) {
sink_.set_mist_on(true);
emit_comment_state(sink_, line_number, 11);
@@ -8058,6 +8118,10 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
}
sink_.select_tool(tool_number);
sink_.change_tool(line_number);
if (tool_number == 0) {
spindle_tool_id_ = 0;
}
current_pocket_index_ = tool_number;
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
@@ -8192,17 +8256,32 @@ int SmokeGcodeParser::parse(const char *program, size_t program_len, std::string
return -1;
}
} else if (m == 428) {
sink_.switch_kinematics(1, line_number);
if (!sink_.switch_m_code_kinematics(428, 1, line_number)) {
if (error) {
*error = "M-code greater than 199: M428";
}
return -1;
}
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
} else if (m == 429) {
sink_.switch_kinematics(0, line_number);
if (!sink_.switch_m_code_kinematics(429, 0, line_number)) {
if (error) {
*error = "M-code greater than 199: M429";
}
return -1;
}
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}
} else if (m == 430) {
sink_.switch_kinematics(2, line_number);
if (!sink_.switch_m_code_kinematics(430, 2, line_number)) {
if (error) {
*error = "M-code greater than 199: M430";
}
return -1;
}
if (stop_if_callback_aborted(sink_, error)) {
return -1;
}

View File

@@ -14,6 +14,7 @@ public:
private:
struct SmokeToolTableEntry {
int pocketno = 0;
CncSimPose offset{};
double diameter = 0.0;
double frontangle = 0.0;
@@ -64,5 +65,7 @@ private:
double oword_return_value_ = 0.0;
bool oword_value_returned_ = false;
int selected_tool_id_ = 0;
int current_pocket_index_ = 0;
int selected_pocket_index_ = 0;
std::unordered_map<int, SmokeToolTableEntry> tool_table_;
};