#include "kinematics.h"
#include "rtapi_math.h"
#include "gotypes.h"
#define L0_HORIZONTAL_DISTANCE 16
#define L0_VERTICAL_DISTANCE 140
#define L1_LENGTH 221
#define L2_LENGTH 221
static void compute_j1_cartesian_location(double j0, EmcPose *j1_cart) {
j1_cart->tran.x = L0_HORIZONTAL_DISTANCE * cos(TO_RAD * j0);
j1_cart->tran.y = L0_HORIZONTAL_DISTANCE * sin(TO_RAD * j0);
j1_cart->tran.z = L0_VERTICAL_DISTANCE;
j1_cart->a = 0;
j1_cart->b = 0;
j1_cart->c = 0;
j1_cart->u = 0;
j1_cart->v = 0;
j1_cart->w = 0;
}
int kinematicsForward(
const double *joints,
EmcPose *pose,
const KINEMATICS_FORWARD_FLAGS *fflags,
KINEMATICS_INVERSE_FLAGS *iflags
) {
EmcPose j1_vector; EmcPose j2_vector; EmcPose j3_vector;
double r;
compute_j1_cartesian_location(joints[0], &j1_vector);
r = L1_LENGTH * cos(TO_RAD * joints[1]);
j2_vector.tran.x = r * cos(TO_RAD * joints[0]);
j2_vector.tran.y = r * sin(TO_RAD * joints[0]);
j2_vector.tran.z = L1_LENGTH * sin(TO_RAD * joints[1]);
r = L2_LENGTH * cos(TO_RAD * joints[2]);
j3_vector.tran.x = r * cos(TO_RAD * joints[0]);
j3_vector.tran.y = r * sin(TO_RAD * joints[0]);
j3_vector.tran.z = L2_LENGTH * sin(TO_RAD * joints[2]);
pose->tran.x = j1_vector.tran.x + j2_vector.tran.x + j3_vector.tran.x;
pose->tran.y = j1_vector.tran.y + j2_vector.tran.y + j3_vector.tran.y;
pose->tran.z = j1_vector.tran.z + j2_vector.tran.z + j3_vector.tran.z;
pose->a = joints[3];
pose->b = joints[4];
return 0;
}
int kinematicsInverse(
const EmcPose *pose,
double *joints,
const KINEMATICS_INVERSE_FLAGS *iflags,
KINEMATICS_FORWARD_FLAGS *fflags
) {
double distance_to_cp, distance_to_center;
double r_j1, z_j1; double r_cp, z_cp; double angle_to_cp;
double j1_angle;
double z_j2;
joints[0] = TO_DEG * atan2(pose->tran.y, pose->tran.x);
r_j1 = L0_HORIZONTAL_DISTANCE;
z_j1 = L0_VERTICAL_DISTANCE;
r_cp = sqrt(pow(pose->tran.x, 2) + pow(pose->tran.y, 2));
z_cp = pose->tran.z;
r_cp -= r_j1;
z_cp -= z_j1;
distance_to_cp = sqrt(pow(r_cp, 2) + pow(z_cp, 2));
distance_to_center = distance_to_cp / 2;
angle_to_cp = TO_DEG * acos(r_cp / distance_to_cp);
if (z_cp < 0) {
angle_to_cp *= -1;
}
j1_angle = TO_DEG * acos(distance_to_center / L1_LENGTH);
joints[1] = angle_to_cp + j1_angle;
z_j2 = L1_LENGTH * sin(TO_RAD * joints[1]);
joints[2] = -1.0 * TO_DEG * asin((z_j2 - z_cp) / L2_LENGTH);
#if 0#endif
joints[3] = pose->a;
joints[4] = pose->b;
return 0;
}
KINEMATICS_TYPE kinematicsType(void) {
return KINEMATICS_BOTH;
}
#include "rtapi.h"
#include "rtapi_app.h"
#include "hal.h"
EXPORT_SYMBOL(kinematicsType);
EXPORT_SYMBOL(kinematicsForward);
EXPORT_SYMBOL(kinematicsInverse);
MODULE_LICENSE("GPL");
static int comp_id;
int rtapi_app_main(void) {
comp_id = hal_init("scorbot-kins");
if (comp_id < 0) {
return comp_id;
}
hal_ready(comp_id);
return 0;
}
void rtapi_app_exit(void) {
hal_exit(comp_id);
}