5 Axis MCT Tool Positioning Plugin for Grasshopper

Vector to IJKABC is a dedicated laser scanner positioning tool developed for Hwacheon LP840 Laser Ablation Machining Center. This GH component will convert GH frame data into machine specific formatted data. LP840 has varient head/table configuration, which differ from one another not only in freedom of axis, but also in travel constraints. XYZ IJK ABC are as follow.

XYZ : target position coordinate

IJK : directional vector

ABC : rotation (deg) on each axis (YZ,XZ,XY plane respectively)

I used IJK to calculate rotation degree on A,B and C.

A = arctan(k/abs(j))-PI/2
B = (arctan(k/abs(j))-PI/2)*(i/abs(i))
if 0<i<1 and -1<j<1,  C = (arctan(j/abs(i))-PI/2)*(i/(abs(i))
if -1<i<0 and -1<j<1, C = (arctan(j/abs(i))+PI/2)*(i/abs(i))-PI

For example, in 4 Axis with Head/Table setup, table rotates while laser head rotates around x or y axis only.

This component works as part of LP840 Smart Texture for Rhino Grasshopper plug-in.

View Code (C#) Vector to IJKABC

private void RunScript(Point3d pt, Vector3d v, int Mode, ref object I, ref object J, ref object K, ref object A, ref object B, ref object C, ref object formatted)
{

AxisTransform at = new AxisTransform(v, (MachineType) Mode);
double i = Math.Round(at.I(), 4);
double j = Math.Round(at.J(), 4);
double k = Math.Round(at.K(), 4);
//rad to deg
double a = Math.Round(at.A() * 180 / Math.PI, 4);
double b = Math.Round(at.B() * 180 / Math.PI, 4);
double c = Math.Round(at.C() * 180 / Math.PI, 4);
//Formatter
switch ((MachineType) Mode){
case MachineType.qaxvt:
{
formatted = x + ” ” + y + ” ” + z + ” ” + i + ” ” + j + ” ” + k + ” ” + c + ” “;
break;
}
case MachineType.qaxht:
{
formatted = x + ” ” + y + ” ” + z + ” ” + i + ” ” + j + ” ” + k + ” ” + c + ” “;
break;
}
case MachineType.vaxht:
{
formatted = x + ” ” + y + ” ” + z + ” ” + i + ” ” + j + ” ” + k + ” ” + b + ” ” + c + ” “;
break;
}
case MachineType.vaxtt:
{
formatted = x + ” ” + y + ” ” + z + ” ” + i + ” ” + j + ” ” + k + ” ” + a + ” ” + c + ” “;
break;
}
}

}

public enum MachineType {qaxvt, qaxht,vaxtt,vaxht};

//transform class
class AxisTransform{

//properties
private Vector3d norm;
private double i;
private double j;
private double k;
private double a;
private double b;
private double c;
//set ABC rotation value by MachineType
public AxisTransform(Vector3d n, MachineType tp){

norm = n;
i = norm.X;
j = norm.Y;
k = norm.Z;

switch(tp){

case MachineType.qaxvt:
{

c = qvtc();
break;

}
case MachineType.qaxht:
{

c = qhtc();
break;

}
case MachineType.vaxht:
{

b = vhtb();
c = vhtc();
break;

}
case MachineType.vaxtt:
{

a = vtta();
c = vttc();
break;

}

}

}
//get value methods
public double I(){
return i;
}
public double J(){
return j;
}
public double K(){
return k;
}
public double A(){
return a;
}
public double B(){
return b;
}
public double C(){
return c;
}
//calculate ABC rotation degree
// 5 axis Head Table B

private double vhtb(){

double bx;
if(i == 0 && j == 0){

bx = 0;

}
else{
bx = -(System.Math.Atan(k / System.Math.Pow(Math.Pow(i, 2) + Math.Pow(j, 2), 0.5)) – System.Math.PI / 2);
}
return bx;

}
//5 axis Head Table C
private double vhtc(){

double cx;
if(i > 0){
cx = (Math.Atan(j / Math.Abs(i)) – (Math.PI / 2)) * (i / Math.Abs(i)) + (Math.PI / 2);
}
else if(i < 0){
cx = (Math.Atan(j / Math.Abs(i)) + (Math.PI / 2)) * (i / Math.Abs(i)) – (Math.PI / 2);
}
else{
cx = -Math.PI / 2;
}
return cx;

}
//5 axis Table Table A
private double vtta(){

double ax;
if(i == 0 && j == 0){
ax = 0;
}
else{
ax = System.Math.Atan(k / System.Math.Pow(Math.Pow(i, 2) + Math.Pow(j, 2), 0.5)) – System.Math.PI / 2;
}
return ax;

}
//5 axis Table Table C
private double vttc(){

double cx;
if(i > 0){
cx = (Math.Atan(j / Math.Abs(i)) – (Math.PI / 2)) * (i / Math.Abs(i));
}
else if(i < 0){
cx = (Math.Atan((j / Math.Abs(i)) + Math.PI / 2)) * (i / Math.Abs(i)) – Math.PI / 2;
}
else{
cx = 0;
}
return cx;

}
//4 axis Heac Table C
private double qhtc(){

double cx;
if(k == 1){
cx = 0;
}
else if(k == -1){
cx = -Math.PI;
}
else if(j == 1){
cx = -Math.PI / 2;
}
else if(j == -1){
cx = -3 * Math.PI / 2;
}
else if(j > 0){
cx = (Math.Atan((k / Math.Abs(j)) – Math.PI / 2)) * (j / Math.Abs(j));
}
else{
cx = (Math.Atan((k / Math.Abs(j)) – Math.PI / 2)) * (j / Math.Abs(j)) – Math.PI;
}
return cx;

}
//4 axis Table only C
private double qvtc(){

double cx;
if(j == 1){
cx = 0;
}
else if(j == -1){
cx = -Math.PI;
}
else if(i == 1){
cx = -Math.PI / 2;
}
else if(i == -1){
cx = -3 * Math.PI / 2;
}
else if(i > 0){
cx = (Math.Atan((j / Math.Abs(i)) – Math.PI / 2)) * (i / Math.Abs(i));
}
else{
cx = (Math.Atan((j / Math.Abs(i)) + Math.PI / 2)) * (i / Math.Abs(i)) – Math.PI;
}
return cx;

}

}

Leave a Reply