BowlerKernel
AbstractKinematicsNR.java
Go to the documentation of this file.
1 package com.neuronrobotics.sdk.addons.kinematics;
2 
3 import java.io.InputStream;
4 import java.sql.Timestamp;
5 import java.util.ArrayList;
6 //import java.util.concurrent.CountDownLatch;
7 
8 
9 import org.w3c.dom.Document;
10 import org.w3c.dom.Element;
11 import org.w3c.dom.Node;
12 import org.w3c.dom.NodeList;
13 
14 import Jama.Matrix;
15 
16 import com.neuronrobotics.sdk.addons.kinematics.imu.IMU;
17 import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
18 import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
19 import com.neuronrobotics.sdk.addons.kinematics.xml.XmlFactory;
20 import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
21 import com.neuronrobotics.sdk.common.BowlerDatagram;
22 import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
23 import com.neuronrobotics.sdk.common.InvalidConnectionException;
24 //import com.neuronrobotics.sdk.addons.kinematics.PidRotoryLink;
25 import com.neuronrobotics.sdk.common.Log;
26 import com.neuronrobotics.sdk.common.NonBowlerDevice;
27 import com.neuronrobotics.sdk.common.TickToc;
28 import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
29 import com.neuronrobotics.sdk.pid.IPIDEventListener;
30 import com.neuronrobotics.sdk.pid.InterpolationEngine;
31 import com.neuronrobotics.sdk.pid.InterpolationType;
32 import com.neuronrobotics.sdk.pid.PIDChannel;
33 //import com.neuronrobotics.sdk.pid.PIDCommandException;
34 import com.neuronrobotics.sdk.pid.PIDConfiguration;
35 import com.neuronrobotics.sdk.pid.PIDEvent;
36 import com.neuronrobotics.sdk.pid.PIDLimitEvent;
37 import com.neuronrobotics.sdk.util.ThreadUtil;
38 // TODO: Auto-generated Javadoc
39 //import javax.swing.JFrame;
40 //import javax.swing.JOptionPane;
41 
42 
46 @SuppressWarnings("restriction")
47 public abstract class AbstractKinematicsNR extends NonBowlerDevice implements IPIDEventListener, ILinkListener {
48 
49 
50 
52  private ArrayList<PIDConfiguration> pidConfigurations = new ArrayList<PIDConfiguration>();
53 
55  private ArrayList<ITaskSpaceUpdateListenerNR> taskSpaceUpdateListeners = new ArrayList<ITaskSpaceUpdateListenerNR>();
56 
58  protected ArrayList<IJointSpaceUpdateListenerNR> jointSpaceUpdateListeners = new ArrayList<IJointSpaceUpdateListenerNR>();
59 
61  private ArrayList<IRegistrationListenerNR> regListeners = new ArrayList<IRegistrationListenerNR>();
62 
64  private ArrayList<MobileBase> mobileBases = new ArrayList<MobileBase>();
65 
67  private String[] dhEngine = new String[] { "https://github.com/madhephaestus/carl-the-hexapod.git",
68  "DefaultDhSolver.groovy" };
69 
71  private String[] cadEngine = new String[] { "https://github.com/madhephaestus/carl-the-hexapod.git",
72  "ThreeDPrintCad.groovy" };
73 
75  /* This is in RAW joint level ticks */
76  //protected double[] currentJointSpacePositions = null;
77 
79 // public double[] currentJointSpaceTarget;
80 
82  private TransformNR currentPoseTarget = new TransformNR();
83 
85  private TransformNR base2Fiducial = new TransformNR();
86 
88  private TransformNR fiducial2RAS = new TransformNR();
89 
91  private boolean noFlush = false;
92 
94  private boolean noXmlConfig = true;
95 
97  private DHChain dhParametersChain = null;
98 
100  private Object root;
101 
102  /* The device */
104  // private IPIDControl device =null;
105  private LinkFactory factory = null;
106 
108  private int retryNumberBeforeFail = 5;
113  private IMU imu = new IMU();
114 
115  private Runnable renderWrangler=null;
116 
122  public Object getRootListener() {
123  return root;
124  }
125 
131  public void setRootListener(Object listener) {
132  this.root = listener;
133  }
134 
140  public abstract void disconnectDevice();
141 
147  public abstract boolean connectDevice();
148 
149  /*
150  * (non-Javadoc)
151  *
152  * @see com.neuronrobotics.sdk.common.NonBowlerDevice#getNamespacesImp()
153  */
154  @Override
155  public ArrayList<String> getNamespacesImp() {
156  // TODO Auto-generated method stub
157  ArrayList<String> back = new ArrayList<String>();
158  back.add("bcs.cartesian.*");
159  return back;
160  }
161 
162  /*
163  * (non-Javadoc)
164  *
165  * @see com.neuronrobotics.sdk.common.NonBowlerDevice#disconnectDeviceImp()
166  */
167  public void disconnectDeviceImp() {
168  getFactory().removeLinkListener(this);
169  for (LinkConfiguration lf : getFactory().getLinkConfigurations())
170  if (getFactory().getPid(lf) != null)
171  getFactory().getPid(lf).removePIDEventListener(this);
172 
173  disconnectDevice();
174  }
175 
176  /*
177  * (non-Javadoc)
178  *
179  * @see com.neuronrobotics.sdk.common.NonBowlerDevice#connectDeviceImp()
180  */
181  public boolean connectDeviceImp() {
182  return connectDevice();
183  }
184 
189 // File l = new File("RobotLog_"+getDate()+"_"+System.currentTimeMillis()+".txt");
190 // //File e = new File("RobotError_"+getDate()+"_"+System.currentTimeMillis()+".txt");
191 // try {
192 // PrintStream p =new PrintStream(l);
193 // Log.setOutStream(new PrintStream(p));
194 // Log.setErrStream(new PrintStream(p));
195 // } catch (FileNotFoundException e1) {
196 // e1.printStackTrace();
197 // }
198  setDhParametersChain(new DHChain(this));
199  }
200 
207  public AbstractKinematicsNR(InputStream configFile, LinkFactory f) {
208  this();
209  if(configFile==null||f==null)
210  return;
211  Document doc = XmlFactory.getAllNodesDocument(configFile);
212  NodeList nodListofLinks = doc.getElementsByTagName("appendage");
213  for (int i = 0; i < 1; i++) {
214  Node linkNode = nodListofLinks.item(i);
215  if (linkNode.getNodeType() == Node.ELEMENT_NODE) {
216  noXmlConfig = false;
217  if (configFile != null && f != null) {
218  setDevice(f, loadConfig((Element) linkNode));
219  }
220  } else {
221  Log.info("Not Element Node");
222  }
223  }
224 
225 
226  }
227 
234  public AbstractKinematicsNR(Element doc, LinkFactory f) {
235  this();
236  noXmlConfig = false;
237  if (doc != null && f != null) {
238  setDevice(f, loadConfig(doc));
239  }
240 
241  }
242 
248  private String getDate() {
249  Timestamp t = new Timestamp(System.currentTimeMillis());
250  return t.toString().split("\\ ")[0];
251  }
252 
260  protected ArrayList<LinkConfiguration> loadConfig(Element doc) {
261  ArrayList<LinkConfiguration> localConfigsFromXml = new ArrayList<LinkConfiguration>();
262 
263  NodeList nodListofLinks = doc.getChildNodes();
264  setGitCadEngine(getGitCodes(doc, "cadEngine"));
265  setGitDhEngine(getGitCodes(doc, "kinematics"));
266  for (int i = 0; i < nodListofLinks.getLength(); i++) {
267  Node linkNode = nodListofLinks.item(i);
268 
269  if (linkNode.getNodeType() == Node.ELEMENT_NODE && linkNode.getNodeName().contentEquals("link")) {
270  LinkConfiguration newLinkConf = new LinkConfiguration((Element) linkNode);
271  localConfigsFromXml.add(newLinkConf);
272 
273  NodeList dHParameters = linkNode.getChildNodes();
274  // System.out.println("Link "+newLinkConf.getName()+" has "+dHParameters
275  // .getLength()+" children");
276  for (int x = 0; x < dHParameters.getLength(); x++) {
277  Node nNode = dHParameters.item(x);
278  if (nNode.getNodeType() == Node.ELEMENT_NODE && nNode.getNodeName().contentEquals("DHParameters")) {
279  Element dhNode = (Element) nNode;
280  DHLink newLink = new DHLink(dhNode,newLinkConf);
281  getDhParametersChain().addLink(newLink);// 0->1
282  NodeList mobileBasesNodeList = dhNode.getChildNodes();
283  for (int j = 0; j < mobileBasesNodeList.getLength(); j++) {
284  Node mb = mobileBasesNodeList.item(j);
285  if (mb.getNodeType() == Node.ELEMENT_NODE && mb.getNodeName().contentEquals("mobilebase")) {
286  final MobileBase newMobileBase = new MobileBase((Element) mb);
287  mobileBases.add(newMobileBase);
288  newLink.setMobileBaseXml(newMobileBase);
289  addConnectionEventListener(new IDeviceConnectionEventListener() {
290 
291  @Override
292  public void onDisconnect(BowlerAbstractDevice source) {
293  mobileBases.remove(newMobileBase);
294  }
295 
296  @Override
297  public void onConnect(BowlerAbstractDevice source) {
298  }
299  });
300  }
301  }
302  } else {
303  if (nNode.getNodeType() == Node.ELEMENT_NODE
304  && nNode.getNodeName().contentEquals("slaveLink")) {
305  // System.out.println("Slave link found: ");
306  LinkConfiguration jc = new LinkConfiguration((Element) nNode);
307  // System.out.println(jc);
308  newLinkConf.getSlaveLinks().add(jc);
309  }
310  }
311  }
312  } else if (linkNode.getNodeType() == Node.ELEMENT_NODE && linkNode.getNodeName().contentEquals("name")) {
313  try {
314  setScriptingName(XmlFactory.getTagValue("name", doc));
315  } catch (Exception E) {
316  E.printStackTrace();
317  }
318  } else if (linkNode.getNodeType() == Node.ELEMENT_NODE
319  && linkNode.getNodeName().contentEquals("ZframeToRAS")) {
320  Element eElement = (Element) linkNode;
321  try {
322  setGlobalToFiducialTransform(new TransformNR(
323  Double.parseDouble(XmlFactory.getTagValue("x", eElement)),
324  Double.parseDouble(XmlFactory.getTagValue("y", eElement)),
325  Double.parseDouble(XmlFactory.getTagValue("z", eElement)),
326  new RotationNR(new double[] { Double.parseDouble(XmlFactory.getTagValue("rotw", eElement)),
327  Double.parseDouble(XmlFactory.getTagValue("rotx", eElement)),
328  Double.parseDouble(XmlFactory.getTagValue("roty", eElement)),
329  Double.parseDouble(XmlFactory.getTagValue("rotz", eElement)) })));
330  } catch (Exception ex) {
331  ex.printStackTrace();
332  setGlobalToFiducialTransform(new TransformNR());
333  }
334  } else if (linkNode.getNodeType() == Node.ELEMENT_NODE
335  && linkNode.getNodeName().contentEquals("baseToZframe")) {
336  Element eElement = (Element) linkNode;
337  try {
338  setRobotToFiducialTransform(new TransformNR(Double.parseDouble(XmlFactory.getTagValue("x", eElement)),
339  Double.parseDouble(XmlFactory.getTagValue("y", eElement)),
340  Double.parseDouble(XmlFactory.getTagValue("z", eElement)),
341  new RotationNR(new double[] { Double.parseDouble(XmlFactory.getTagValue("rotw", eElement)),
342  Double.parseDouble(XmlFactory.getTagValue("rotx", eElement)),
343  Double.parseDouble(XmlFactory.getTagValue("roty", eElement)),
344  Double.parseDouble(XmlFactory.getTagValue("rotz", eElement)) })));
345  } catch (Exception ex) {
346  ex.printStackTrace();
347  setRobotToFiducialTransform(new TransformNR());
348  }
349  } else {
350  // System.err.println(linkNode.getNodeName());
351  // Log.error("Node not known: "+linkNode.getNodeName());
352  }
353  }
354 
355  return localConfigsFromXml;
356  }
357 
363  /*
364  *
365  * Generate the xml configuration to generate an XML of this robot.
366  */
367  public String getXml() {
368  String xml = "<root>\n";
369  xml += "\n<appendage>";
370  xml += "\n<name>" + getScriptingName() + "</name>\n";
371  for (int i = 0; i < getLinkConfigurations().size(); i++) {
372  xml += "<link>\n";
373  xml += getLinkConfiguration(i).getXml();
374  xml += "\n</link>\n";
375  }
376  xml += "\n<ZframeToRAS>\n";
377  xml += getFiducialToGlobalTransform().getXml();
378  xml += "\n</ZframeToRAS>\n";
379 
380  xml += "\n<baseToZframe>\n";
381  xml += getRobotToFiducialTransform().getXml();
382  xml += "\n</baseToZframe>\n";
383  xml += "\n</appendage>";
384  xml += "\n</root>";
385  return xml;
386  }
387 
394  public LinkConfiguration getLinkConfiguration(int linkIndex) {
395  return getLinkConfigurations().get(linkIndex);
396  }
397 
403  public ArrayList<LinkConfiguration> getLinkConfigurations() {
404 
405  return getFactory().getLinkConfigurations();
406 
407  }
408 
416  return getAxisPidConfiguration().get(chan);
417  }
418 
426  getAxisPidConfiguration().set(chan, c);
427  }
428 
434  protected LinkFactory getDevice() {
435  return getFactory();
436  }
437 
444  public AbstractLink getAbstractLink(int index) {
445  return getFactory().getLink(getLinkConfiguration(index));
446  }
447 
454  protected void setDevice(LinkFactory f, ArrayList<LinkConfiguration> linkConfigs) {
455  Log.info("Loading device: " + f.getClass() + " " + f);
456  setFactory(f);
457  // Log.enableDebugPrint(true);
458  for (int i = 0; i < linkConfigs.size(); i++) {
459  LinkConfiguration c = linkConfigs.get(i);
460  c.setLinkIndex(i);
461  getFactory().getLink(c);
462  Log.info("\nAxis #" + i + " Configuration:\n" + c);
463  if (c.getTypeEnum() == LinkType.PID) {
464  IPidControlNamespace device = getFactory().getPid(c);
465  try {
467  tmpConf.setGroup(c.getHardwareIndex());
468  tmpConf.setKP(c.getKP());
469  tmpConf.setKI(c.getKI());
470  tmpConf.setKD(c.getKD());
471  tmpConf.setEnabled(true);
472  tmpConf.setInverted(c.isInverted());
473  tmpConf.setAsync(false);
474 
475  tmpConf.setUseLatch(false);
476  tmpConf.setIndexLatch(c.getIndexLatch());
477  tmpConf.setStopOnIndex(false);
478 
479  Log.info("\nAxis #" + i + " " + tmpConf);
480  getAxisPidConfiguration().add(tmpConf);
481  // setLinkCurrentConfiguration(i,tmpConf);
482  // Send configuration for ONE axis
483  device.ConfigurePIDController(tmpConf);
484  } catch (Exception ex) {
485  Log.error("Configuration #" + i + " failed!!");
486  ex.printStackTrace();
487  }
488  device.addPIDEventListener(this);
489  }
490  }
491  getCurrentTaskSpaceTransform();
492  getFactory().addLinkListener(this);
493  getDhParametersChain().setFactory(getFactory());
494 
495  // filling up the d-h parameters so the chain sizes match
496  while (getDhParametersChain().getLinks().size() < linkConfigs.size()) {
497  getDhParametersChain().addLink(new DHLink(0, 0, 0, 0));
498  }
499  }
500 
506  public int getNumberOfLinks() {
507  return getLinkConfigurations().size();
508  }
509 
517  TransformNR fwd = forwardKinematics(getCurrentJointSpaceVector());
518  if (fwd == null)
519  throw new RuntimeException("Implementations of the kinematics need to return a transform not null");
520  // Log.info("Getting robot task space "+fwd);
521  TransformNR taskSpaceTransform = forwardOffset(fwd);
522  // Log.info("Getting global task space "+taskSpaceTransform);
523  return taskSpaceTransform;
524  }
525  public double readLinkValue(int index) {
526  return getFactory().getLink(getLinkConfiguration(index)).getCurrentEngineeringUnits();
527  }
528  public double readLinkTarget(int index) {
529  return getFactory().getLink(getLinkConfiguration(index)).getTargetEngineeringUnits();
530  }
537  public double[] getCurrentJointSpaceVector() {
538  double[] jointSpaceVect = new double[getNumberOfLinks()];
539  for (int i = 0; i < getNumberOfLinks(); i++) {
540  // double pos =
541  // currentLinkSpacePositions[getLinkConfigurations().get(i).getHardwareIndex()];
542  // Here the RAW values are converted to engineering units
543  try {
544  jointSpaceVect[i] = readLinkValue(i);
545  }catch(Exception e) {
546  jointSpaceVect[i]=0;
547  }
548  }
549 
550  return jointSpaceVect;
551  }
552 
553  public double[] getCurrentJointSpaceTarget() {
554 
555  double[] currentJointSpaceTarget=new double[getNumberOfLinks()];
556  for(int i=0;i<currentJointSpaceTarget.length;i++) {
557  currentJointSpaceTarget[i]=readLinkTarget(i);
558  }
559  return currentJointSpaceTarget;
560  }
561  public double getCurrentLinkEngineeringUnits(int linkIndex) {
562  return getFactory().getLink(getLinkConfiguration(linkIndex)).getCurrentEngineeringUnits();
563  }
564 
574  public double[] setDesiredTaskSpaceTransform(TransformNR taskSpaceTransform, double seconds) throws Exception {
575  TickToc.tic("setDesiredTaskSpaceTransform start");
576  Log.info("Setting target pose: " + taskSpaceTransform);
577  setCurrentPoseTarget(taskSpaceTransform);
578  TickToc.tic("setCurrentPoseTarget");
579  TransformNR inverseOffset = inverseOffset(taskSpaceTransform);
580  TickToc.tic("inverseOffset");
581  double[] jointSpaceVect = inverseKinematics(inverseOffset);
582  TickToc.tic("inverseKinematics");
583  if(checkVector(this,jointSpaceVect,seconds)) {
584  TickToc.tic("checkVector success");
585  if (jointSpaceVect == null)
586  throw new RuntimeException("The kinematics model must return an array, not null");
587 
588  _setDesiredJointSpaceVector(jointSpaceVect, seconds,false);
589  TickToc.tic("_setDesiredJointSpaceVector complete");
590  return jointSpaceVect;
591  }else
592  TickToc.tic("checkVector fail");
593 
594  double[] currentJointSpaceTarget2 = getCurrentJointSpaceTarget();
595  TickToc.tic("getCurrentJointSpaceTarget");
596  return currentJointSpaceTarget2;
597  }
598 
605  public static boolean checkTaskSpaceTransform(AbstractKinematicsNR dev, TransformNR taskSpaceTransform, double seconds) {
606  try {
607  double[] jointSpaceVect = dev.inverseKinematics(dev.inverseOffset(taskSpaceTransform));
608  return checkVector(dev, jointSpaceVect,seconds);
609  } catch (Throwable ex) {
610  //Log.error(ex);
611  //ex.printStackTrace();
612  return false;
613  }
614  }
621  public static boolean checkTaskSpaceTransform(AbstractKinematicsNR dev, TransformNR taskSpaceTransform) {
622  return checkTaskSpaceTransform(dev,taskSpaceTransform,0);
623  }
624  private static boolean checkVector(AbstractKinematicsNR dev, double[] jointSpaceVect, double seconds) {
625  double[] current = dev.getCurrentJointSpaceTarget();
626  for (int i = 0; i < jointSpaceVect.length; i++) {
628  double val = jointSpaceVect[i];
629  Double double1 = new Double(val);
630  if(double1.isNaN() ||double1.isInfinite() ) {
631  Log.error(dev.getScriptingName()+" Link "+i+" Invalid unput "+double1);
632  return false;
633  }
634  if (val > link.getMaxEngineeringUnits()) {
635  Log.error(dev.getScriptingName()+" Link "+i+" can not reach "+val+" limited to "+link.getMaxEngineeringUnits());
636  return false;
637  }
638  if (val < link.getMinEngineeringUnits()) {
639  Log.error(dev.getScriptingName()+" Link "+i+" can not reach "+val+" limited to "+link.getMinEngineeringUnits());
640  return false;
641  }
642  if(seconds>0) {
643  double maxVel = Math.abs(link.getMaxVelocityEngineeringUnits());
644  double deltaPosition = Math.abs(current[i] - jointSpaceVect[i]);
645  double computedVelocity = deltaPosition/seconds;
646  if((computedVelocity-maxVel)>0.0001) {
647  Log.error("Link "+i+" can not move at rate of "+computedVelocity+" capped at "+maxVel+" requested position of "+jointSpaceVect[i]+" from current position of "+current[i]+" in "+seconds+" seconds");
648  return false;
649  }
650  }
651  }
652  return true;
653  }
654 
661  public boolean checkTaskSpaceTransform(TransformNR taskSpaceTransform, double seconds) {
662  return AbstractKinematicsNR.checkTaskSpaceTransform(this, taskSpaceTransform,seconds);
663  }
670  public boolean checkTaskSpaceTransform(TransformNR taskSpaceTransform) {
671  return checkTaskSpaceTransform(this, taskSpaceTransform,0);
672  }
673 
680  public double getBestTime(TransformNR currentTaskSpaceTransform) {
681  double[] jointSpaceVect;
682  double best = 0;
683  try {
684  jointSpaceVect = inverseKinematics(inverseOffset(currentTaskSpaceTransform));
685  best = getBestTime(jointSpaceVect);
686  } catch (Exception e) {
687  e.printStackTrace();
688  }
689  return best;
690  }
697  public double getBestTime(double[] jointSpaceVect) {
698  double best=0;
699  double[] current = getCurrentJointSpaceTarget();
700  for (int i = 0; i < current.length; i++) {
701  AbstractLink link = getAbstractLink(i);
702  double maxVel = Math.abs(link.getMaxVelocityEngineeringUnits());
703  double deltaPosition = Math.abs(current[i] - jointSpaceVect[i]);
704  double seconds = deltaPosition / maxVel;
705  if (seconds > best)
706  best = seconds + Double.MIN_VALUE;
707  }
708  return best;
709  }
710 
711 
721  public double[] setDesiredJointSpaceVector(double[] jointSpaceVect, double seconds) throws Exception {
722  return _setDesiredJointSpaceVector(jointSpaceVect,seconds,true);
723  }
733  private double[] _setDesiredJointSpaceVector(double[] jointSpaceVect, double seconds, boolean fireTaskUpdate) throws Exception {
734  if (jointSpaceVect.length != getNumberOfLinks()) {
735  throw new IndexOutOfBoundsException("Vector must be " + getNumberOfLinks()
736  + " links, actual number of links = " + jointSpaceVect.length);
737  }
738 
739  //synchronized(AbstractKinematicsNR.class) {
740  int except = 0;
741  Exception e = null;
742  TickToc.tic("Set hardware values start");
743  do {
744  try {
745  factory.setCachedTargets(jointSpaceVect);
746  TickToc.tic("Cached targets ");
747  if (!isNoFlush()) {
748  //
749  factory.flush(seconds);
750  TickToc.tic("_setDesiredJointSpaceVector flush "+seconds);
751  //
752  }
753  except = 0;
754  e = null;
755  } catch (Exception ex) {
756  except++;
757  e = ex;
758  e.printStackTrace();
759  }
760  } while (except > 0 && except < getRetryNumberBeforeFail());
761  if (e != null)
762  throw new RuntimeException("Limit On "+getScriptingName()+" "+e.getMessage());
763 
764  TickToc.tic("Copy Vector");
765  TransformNR fwd = forwardKinematics(getCurrentJointSpaceTarget());
766  TickToc.tic("FK from vector");
767  fireTargetJointsUpdate(getCurrentJointSpaceTarget(), fwd);
768  TickToc.tic("Joint space updates");
769  if(fireTaskUpdate) {
770  setCurrentPoseTarget(forwardOffset(fwd));
771  TickToc.tic("task space updates");
772  }
773 
774  //}
775  return jointSpaceVect;
776  }
783  public TransformNR calcForward(double[] jointSpaceVect) {
784  return forwardOffset(forwardKinematics(jointSpaceVect));
785  }
786 
793  double homevect[] = new double[getNumberOfLinks()];
794  for (int i = 0; i < homevect.length; i++) {
795  homevect[i] = 0;
796  }
797  return forwardOffset(forwardKinematics(homevect));
798  }
799 
809  public void setDesiredJointAxisValue(int axis, double value, double seconds) throws Exception {
810  //synchronized(AbstractKinematicsNR.class) {
811  LinkConfiguration c = getLinkConfiguration(axis);
812 
813  Log.info("Setting single target joint in mm/deg, axis=" + axis + " value=" + value);
814  try {
815  getFactory().getLink(c).setTargetEngineeringUnits(value);
816  } catch (Exception ex) {
817  throw new Exception("Joint hit software bound, index " + axis + " attempted: " + value + " boundes: U="
818  + c.getUpperLimit() + ", L=" + c.getLowerLimit());
819  }
820  if (!isNoFlush()) {
821  int except = 0;
822  Exception e = null;
823  do {
824  try {
825  getFactory().getLink(c).flush(seconds);
826  except = 0;
827  e = null;
828  } catch (Exception ex) {
829  except++;
830  e = ex;
831  }
832  } while (except > 0 && except < getRetryNumberBeforeFail());
833  if (e != null)
834  throw e;
835  }
836  TransformNR fwd = forwardKinematics(getCurrentJointSpaceTarget());
837  fireTargetJointsUpdate(getCurrentJointSpaceTarget(), fwd);
838  setCurrentPoseTarget(forwardOffset(fwd));
839  //}
840  return;
841  }
842 
848  protected void firePoseTransform(TransformNR transform) {
849  for (int i = 0; i < taskSpaceUpdateListeners.size(); i++) {
850  ITaskSpaceUpdateListenerNR p = taskSpaceUpdateListeners.get(i);
851  p.onTaskSpaceUpdate(this, transform);
852  }
853  }
854 
858  public void firePoseUpdate() {
859  // Log.info("Pose update");
860  firePoseTransform(getCurrentTaskSpaceTransform());
861 
862  double[] vect = getCurrentJointSpaceVector();
863 
864  for (int i = 0; i < jointSpaceUpdateListeners.size(); i++) {
865  IJointSpaceUpdateListenerNR p = jointSpaceUpdateListeners.get(i);
866  p.onJointSpaceUpdate(this, vect);
867  }
868  }
869 
876  protected void fireTargetJointsUpdate(double[] jointSpaceVector, TransformNR fwd) {
877 
878 
879  for (IJointSpaceUpdateListenerNR p : jointSpaceUpdateListeners) {
880  p.onJointSpaceTargetUpdate(this, getCurrentJointSpaceTarget());
881  }
882  }
883 
890  private void fireJointSpaceLimitUpdate(int axis, JointLimit event) {
891  for (IJointSpaceUpdateListenerNR p : jointSpaceUpdateListeners) {
892  p.onJointSpaceLimit(this, axis, event);
893  }
894  }
895 
902  return fiducial2RAS;
903  }
904 
905 // /**
906 // * Sets the base to zframe transform.
907 // *
908 // * @param baseToFiducial the new base to zframe transform
909 // */
910 // @Deprecated
911 // public void setBaseToZframeTransform(TransformNR baseToFiducial) {
912 // setRobotToFiducialTransform(baseToFiducial);
913 // }
914  public void setRobotToFiducialTransform(TransformNR baseToFiducial) {
915  if (baseToFiducial == null) {
916  Log.error("Fiducial can not be null " + baseToFiducial);
917  new Exception().printStackTrace(System.out);
918  return;
919  }
920  Log.info("Setting Fiducial To base Transform " + baseToFiducial);
921  this.base2Fiducial = baseToFiducial;
922  for (IRegistrationListenerNR r : regListeners) {
923  r.onBaseToFiducialUpdate(this, baseToFiducial);
924  }
925 
926  runRenderWrangler();
927  }
928 // /**
929 // * Sets the zframe to global transform.
930 // *
931 // * @param fiducialToRAS the new zframe to global transform
932 // */
933 // @Deprecated
934 // private void setZframeToGlobalTransform(TransformNR fiducialToRAS) {
935 // setGlobalToFiducialTransform(fiducialToRAS);
936 // }
937 
944  return base2Fiducial;
945  }
946 
952  public void setGlobalToFiducialTransform(TransformNR frameToBase, boolean fireUpdate) {
953  if (frameToBase == null) {
954  Log.error("Fiducial can not be null " + frameToBase);
955  new Exception("Fiducial can not be null ").printStackTrace(System.out);
956  return;
957  }
958  this.fiducial2RAS = frameToBase;
959  if(!fireUpdate)
960  return;
961  for (int i = 0; i < regListeners.size(); i++) {
962  IRegistrationListenerNR r = regListeners.get(i);
963  r.onFiducialToGlobalUpdate(this, frameToBase);
964  }
965 
966  runRenderWrangler();
967 
968  }
974  public void setGlobalToFiducialTransform(TransformNR frameToBase) {
975  setGlobalToFiducialTransform(frameToBase, true);
976  }
984  // System.out.println("RobotToFiducialTransform
985  // "+getRobotToFiducialTransform());
986  // System.out.println("FiducialToRASTransform "+getFiducialToRASTransform());
987  Matrix globalToFeducialInverse = getFiducialToGlobalTransform().getMatrixTransform().inverse();
988  Matrix feducialToLimbInverse = getRobotToFiducialTransform().getMatrixTransform().inverse();
989 
990  Matrix NewGlobalSpaceTarget = t.getMatrixTransform();
991  Matrix limbSpaceTarget = feducialToLimbInverse.times(globalToFeducialInverse).times(NewGlobalSpaceTarget);
992 
993  return new TransformNR(limbSpaceTarget);
994  }
995 
1003  Matrix feducialToLimb = getRobotToFiducialTransform().getMatrixTransform();
1004  Matrix globaltoFeducial = getFiducialToGlobalTransform().getMatrixTransform();
1005  Matrix fkOfLimb = t.getMatrixTransform();
1006  Matrix mForward = globaltoFeducial.times(feducialToLimb).times(fkOfLimb);
1007  return new TransformNR(mForward);
1008  }
1009 
1016  if (jointSpaceUpdateListeners.contains(l) || l == null)
1017  return;
1018  jointSpaceUpdateListeners.add(l);
1019  }
1020 
1027  if (jointSpaceUpdateListeners.contains(l))
1028  jointSpaceUpdateListeners.remove(l);
1029  }
1030 
1037  if (regListeners.contains(l) || l == null)
1038  return;
1039  regListeners.add(l);
1040  l.onBaseToFiducialUpdate(this, getRobotToFiducialTransform());
1041  }
1042 
1049  if (regListeners.contains(l))
1050  regListeners.remove(l);
1051  }
1052 
1059  if (taskSpaceUpdateListeners.contains(l) || l == null) {
1060  return;
1061  }
1062  // new RuntimeException("adding "+l.getClass().getName()).printStackTrace();
1063  taskSpaceUpdateListeners.add(l);
1064  }
1065 
1072  if (taskSpaceUpdateListeners.contains(l)) {
1073  // new RuntimeException("Removing "+l.getClass().getName()).printStackTrace();
1074  taskSpaceUpdateListeners.remove(l);
1075  }
1076  }
1077 
1078  /*
1079  * (non-Javadoc)
1080  *
1081  * @see
1082  * com.neuronrobotics.sdk.addons.kinematics.ILinkListener#onLinkPositionUpdate(
1083  * com.neuronrobotics.sdk.addons.kinematics.AbstractLink, double)
1084  */
1085  @Override
1086  public void onLinkPositionUpdate(AbstractLink source, double engineeringUnitsValue) {
1087  for (LinkConfiguration c : getLinkConfigurations()) {
1088  AbstractLink tmp = getFactory().getLink(c);
1089  if (tmp == source) {// Check to see if this lines up with a known link
1090 // // Log.info("Got PID event "+source+" value="+engineeringUnitsValue);
1091 // if(new Double(engineeringUnitsValue).isNaN()) {
1092 // new RuntimeException("Link values can not ne NaN").printStackTrace();
1093 // engineeringUnitsValue=0;
1094 // }
1095 // ArrayList<LinkConfiguration> linkConfigurations = getLinkConfigurations();
1096 // if(linkConfigurations!=null) {
1097 // int indexOf = linkConfigurations.indexOf(c);
1098 // if(currentJointSpacePositions!=null)
1099 // if(indexOf>=0 && indexOf<currentJointSpacePositions.length)
1100 // currentJointSpacePositions[indexOf] = engineeringUnitsValue;
1101 // }
1102  firePoseUpdate();
1103  return;
1104  }
1105  }
1106  Log.error("Got UKNOWN PID event " + source);
1107  }
1108 
1109 
1110 
1111  /*
1112  * (non-Javadoc)
1113  *
1114  * @see
1115  * com.neuronrobotics.sdk.pid.IPIDEventListener#onPIDEvent(com.neuronrobotics.
1116  * sdk.pid.PIDEvent)
1117  */
1118  @Override
1119  public void onPIDEvent(PIDEvent e) {
1120  // Ignore and use Link space events
1121  }
1122 
1123  /*
1124  * (non-Javadoc)
1125  *
1126  * @see com.neuronrobotics.sdk.pid.IPIDEventListener#onPIDLimitEvent(com.
1127  * neuronrobotics.sdk.pid.PIDLimitEvent)
1128  */
1129  @Override
1131  for (int i = 0; i < getNumberOfLinks(); i++) {
1132  if (getLinkConfiguration(i).getHardwareIndex() == e.getGroup())
1133  fireJointSpaceLimitUpdate(i, new JointLimit(i, e, getLinkConfiguration(i)));
1134  }
1135  }
1136 
1137  /*
1138  * (non-Javadoc)
1139  *
1140  * @see com.neuronrobotics.sdk.pid.IPIDEventListener#onPIDReset(int, int)
1141  */
1142  @Override
1143  public void onPIDReset(int group, float currentValue) {
1144  // ignore at this level
1145  }
1146 
1150  public void homeAllLinks() {
1151 
1152  for (int i = 0; i < getNumberOfLinks(); i++) {
1153 
1154  homeLink(i);
1155  // ThreadUtil.wait(2000);
1156  }
1157 
1158  }
1159 
1164  private long homeTime;
1165 
1172  private void runHome(PIDChannel joint, int tps) {
1173  IPIDEventListener listen = new IPIDEventListener() {
1174 
1175  @Override
1176  public void onPIDReset(int group, float currentValue) {
1177  }
1178 
1179  @Override
1180  public void onPIDLimitEvent(PIDLimitEvent e) {
1181  homeTime = 0;// short circut the waiting loop
1182  Log.debug("Homing PID Limit event " + e);
1183  }
1184 
1185  @Override
1186  public void onPIDEvent(PIDEvent e) {
1187  homeTime = System.currentTimeMillis();
1188  }
1189  };
1190  joint.addPIDEventListener(listen);
1191  homeTime = System.currentTimeMillis();
1192 
1193  joint.SetPIDSetPoint(tps, 0);
1194  Log.info("Homing output to value: " + tps);
1195  while ((System.currentTimeMillis() < homeTime + 3000)) {
1196  ThreadUtil.wait(100);
1197  }
1198  joint.removePIDEventListener(listen);
1199  }
1200 
1206  public void homeLink(int link) {
1207  if (link < 0 || link >= getNumberOfLinks()) {
1208  throw new IndexOutOfBoundsException(
1209  "There are only " + getNumberOfLinks() + " known links, requested:" + link);
1210  }
1211  LinkConfiguration conf = getLinkConfiguration(link);
1212  if (conf.getTypeEnum() == LinkType.PID) {
1213  getFactory().getPid(conf).removePIDEventListener(this);
1214  // Range is in encoder units
1215  double range = Math.abs(conf.getUpperLimit() - conf.getLowerLimit()) * 2;
1216 
1217  Log.info("Homing link:" + link + " to latch value: " + conf.getIndexLatch());
1218  PIDConfiguration pidConf = getLinkCurrentConfiguration(link);
1219  PIDChannel joint = getFactory().getPid(conf).getPIDChannel(conf.getHardwareIndex());
1220 
1221  // Clear the index
1222  pidConf.setStopOnIndex(false);
1223  pidConf.setUseLatch(false);
1224  pidConf.setIndexLatch(conf.getIndexLatch());
1225  joint.ConfigurePIDController(pidConf);// Sets up the latch
1226 
1227  // Move forward to stop
1228  runHome(joint, (int) (range));
1229 
1230  // Enable index
1231  pidConf.setStopOnIndex(true);
1232  pidConf.setUseLatch(true);
1233  pidConf.setIndexLatch(conf.getIndexLatch());
1234  joint.ConfigurePIDController(pidConf);// Sets up the latch
1235  // Move negative to the index
1236  runHome(joint, (int) (range * -1));
1237 
1238  pidConf.setStopOnIndex(false);
1239  pidConf.setUseLatch(false);
1240  pidConf.setIndexLatch(conf.getIndexLatch());
1241  joint.ConfigurePIDController(pidConf);// Shuts down the latch
1242 
1243  try {
1244  setDesiredJointAxisValue(link, 0, 0);// go to zero instead of to the index itself
1245  } catch (Exception e) {
1246  e.printStackTrace();
1247  }
1248  getFactory().getPid(conf).addPIDEventListener(this);
1249  } else {
1250  getFactory().getLink(getLinkConfiguration(link)).Home();
1251  getFactory().flush(1000);
1252  }
1253  }
1254 
1258  public void emergencyStop() {
1259  for (LinkConfiguration lf : getFactory().getLinkConfigurations())
1260  if (getFactory().getPid(lf) != null)
1261  getFactory().getPid(lf).killAllPidGroups();
1262  }
1263 
1264 // public void setAxisPidConfiguration(ArrayList<PIDConfiguration> conf) {
1265 // this.pidConfigurations = conf;
1266 // }
1267 
1273  public ArrayList<PIDConfiguration> getAxisPidConfiguration() {
1274  return pidConfigurations;
1275  }
1276 
1284  public abstract double[] inverseKinematics(TransformNR taskSpaceTransform) throws Exception;
1285 
1292  public abstract TransformNR forwardKinematics(double[] jointSpaceVector);
1293 
1300  if (currentPoseTarget == null)
1301  currentPoseTarget = calcHome();
1302  return currentPoseTarget;
1303  }
1304 
1310  public void setCurrentPoseTarget(TransformNR currentPoseTarget) {
1311  this.currentPoseTarget = currentPoseTarget;
1312  for (ITaskSpaceUpdateListenerNR p : taskSpaceUpdateListeners) {
1313  p.onTargetTaskSpaceUpdate(this, currentPoseTarget);
1314  }
1315  }
1316 
1322  public void setFactory(LinkFactory factory) {
1323  this.factory = factory;
1324  }
1325 
1332  if (factory == null)
1333  factory = new LinkFactory();
1334  return factory;
1335  }
1336 
1342  public void setNoFlush(boolean noFlush) {
1343  this.noFlush = noFlush;
1344  }
1345 
1351  public boolean isNoFlush() {
1352  return noFlush;
1353  }
1354 
1361  return retryNumberBeforeFail;
1362  }
1363 
1369  public void setRetryNumberBeforeFail(int retryNumberBeforeFail) {
1370  this.retryNumberBeforeFail = retryNumberBeforeFail;
1371  }
1372 
1373  /*
1374  * (non-Javadoc)
1375  *
1376  * @see com.neuronrobotics.sdk.addons.kinematics.ILinkListener#onLinkLimit(com.
1377  * neuronrobotics.sdk.addons.kinematics.AbstractLink,
1378  * com.neuronrobotics.sdk.pid.PIDLimitEvent)
1379  */
1380  @Override
1381  public void onLinkLimit(AbstractLink arg0, PIDLimitEvent arg1) {
1382  for (int i = 0; i < getNumberOfLinks(); i++) {
1383  if (getLinkConfiguration(i).getHardwareIndex() == arg0.getLinkConfiguration().getHardwareIndex())
1384  fireJointSpaceLimitUpdate(i, new JointLimit(i, arg1, arg0.getLinkConfiguration()));
1385  }
1386  }
1387 
1388 
1395  return dhParametersChain;
1396  }
1397 
1403  public void setDhParametersChain(DHChain dhParametersChain) {
1404  this.dhParametersChain = dhParametersChain;
1405  }
1406 
1412  public String[] getGitDhEngine() {
1413  return dhEngine;
1414  }
1415 
1421  public void setGitDhEngine(String[] dhEngine) {
1422  if (dhEngine != null && dhEngine[0] != null && dhEngine[1] != null)
1423  this.dhEngine = dhEngine;
1424  }
1425 
1431  public String[] getGitCadEngine() {
1432  return cadEngine;
1433  }
1434 
1440  public void setGitCadEngine(String[] cadEngine) {
1441  if (cadEngine != null && cadEngine[0] != null && cadEngine[1] != null)
1442  this.cadEngine = cadEngine;
1443  }
1444 
1452  protected String getCode(Element e, String tag) {
1453  try {
1454  NodeList nodListofLinks = e.getChildNodes();
1455 
1456  for (int i = 0; i < nodListofLinks.getLength(); i++) {
1457  Node linkNode = nodListofLinks.item(i);
1458  if (linkNode.getNodeType() == Node.ELEMENT_NODE && linkNode.getNodeName().contentEquals(tag)) {
1459  return XmlFactory.getTagValue(tag, e);
1460  }
1461  }
1462  } catch (Exception ex) {
1463  ex.printStackTrace();
1464  }
1465  throw new RuntimeException("No tag " + tag + " found");
1466  }
1467 
1475  protected String[] getGitCodes(Element doc, String tag) {
1476  String[] content = new String[3];
1477  try {
1478  NodeList nodListofLinks = doc.getChildNodes();
1479  for (int i = 0; i < nodListofLinks.getLength(); i++) {
1480  Node linkNode = nodListofLinks.item(i);
1481  if (linkNode.getNodeType() == Node.ELEMENT_NODE && linkNode.getNodeName().contentEquals(tag)) {
1482  Element e = (Element) linkNode;
1483  try {
1484  if (getCode(e, "gist") != null)
1485  content[0] = "https://gist.github.com/" + getCode(e, "gist") + ".git";
1486  } catch (Exception ex) {
1487 
1488  }
1489  try {
1490  if (getCode(e, "git") != null)
1491  content[0] = getCode(e, "git");
1492  } catch (Exception ex) {
1493 
1494  }
1495  try {
1496  if (getCode(e, "parallelGroup") != null)
1497  content[2] = getCode(e, "parallelGroup");
1498  } catch (Exception ex) {
1499 
1500  }
1501  content[1] = getCode(e, "file");
1502  }
1503  }
1504  return content;
1505  } catch (Exception e) {
1506  e.printStackTrace();
1507  }
1508  return null;
1509  }
1510 
1511  public IMU getImu() {
1512  return imu;
1513  }
1514 
1515  // New helper functions to make the API simpler
1516 
1517  public void boundedLinkValueSet(int index, double value) throws Exception {
1518  value = boundToLinkLimits(index, value);
1519  double[] vect = getCurrentJointSpaceVector();
1520  vect[index] = value;
1521  setDesiredJointSpaceVector(vect, 0);
1522  }
1523 
1524  public double boundToLinkLimits(int index, double value) {
1525  AbstractLink l1 = getAbstractLink(index);
1526  if (value > l1.getMaxEngineeringUnits()) {
1527  value = l1.getMaxEngineeringUnits();
1528  }
1529  if (value < l1.getMinEngineeringUnits()) {
1530  value = l1.getMinEngineeringUnits();
1531  }
1532  return value;
1533  }
1534 
1535  public double linkMass(int linkIndex) {
1536  return getLinkConfiguration(linkIndex).getMassKg();
1537  }
1538 
1544  public double getMaxEngineeringUnits(int linkIndex) {
1545  return getAbstractLink(linkIndex).getMaxEngineeringUnits();
1546  }
1547 
1553  public double getMinEngineeringUnits(int linkIndex) {
1554 
1555  return getAbstractLink(linkIndex).getMinEngineeringUnits();
1556  }
1557 
1563  public void setMaxEngineeringUnits(int linkIndex, double maxLimit) {
1564  getAbstractLink(linkIndex).setMaxEngineeringUnits(maxLimit);
1565  }
1566 
1572  public void setMinEngineeringUnits(int linkIndex, double minLimit) {
1573 
1574  getAbstractLink(linkIndex).setMinEngineeringUnits(minLimit);
1575  }
1576  public String getElectroMechanicalType(int linkIndex) {
1577  return getLinkConfiguration(linkIndex).getElectroMechanicalType() ;
1578  }
1579 
1580  public void setElectroMechanicalType(int linkIndex,String electroMechanicalType) {
1581  getLinkConfiguration(linkIndex).setElectroMechanicalType(electroMechanicalType);
1582  }
1583 
1584  public String getElectroMechanicalSize(int linkIndex) {
1585  return getLinkConfiguration(linkIndex).getElectroMechanicalSize() ;
1586  }
1587 
1588  public void setElectroMechanicalSize(int linkIndex,String electroMechanicalSize) {
1589  getLinkConfiguration(linkIndex).setElectroMechanicalSize(electroMechanicalSize);
1590  }
1591 
1592  public String getShaftType(int linkIndex) {
1593  return getLinkConfiguration(linkIndex).getShaftType();
1594  }
1595 
1596  public void setShaftType(int linkIndex,String shaftType) {
1597  getLinkConfiguration(linkIndex).setShaftType(shaftType);
1598  }
1599 
1600  public String getShaftSize(int linkIndex) {
1601  return getLinkConfiguration(linkIndex).getShaftSize();
1602  }
1606  public void setDeviceMaximumValue(int linkIndex,double max) {
1607  getLinkConfiguration(linkIndex).setDeviceTheoreticalMax(max);
1608  }
1613  public void setDeviceMinimumValue(int linkIndex,double min) {
1614  getLinkConfiguration(linkIndex).setDeviceTheoreticalMin(min);
1615  }
1620  public double getDeviceMaximumValue(int linkIndex) {
1621  return getLinkConfiguration(linkIndex).getDeviceTheoreticalMax();
1622  }
1627  public double getDeviceMinimumValue(int linkIndex) {
1628  return getLinkConfiguration(linkIndex).getDeviceTheoreticalMin();
1629  }
1631  getLinkConfiguration(linkIndex).addChangeListener(l);
1632  }
1634  getLinkConfiguration(linkIndex).removeChangeListener(l);
1635  }
1636  public void clearChangeListener(int linkIndex) {
1637  getLinkConfiguration(linkIndex).clearChangeListener();
1638  }
1639 
1640 
1641 
1642  public void runRenderWrangler() {
1643  firePoseUpdate();
1644  if(renderWrangler!=null)
1645  try {
1646  renderWrangler.run();
1647  }catch(Throwable t) {
1648  t.printStackTrace();
1649  }
1650  }
1651 
1652  public void setRenderWrangler(Runnable renderWrangler) {
1653  this.renderWrangler = renderWrangler;
1654  }
1655 
1657  TransformNR startingPoint = getCurrentPoseTarget();
1658  // create a transform thats a delta from the current pose to the new pose
1659  return startingPoint.inverse().times(target);
1660  }
1661 
1662  public TransformNR getTipAlongTrajectory(TransformNR startingPoint,TransformNR deltaToTarget,double unitIncrement) {
1663  return startingPoint.times(deltaToTarget.scale(unitIncrement));
1664  }
1665  public void asyncInterpolatedMove(TransformNR target, double seconds, InterpolationType type,IOnInterpolationDone listener, double ...conf ) {
1666  new Thread(()->{
1667  try {
1668  InterpolationMoveState s = blockingInterpolatedMove(target, seconds, type, conf);
1669  listener.done(s);
1670  }catch(Throwable t) {
1671  t.printStackTrace();
1672  listener.done(InterpolationMoveState.FAULT);
1673  }
1674  }).start();
1675 
1676  }
1677 
1678  public InterpolationMoveState blockingInterpolatedMove(TransformNR target, double seconds, InterpolationType type, double ...conf ) {
1680  long currentTimeMillis = System.currentTimeMillis();
1681  TransformNR delta =getDeltaToTarget(target);
1682  TransformNR startingPoint = getCurrentPoseTarget();
1683  if (checkTaskSpaceTransform(target)) {
1684  if (!checkTaskSpaceTransform(target, seconds)) {
1685  // if the robot can not acive that speed, then compute the best possible time
1686  double bestTime = getBestTime(target);
1687  // if speed is capped and no valid, then just cap the speed and print a warning
1688  if (bestTime > seconds) {
1689  seconds = bestTime;
1690  }
1691  }
1692 
1693  engine.setSetpointWithTime(currentTimeMillis,1,seconds,type,conf);
1694  double ms = seconds * 1000;
1695  double msPerStep = 10;
1696  double steps = ms / msPerStep;
1697  double unitIncrement = 1.0 / steps;
1698  // iterate over all of the time slices to perfoem a task-space interpolation
1699  for (double i = 0; i < (1 + unitIncrement); i += unitIncrement) {
1700  // compute the next tip location
1701  // the delta of the overall translation above is scaled by the unit vector
1702  // of the translation
1703  // the new tip point here calculated is multiplied by the starting point to get
1704  // a global space tip target
1705  TransformNR nextPoint = getTipAlongTrajectory(startingPoint,delta,engine.getInterpolationUnitIncrement(System.currentTimeMillis()));
1706  // now the best time for this increment is calculated
1707  double bestTime = getBestTime(nextPoint);
1708  // error check for the best time being below the commanded time
1709  if (bestTime > msPerStep / 1000.0) {
1710  // print an error in the event of speed capped
1711  }
1712  // perform one last tip and speed check of the increment
1713  if (checkTaskSpaceTransform(nextPoint, bestTime)) {
1714  // send the tip update to the simulator
1715  try {
1716  setDesiredTaskSpaceTransform(nextPoint, bestTime);
1717  } catch (Exception e) {
1719  }
1720  } else {
1721  // incremental tip failed, fault
1723  }
1724  ThreadUtil.wait((int) msPerStep);
1725  }
1726  }else {
1728  }
1730  }
1731 }
static boolean checkTaskSpaceTransform(AbstractKinematicsNR dev, TransformNR taskSpaceTransform, double seconds)
InterpolationMoveState blockingInterpolatedMove(TransformNR target, double seconds, InterpolationType type, double ...conf)
void addChangeListener(int linkIndex, ILinkConfigurationChangeListener l)
void setElectroMechanicalType(int linkIndex, String electroMechanicalType)
abstract TransformNR forwardKinematics(double[] jointSpaceVector)
void onLinkPositionUpdate(AbstractLink source, double engineeringUnitsValue)
boolean checkTaskSpaceTransform(TransformNR taskSpaceTransform, double seconds)
void setGlobalToFiducialTransform(TransformNR frameToBase, boolean fireUpdate)
void fireTargetJointsUpdate(double[] jointSpaceVector, TransformNR fwd)
void setElectroMechanicalSize(int linkIndex, String electroMechanicalSize)
double[] _setDesiredJointSpaceVector(double[] jointSpaceVect, double seconds, boolean fireTaskUpdate)
double getBestTime(TransformNR currentTaskSpaceTransform)
void asyncInterpolatedMove(TransformNR target, double seconds, InterpolationType type, IOnInterpolationDone listener, double ...conf)
void setDesiredJointAxisValue(int axis, double value, double seconds)
void setDevice(LinkFactory f, ArrayList< LinkConfiguration > linkConfigs)
static boolean checkVector(AbstractKinematicsNR dev, double[] jointSpaceVect, double seconds)
TransformNR getTipAlongTrajectory(TransformNR startingPoint, TransformNR deltaToTarget, double unitIncrement)
double[] setDesiredJointSpaceVector(double[] jointSpaceVect, double seconds)
abstract double[] inverseKinematics(TransformNR taskSpaceTransform)
void removeChangeListener(int linkIndex, ILinkConfigurationChangeListener l)
double[] setDesiredTaskSpaceTransform(TransformNR taskSpaceTransform, double seconds)
static boolean checkTaskSpaceTransform(AbstractKinematicsNR dev, TransformNR taskSpaceTransform)
static String getTagValue(String sTag, Element eElement)
Definition: XmlFactory.java:77
static Document getAllNodesDocument(InputStream config)
Definition: XmlFactory.java:37
static void info(String message)
Definition: Log.java:110
static void error(String message)
Definition: Log.java:92
static void debug(String message)
Definition: Log.java:128
static void tic(String message)
Definition: TickToc.java:32
void setSetpointWithTime(long startTimeMs, double setpoint, double seconds, InterpolationType mode, double ...conf)
boolean SetPIDSetPoint(float setpoint, double seconds)
Definition: PIDChannel.java:47
void removePIDEventListener(IPIDEventListener l)
void addPIDEventListener(IPIDEventListener l)
boolean ConfigurePIDController(PIDConfiguration config)
Definition: PIDChannel.java:91
void onJointSpaceUpdate(AbstractKinematicsNR source, double[] joints)
void onBaseToFiducialUpdate(AbstractKinematicsNR source, TransformNR regestration)
void onFiducialToGlobalUpdate(AbstractKinematicsNR source, TransformNR regestration)
void onTaskSpaceUpdate(AbstractKinematicsNR source, TransformNR pose)