Skip to content

Commit

Permalink
finish #274
Browse files Browse the repository at this point in the history
  • Loading branch information
i-make-robots committed Jan 24, 2024
1 parent 1154595 commit db4cd73
Show file tree
Hide file tree
Showing 5 changed files with 706 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.NodePath;
import com.marginallyclever.ro3.node.nodes.HingeJoint;
import com.marginallyclever.ro3.node.nodes.limbsolver.ApproximateJacobianFiniteDifferences;
import com.marginallyclever.ro3.node.nodes.limbsolver.LimbSolver;
import com.marginallyclever.ro3.node.nodes.Motor;
import com.marginallyclever.ro3.node.nodes.marlinsimulation.MarlinCoordinate;
import com.marginallyclever.ro3.node.nodes.marlinsimulation.MarlinSettings;
import com.marginallyclever.ro3.node.nodes.marlinsimulation.MarlinSimulation;
import com.marginallyclever.ro3.node.nodes.marlinsimulation.MarlinSimulationBlock;
import com.marginallyclever.ro3.node.nodes.pose.Pose;
import com.marginallyclever.ro3.node.nodes.pose.poses.Limb;
import org.json.JSONObject;
Expand Down Expand Up @@ -36,6 +39,12 @@ public class MarlinRobotArm extends Node {
public final NodePath<LimbSolver> solver = new NodePath<>(this,LimbSolver.class);
private final NodePath<Motor> gripperMotor = new NodePath<>(this,Motor.class);
private double reportInterval=1.0; // seconds
private final MarlinSettings settings = new MarlinSettings();
private final MarlinSimulation simulation = new MarlinSimulation(settings);
private MarlinSimulationBlock currentBlock = null;
private double feedrate = settings.getDouble(MarlinSettings.MAX_FEEDRATE);
private double acceleration = settings.getDouble(MarlinSettings.MAX_ACCELERATION);


public MarlinRobotArm() {
this("MarlinRobotArm");
Expand Down Expand Up @@ -197,30 +206,39 @@ private String parseG0(String gcode) {
}
String [] parts = gcode.split("\\s+");
try {
var destination = new MarlinCoordinate();

int i=0;
for (NodePath<Motor> paths : getLimb().getSubject().getMotors()) {
Motor motor = paths.getSubject();
if (motor != null && motor.hasHinge()) {
String motorName = motor.getName();
for (String p : parts) {
if (p.startsWith(motor.getName())) {
if (p.startsWith(motorName)) {
// TODO check new value is in range.
motor.getHinge().setAngle(Double.parseDouble(p.substring(motor.getName().length())));
destination.p[i] = Double.parseDouble(p.substring(motor.getName().length()));
break;
}
}
}
i++;
}
// gripper motor
Motor gripperMotor = this.gripperMotor.getSubject();
if (gripperMotor != null && gripperMotor.hasHinge()) {
String motorName = gripperMotor.getName();
for (String p : parts) {
if (p.startsWith(gripperMotor.getName())) {
if (p.startsWith(motorName)) {
// TODO check new value is in range.
gripperMotor.getHinge().setAngle(Double.parseDouble(p.substring(gripperMotor.getName().length())));
destination.p[i] = Double.parseDouble(p.substring(gripperMotor.getName().length()));
break;
}
}
i++;
}
// else ignore unused parts

simulation.bufferLine(destination,feedrate,acceleration);
} catch( NumberFormatException e ) {
logger.error("Number format exception: "+e.getMessage());
return "Error: "+e.getMessage();
Expand All @@ -232,9 +250,59 @@ private String parseG0(String gcode) {
@Override
public void update(double dt) {
super.update(dt);
// TODO Simulate Marlin behavior here.
// Queue up GCode commands and send "Ok" at the appropriate time.

// Simulate Marlin behavior.
if(currentBlock==null) {
currentBlock = findBlock();
if(currentBlock!=null) {
logger.debug("starting block " + currentBlock.id);
currentBlock.busy = true;
}
}
if(currentBlock==null) return;

// advance time in the block
currentBlock.now_s += dt;
double extra = currentBlock.now_s - currentBlock.end_s;
if (currentBlock.now_s >= currentBlock.end_s) {
// no overflow!
currentBlock.now_s = currentBlock.end_s;
}

// Drive motors using trapezoidal velocity profiles.
// update motors according to currentBlock
logger.debug("working block " + currentBlock.id);
int i=0;
for(NodePath<Motor> paths : getLimb().getSubject().getMotors()) {
Motor motor = paths.getSubject();
double fraction = currentBlock.now_s / currentBlock.end_s;
if(motor!=null && motor.hasHinge()) {
HingeJoint hinge = motor.getHinge();
hinge.setAngle(
currentBlock.start.p[i] + currentBlock.delta.p[i] * fraction);
}
++i;
}

// is block done?
if (currentBlock.now_s >= currentBlock.end_s) {
logger.debug("ending block " + currentBlock.id);
currentBlock.busy = false;
simulation.getQueue().remove(currentBlock);

currentBlock = findBlock();
if(currentBlock!=null) {
logger.debug("starting block " + currentBlock.id);
currentBlock.busy = true;
currentBlock.now_s = extra;
}
}

// Queue up GCode commands and send "Ok" at the appropriate time.
}

private MarlinSimulationBlock findBlock() {
return (simulation.getQueue().isEmpty()) ? null : simulation.getQueue().peek();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.marginallyclever.ro3.node.nodes.marlinsimulation;

import javax.vecmath.Vector3d;
import java.util.Arrays;

public class MarlinCoordinate {
public static final int SIZE=6;
public final double [] p = new double[SIZE];

public MarlinCoordinate() {}

public MarlinCoordinate(MarlinCoordinate other) {
set(other);
}

public void add(MarlinCoordinate other) {
for(int i=0;i<SIZE;++i) {
p[i] += other.p[i];
}
}

public void sub(MarlinCoordinate other) {
for(int i=0;i<SIZE;++i) {
p[i] -= other.p[i];
}
}

public void scale(double s) {
for(int i=0;i<SIZE;++i) {
p[i] *= s;
}
}

public void set(MarlinCoordinate other) {
System.arraycopy(other.p, 0, p, 0, SIZE);
}

@Override
public String toString() {
return super.toString() + Arrays.toString(p);
}

public void normalize() {
double len = length();
if(len==0) return;
scale(1.0/len);
}

public double length() {
return Math.sqrt(dot(this));
}

public void sub(MarlinCoordinate a, MarlinCoordinate b) {
for(int i=0;i<SIZE;++i) {
this.p[i] = a.p[i] - b.p[i];
}
}

public double dot(MarlinCoordinate b) {
double sum=0;
for(int i=0;i<SIZE;++i) {
sum += p[i] * b.p[i];
}
return sum;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.marginallyclever.ro3.node.nodes.marlinsimulation;

public class MarlinSettings {
public static final int MAX_ACCELERATION = 1;
public static final int SEGMENTS_PER_SECOND = 2;
public static final int MIN_SEGMENT_LENGTH = 3;
public static final int BLOCK_BUFFER_SIZE = 4;
public static final int MIN_SEG_TIME = 5;
public static final int MINIMUM_PLANNER_SPEED = 6;
public static final int HANDLE_SMALL_SEGMENTS = 7;
public static final int MAX_FEEDRATE = 8;

public double getDouble(int key) {
return switch (key) {
case MAX_ACCELERATION -> 3000;
case MAX_FEEDRATE -> 5;
case MIN_SEGMENT_LENGTH -> 0.5;
case MINIMUM_PLANNER_SPEED -> 0.05;
default -> 0;
};
}

public int getInteger(int key) {
return switch (key) {
case SEGMENTS_PER_SECOND -> 5;
case BLOCK_BUFFER_SIZE -> 16;
case MIN_SEG_TIME -> 100;
default -> 0;
};
}

public boolean getBoolean(int key) {
if (key == HANDLE_SMALL_SEGMENTS) {
return false;
}
return false;
}
}
Loading

0 comments on commit db4cd73

Please sign in to comment.