@Override
  public void moveTo(ReferenceHeadMountable hm, Location location, double speed) throws Exception {
    location = location.subtract(hm.getHeadOffsets());

    location = location.convertToUnits(LengthUnit.Millimeters);

    double x = location.getX();
    double y = location.getY();
    double z = location.getZ();
    double c = location.getRotation();

    StringBuffer sb = new StringBuffer();
    if (!Double.isNaN(x) && x != this.x) {
      sb.append(String.format(Locale.US, "X%2.2f ", x));
    }
    if (!Double.isNaN(y) && y != this.y) {
      sb.append(String.format(Locale.US, "Y%2.2f ", y));
    }
    if (!Double.isNaN(z) && z != this.z) {
      sb.append(String.format(Locale.US, "Z%2.2f ", z));
    }
    if (!Double.isNaN(c) && c != this.c) {
      sb.append(String.format(Locale.US, "E%2.2f ", c));
    }
    if (sb.length() > 0) {
      sb.append(String.format(Locale.US, "F%2.2f", feedRateMmPerMinute));
      sendCommand("G1 " + sb.toString());
      dwell();
    }
    if (!Double.isNaN(x)) {
      this.x = x;
    }
    if (!Double.isNaN(y)) {
      this.y = y;
    }
    if (!Double.isNaN(z)) {
      this.z = z;
    }
    if (!Double.isNaN(c)) {
      this.c = c;
    }
  }
 @Override
 public Location getLocation(ReferenceHeadMountable hm) {
   return new Location(LengthUnit.Millimeters, x, y, z, c).add(hm.getHeadOffsets());
 }