BowlerKernel
DHParameterKinematics.java
Go to the documentation of this file.
1 package com.neuronrobotics.sdk.addons.kinematics;
2 
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.InputStream;
7 import java.util.ArrayList;
8 
9 import org.w3c.dom.Element;
10 
11 import Jama.Matrix;
12 import javafx.scene.transform.Affine;
13 
14 import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
15 import com.neuronrobotics.sdk.addons.kinematics.xml.XmlFactory;
16 import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
17 import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
18 
19 // TODO: Auto-generated Javadoc
25 
27  private DHChain chain = null;
28 
30  private ArrayList<Object> linksListeners = new ArrayList<Object>();
31 
33  private Object currentTarget = new Object();
34 
36  boolean disconnecting = false;
37 
40  @Override
41  public void onDisconnect(BowlerAbstractDevice source) {
42  if (!disconnecting) {
43  disconnecting = true;
44  //disconnect();
45  }
46 
47  }
48 
49  @Override
50  public void onConnect(BowlerAbstractDevice source) {
51  }
52  };
53 
54  private ArrayList<LinkConfiguration> configs;
55 
64  public DHParameterKinematics(BowlerAbstractDevice bad, Element linkStream) {
65  super(linkStream, new LinkFactory(bad));
68  if (getFactory().getDyio(lf) != null) {
70  return;
71  }
73 
74  @Override
75  public void onDisconnect(BowlerAbstractDevice source) {
76  for(int i=0;i<getNumberOfLinks();i++) {
78  if(m!=null)
79  m.disconnect();
80  }
81  }
82 
83  @Override
84  public void onConnect(BowlerAbstractDevice source) {
85  // TODO Auto-generated method stub
86 
87  }
88  });
89  }
90 
99  public DHParameterKinematics(BowlerAbstractDevice bad, InputStream linkStream) {
100  super(linkStream, new LinkFactory(bad));
103  if (getFactory().getDyio(lf) != null) {
105  return;
106  }
107  }
108 
119  @Deprecated
120  public DHParameterKinematics(BowlerAbstractDevice bad, InputStream linkStream, InputStream depricated) {
121  this(bad, linkStream);
122  }
123 
131  this(bad, XmlFactory.getDefaultConfigurationStream("TrobotLinks.xml"));
132  }
133 
142  public DHParameterKinematics(BowlerAbstractDevice bad, String file) {
143  this(bad, XmlFactory.getDefaultConfigurationStream(file));
144  }
145 
156  public DHParameterKinematics(BowlerAbstractDevice bad, File configFile) throws FileNotFoundException {
157  this(bad, new FileInputStream(configFile));
158  }
159 
164  this(null,(InputStream)null);
165  }
166 
173  public DHParameterKinematics(String file) {
174  this(null, XmlFactory.getDefaultConfigurationStream(file));
175  }
176 
183  public DHParameterKinematics(Element linkStream) {
184  this(null, linkStream);
185  }
186 
195  public DHParameterKinematics(File configFile) throws FileNotFoundException {
196  this(null, new FileInputStream(configFile));
197  }
198 
199  /*
200  * (non-Javadoc)
201  *
202  * @see com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR#
203  * inverseKinematics(com.neuronrobotics.sdk.addons.kinematics.math.TransformNR)
204  */
205  @Override
206  public double[] inverseKinematics(TransformNR taskSpaceTransform) throws Exception {
207  return getDhChain().inverseKinematics(taskSpaceTransform, getCurrentJointSpaceVector());
208  }
209 
210  /*
211  * (non-Javadoc)
212  *
213  * @see com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR#
214  * forwardKinematics(double[])
215  */
216  @Override
217  public TransformNR forwardKinematics(double[] jointSpaceVector) {
218  if (jointSpaceVector == null || getDhChain() == null)
219  return new TransformNR();
220  TransformNR rt = getDhChain().forwardKinematics(jointSpaceVector);
221  return rt;
222  }
230  private double [] crossProduct(double[] a, double[] b){
231  double [] xProd = new double [3];
232 
233  xProd[0]=a[1]*b[2]-a[2]*b[1];
234  xProd[1]=a[2]*b[0]-a[0]*b[2];
235  xProd[2]=a[0]*b[1]-a[1]*b[0];
236 
237  return xProd;
238  }
245  public Matrix getJacobian(DHChain chain, double[] jointSpaceVector, int index){
246  int size = chain.getLinks().size();
247  double [][] data = new double[6][size];
248  chain.getChain(jointSpaceVector);
249  for(int i=0;i<size;i++){
250  if(i>index) continue;
251  Matrix rotationComponent = forwardOffset(new TransformNR()).getMatrixTransform();
252  for(int j=i;j<size && j<=index;j++) {
253  double value=0;
254  if(chain.getLinks().get(j).getLinkType()==DhLinkType.ROTORY)
255  value=Math.toRadians(jointSpaceVector[j]);
256  else
257  value=jointSpaceVector[j];
258  Matrix step = chain.getLinks().get(j).DhStep(value);
259  //Log.info( "Current:\n"+current+"Step:\n"+step);
260  //println i+" Link "+j+" index "+index+" step "+TransformNR.getMatrixString(step)
261  rotationComponent = rotationComponent.times(step);
262  }
263  double [] zVect = new double [3];
264  double [] zVectEnd = new double [3];
265  double [][] rotation=new TransformNR(rotationComponent).getRotationMatrix().getRotationMatrix();
266  zVectEnd[0]=rotation[2][2];
267  zVectEnd[1]=rotation[2][1];
268  zVectEnd[2]=rotation[2][0];
269  if(i==0 && index ==0 ){
270  zVect[0]=0;
271  zVect[1]=0;
272  zVect[2]=1;
273  }else if(i<=index){
274  //println "Link "+index+" "+TransformNR.getMatrixString(new Matrix(rotation))
275  //Get the rz vector from matrix
276  zVect[0]=zVectEnd[0];
277  zVect[1]=zVectEnd[1];
278  zVect[2]=zVectEnd[2];
279  }else{
280  zVect[0]=0;
281  zVect[1]=0;
282  zVect[2]=0;
283  }
284  //Assume all rotational joints
285  //Set to zero if prismatic
286  if(chain.getLinks().get(i).getLinkType()==DhLinkType.ROTORY){
287  data[3][i]=zVect[0];
288  data[4][i]=zVect[1];
289  data[5][i]=zVect[2];
290  }else{
291  data[3][i]=0;
292  data[4][i]=0;
293  data[5][i]=0;
294  }
295  double []rVect = new double [3];
296  Matrix rComponentmx = forwardOffset(new TransformNR()).getMatrixTransform();
297  for(int j=0;j<i ;j++) {
298  double value=0;
299  if(chain.getLinks().get(j).getLinkType()==DhLinkType.ROTORY)
300  value=Math.toRadians(jointSpaceVector[j]);
301  else
302  value=jointSpaceVector[j];
303  Matrix step = chain.getLinks().get(j).DhStep(value);
304  //Log.info( "Current:\n"+current+"Step:\n"+step);
305  //println i+" Link "+j+" index "+index+" step "+TransformNR.getMatrixString(step)
306  rComponentmx = rComponentmx.times(step);
307  }
308  //Figure out the current
309  Matrix tipOffsetmx =forwardOffset( new TransformNR()).getMatrixTransform();
310  for(int j=0;j<size && j<=index;j++) {
311  double value=0;
312  if(chain.getLinks().get(j).getLinkType()==DhLinkType.ROTORY)
313  value=Math.toRadians(jointSpaceVector[j]);
314  else
315  value=jointSpaceVector[j];
316  Matrix step = chain.getLinks().get(j).DhStep(value);
317  //Log.info( "Current:\n"+current+"Step:\n"+step);
318  //println i+" Link "+j+" index "+index+" step "+TransformNR.getMatrixString(step)
319  tipOffsetmx = tipOffsetmx.times(step);
320  }
321  double []tipOffset = new double [3];
322  double []rComponent = new double [3];
323  TransformNR tipOffsetnr = new TransformNR(tipOffsetmx);//.times(myInvertedStarting);
324  tipOffset[0]=tipOffsetnr.getX();
325  tipOffset[1]=tipOffsetnr.getY();
326  tipOffset[2]=tipOffsetnr.getZ();
327  TransformNR rComponentnr = new TransformNR(rComponentmx);//.times(myInvertedStarting);
328  rComponent[0]=rComponentnr.getX();
329  rComponent[1]=rComponentnr.getY();
330  rComponent[2]=rComponentnr.getZ();
331  for(int x=0;x<3;x++)
332  rVect[x]=(tipOffset[x]-rComponent[x]);
333  //Cross product of rVect and Z vect
334  double []xProd = crossProduct( zVect,rVect);
335  data[0][i]=xProd[0];
336  data[1][i]=xProd[1];
337  data[2][i]=xProd[2];
338  }
339  //println "\n\n"
340  return new Matrix(data);
341  }
342 
348  public Matrix getJacobian() {
349  return getJacobian(getDhChain().getLinks().size()-1);
350  }
356  public Matrix getJacobian(int index) {
357  return getJacobian(getCurrentJointSpaceVector() , index) ;
358  }
364  public Matrix getJacobian(double[] jointSpaceVector,int index) {
365 
366  return getJacobian(getDhChain() , jointSpaceVector, index);
367  }
373  public ArrayList<TransformNR> getChainTransformations() {
375  }
376 
383  public void setDhChain(DHChain chain) {
384  this.setChain(chain);
385  }
386 
392  public DHChain getDhChain() {
393  return getChain();
394  }
395 
401  public DHChain getChain() {
402  return chain;
403  }
404 
411  public void setChain(DHChain chain) {
412  this.chain = chain;
413  ArrayList<DHLink> dhLinks = chain.getLinks();
414 // for (int i = linksListeners.size(); i < dhLinks.size(); i++) {
415 // linksListeners.add(new Object());
416 // }
417  LinkFactory lf = getFactory();
419  for (int i = 0; i < dhLinks.size(); i++) {
420  //dhLinks.get(i).setListener(linksListeners.get(i));
421  dhLinks.get(i).setRootListener(getRootListener());
422  // This mapps together the position of the links in the kinematics and the link
423  // actions themselves (used for cameras and tools)
424  //lf.getLink(configs.get(i)).setGlobalPositionListener(linksListeners.get(i));
425  if (getLinkConfiguration(i).isTool()) {
426  dhLinks.get(i).setLinkType(DhLinkType.TOOL);
427  } else if (getLinkConfiguration(i).isPrismatic())
428  dhLinks.get(i).setLinkType(DhLinkType.PRISMATIC);
429  else
430  dhLinks.get(i).setLinkType(DhLinkType.ROTORY);
431  }
432  addPoseUpdateListener(this);
433  addJointSpaceListener(this);
434  }
435 
436  /*
437  * (non-Javadoc)
438  *
439  * @see com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR#getXml()
440  */
441  /*
442  *
443  * Generate the xml configuration to generate an XML of this robot.
444  */
445  public String getXml() {
446  String xml = "<root>\n";
447  xml += getEmbedableXml();
448  xml += "\n</root>";
449  return xml;
450  }
451 
457  /*
458  *
459  * Generate the xml configuration to generate an XML of this robot.
460  */
461  public String getEmbedableXml() {
462 
463  String xml = "";
464 
465  xml += "\t<cadEngine>\n";
466  xml += "\t\t<git>" + getGitCadEngine()[0] + "</git>\n";
467  xml += "\t\t<file>" + getGitCadEngine()[1] + "</file>\n";
468  xml += "\t</cadEngine>\n";
469 
470  xml += "\t<kinematics>\n";
471  xml += "\t\t<git>" + getGitDhEngine()[0] + "</git>\n";
472  xml += "\t\t<file>" + getGitDhEngine()[1] + "</file>\n";
473  xml += "\t</kinematics>\n";
474 
475  ArrayList<DHLink> dhLinks = chain.getLinks();
476  for (int i = 0; i < dhLinks.size(); i++) {
477  xml += "<link>\n";
478  xml += getLinkConfiguration(i).getXml();
479  xml += dhLinks.get(i).getXml();
480  xml += "\n</link>\n";
481  }
482  xml += "\n<ZframeToRAS\n>";
484  xml += "\n</ZframeToRAS>\n";
485 
486  xml += "\n<baseToZframe>\n";
488  xml += "\n</baseToZframe>\n";
489  return xml;
490  }
491 
492  /*
493  * (non-Javadoc)
494  *
495  * @see com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR#
496  * disconnectDevice()
497  */
498  @Override
499  public void disconnectDevice() {
500  // TODO Auto-generated method stub
503  }
504 
505  /*
506  * (non-Javadoc)
507  *
508  * @see
509  * com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR#connectDevice()
510  */
511  @Override
512  public boolean connectDevice() {
513  // TODO Auto-generated method stub
514  return true;
515  }
516 
517  /*
518  * (non-Javadoc)
519  *
520  * @see com.neuronrobotics.sdk.addons.kinematics.ITaskSpaceUpdateListenerNR#
521  * onTaskSpaceUpdate(com.neuronrobotics.sdk.addons.kinematics.
522  * AbstractKinematicsNR,
523  * com.neuronrobotics.sdk.addons.kinematics.math.TransformNR)
524  */
525  @Override
527 
528  }
529 
530  /*
531  * (non-Javadoc)
532  *
533  * @see com.neuronrobotics.sdk.addons.kinematics.ITaskSpaceUpdateListenerNR#
534  * onTargetTaskSpaceUpdate(com.neuronrobotics.sdk.addons.kinematics.
535  * AbstractKinematicsNR,
536  * com.neuronrobotics.sdk.addons.kinematics.math.TransformNR)
537  */
538  @Override
540  // TODO Auto-generated method stub
541  // TransformFactory.getTransform(pose, getCurrentTargetObject());
542  }
543 
550  return chain.getInverseSolver();
551  }
552 
559  public void setInverseSolver(DhInverseSolver inverseSolver) {
560  chain.setInverseSolver(inverseSolver);
561  }
562 
568  public Object getCurrentTargetObject() {
569  return currentTarget;
570  }
571 
580  public void addNewLink(LinkConfiguration newLink, DHLink dhLink) {
582  // remove the link listener while the number of links could chnage
584  AbstractLink link = factory.getLink(newLink);// adds new link internally
585  if(dhLink.getListener()==null)
586  throw new RuntimeException("FAIL the link listner must be set to dhLink.setListener(new Affine());");
587  link.setGlobalPositionListener(dhLink.getListener());
589  chain.addLink(dhLink);
590  // set the modified kinematics chain
591  setChain(chain);
592  if (newLink.isTool()) {
593  dhLink.setLinkType(DhLinkType.TOOL);
594  } else if (newLink.isPrismatic())
596  else
597  dhLink.setLinkType(DhLinkType.ROTORY);
598  // once the new link configuration is set up, re add the listener
599  factory.addLinkListener(this);
601 
602  link.flush(0);
603  }
604 
611  public void removeLink(int index) {
613  // remove the link listener while the number of links could chnage
616  chain.getLinks().remove(index);
617  factory.deleteLink(index);
618  // set the modified kinematics chain
619  setChain(chain);
620  // once the new link configuration is set up, re add the listener
621  factory.addLinkListener(this);
622  }
623 
627  public ArrayList<TransformNR> updateCadLocations() {
628  try {
629  ArrayList<TransformNR> ll = getChain().getChain(getCurrentJointSpaceVector());
630  return ll;
631  } catch (Exception ex) {
632  // ex.printStackTrace();
633  }
634 
635  return null;
636  }
637 
638  /*
639  * (non-Javadoc)
640  *
641  * @see com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR#
642  * onJointSpaceUpdate(com.neuronrobotics.sdk.addons.kinematics.
643  * AbstractKinematicsNR, double[])
644  */
645  @Override
646  public void onJointSpaceUpdate(final AbstractKinematicsNR source, final double[] joints) {
647  ArrayList<TransformNR> cached=updateCadLocations();
648  if(cached!=null)
649  for(int i=0;i<joints.length;i++) {
650  DHLink dhLink = getChain().getLinks().get(i);
651  TransformNR newPose = cached.get(i);
652  dhLink.fireOnLinkGlobalPositionChange(newPose);
653  }
654  }
655 
662  @Override
663  public void setGlobalToFiducialTransform(TransformNR frameToBase) {
664  super.setGlobalToFiducialTransform(frameToBase);
665  if(getChain()!=null) {
666  getChain().setChain(null);// force an update of teh cached locations because base changed
667  try {
668  getChain().getChain(getCurrentJointSpaceVector());//calculate new locations
669  }catch(Exception e) {
670  throw new RuntimeException("Limb "+getScriptingName()+", "+e.getMessage());
671  }
672  }
674  }
675 
676  /*
677  * (non-Javadoc)
678  *
679  * @see com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR#
680  * onJointSpaceTargetUpdate(com.neuronrobotics.sdk.addons.kinematics.
681  * AbstractKinematicsNR, double[])
682  */
683  @Override
684  public void onJointSpaceTargetUpdate(AbstractKinematicsNR source, double[] joints) {
685  // TODO Auto-generated method stub
686 
687  }
688 
689  /*
690  * (non-Javadoc)
691  *
692  * @see com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR#
693  * onJointSpaceLimit(com.neuronrobotics.sdk.addons.kinematics.
694  * AbstractKinematicsNR, int,
695  * com.neuronrobotics.sdk.addons.kinematics.JointLimit)
696  */
697  @Override
698  public void onJointSpaceLimit(AbstractKinematicsNR source, int axis, JointLimit event) {
699  // TODO Auto-generated method stub
700 
701  }
702 
703  // New helper functions
704 
705  public TransformNR linkCoM(double linkAngleToClaculate, int linkIndex) {
706  double[] vectortail = getCurrentJointSpaceVector();
707  vectortail[linkIndex] = linkAngleToClaculate;
708  return getChain().getChain(vectortail).get(linkIndex)
709  .times(getLinkConfiguration(linkIndex).getCenterOfMassFromCentroid());
710 
711  }
712 
713  public TransformNR linkCoM(int linkIndex) {
714  return linkCoM(getCurrentJointSpaceVector()[linkIndex],linkIndex);
715  }
716  public Object getLinkObjectManipulator(int index) {
717  return getChain().getLinks().get(index).getListener();
718  }
725  public double getDH_Theta(int index) {
726  return getChain().getLinks().get(index).getTheta();
727  }
733  public double getDH_D(int index) {
734  return getChain().getLinks().get(index).getDelta();
735  }
736 
737 
738 
744  public double getDH_R(int index) {
745  return getChain().getLinks().get(index).getRadius();
746  }
747 
753  public double getDH_Alpha(int index) {
754  return getChain().getLinks().get(index).getAlpha();
755  }
756 
763  public void setDH_Theta(int index, double value) {
764  getChain().getLinks().get(index).setTheta(value);
765  }
771  public void setDH_D(int index, double value) {
772  getChain().getLinks().get(index).setDelta(value);
773  }
774 
775 
776 
782  public void setDH_R(int index, double value) {
783  getChain().getLinks().get(index).setRadius(value);
784  }
785 
791  public void setDH_Alpha(int index, double value) {
792  getChain().getLinks().get(index).setAlpha(value);
793  }
794 
795  public DHLink getDhLink(int i) {
796  return getDhChain().getLinks().get(i);
797  }
798  public Object getListener(int i) {
799  return getDhChain().getLinks().get(i).getListener();
800  }
806  @Override
807  public void setRobotToFiducialTransform(TransformNR newTrans) {
808  super.setRobotToFiducialTransform(newTrans);
809  }
810 
811  public void refreshPose() {
813  }
814  public MobileBase getSlaveMobileBase(int index) {
815  return getDhLink(index).getSlaveMobileBase();
816  }
824  public void throwExceptionOnJointLimit(boolean b) {
825  for(int i=0;i<getNumberOfLinks();i++) {
827  }
828  }
829 
830  public TransformNR getLinkTip(int linkIndex) {
831  return getChain().getCachedChain().get(linkIndex);
832  }
833 }
ArrayList< TransformNR > getCachedChain()
Definition: DHChain.java:273
void setChain(ArrayList< TransformNR > chain)
Definition: DHChain.java:248
TransformNR forwardKinematics(double[] jointSpaceVector)
Definition: DHChain.java:140
double[] inverseKinematics(TransformNR target, double[] jointSpaceVector)
Definition: DHChain.java:113
ArrayList< TransformNR > getChain(double[] jointSpaceVector)
Definition: DHChain.java:262
Matrix getJacobian(DHChain chain, double[] jointSpaceVector, int index)
DHParameterKinematics(BowlerAbstractDevice bad, InputStream linkStream)
DHParameterKinematics(BowlerAbstractDevice bad, Element linkStream)
DHParameterKinematics(BowlerAbstractDevice bad, InputStream linkStream, InputStream depricated)
void onJointSpaceTargetUpdate(AbstractKinematicsNR source, double[] joints)
void onTargetTaskSpaceUpdate(AbstractKinematicsNR source, TransformNR pose)
void onJointSpaceUpdate(final AbstractKinematicsNR source, final double[] joints)
void addNewLink(LinkConfiguration newLink, DHLink dhLink)
void onTaskSpaceUpdate(AbstractKinematicsNR source, TransformNR pose)
void onJointSpaceLimit(AbstractKinematicsNR source, int axis, JointLimit event)
TransformNR linkCoM(double linkAngleToClaculate, int linkIndex)
DHParameterKinematics(BowlerAbstractDevice bad, File configFile)
ArrayList< LinkConfiguration > getLinkConfigurations()
static InputStream getDefaultConfigurationStream(String file)
Definition: XmlFactory.java:27
void addConnectionEventListener(final IDeviceConnectionEventListener l)