GRL_Driver.java
Go to the documentation of this file.
1 package grl.driver;
2 
3 import static com.kuka.roboticsAPI.motionModel.BasicMotions.positionHold;
4 import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp;
5 
6 import grl.FRIMode;
9 import grl.TeachMode;
11 import grl.UDPManager;
12 import grl.flatbuffer.ArmState;
19 import grl.flatbuffer.Wrench;
20 
21 import java.io.IOException;
22 import java.net.UnknownHostException;
23 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.TimeoutException;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantLock;
27 
28 import com.google.flatbuffers.FlatBufferBuilder;
29 import com.google.flatbuffers.Table;
30 
31 // 1. Compiler error here? COMMENT ALL FLEXFELLOW AND MEDIAFLANGEIOGROUP lines
32 // 2. FlexFellow lines commented? DO NOT DELETE THEM, other people have different hardware!
33 // 3. Have a FlexFellow? Uncomment all the FlexFellow lines and the lights will let you know
34 // what mode the arm is in!
35 //
36 //import com.kuka.generated.ioAccess.FlexFellowIOGroup;
37 //import com.kuka.generated.ioAccess.MediaFlangeIOGroup;
38 import com.kuka.common.ThreadUtil;
39 import com.kuka.connectivity.fastRobotInterface.FRIConfiguration;
40 import com.kuka.connectivity.fastRobotInterface.FRIJointOverlay;
41 import com.kuka.connectivity.fastRobotInterface.FRISession;
42 import com.kuka.connectivity.fastRobotInterface.FRIChannelInformation.FRISessionState;
43 import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime;
44 import com.kuka.connectivity.motionModel.smartServo.ServoMotion;
45 import com.kuka.connectivity.motionModel.smartServo.ServoMotionJP;
46 import com.kuka.connectivity.motionModel.smartServo.SmartServo;
47 //import com.kuka.generated.ioAccess.FlexFellowIOGroup;
48 //import com.kuka.generated.ioAccess.MediaFlangeIOGroup;
49 import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication;
50 import com.kuka.roboticsAPI.controllerModel.Controller;
51 import com.kuka.roboticsAPI.controllerModel.recovery.IRecovery;
52 import com.kuka.roboticsAPI.deviceModel.JointLimits;
53 import com.kuka.roboticsAPI.deviceModel.JointPosition;
54 import com.kuka.roboticsAPI.deviceModel.LBR;
55 import com.kuka.roboticsAPI.executionModel.CommandInvalidException;
56 import com.kuka.roboticsAPI.executionModel.ExecutionState;
57 import com.kuka.roboticsAPI.executionModel.IExecutionContainer;
58 import com.kuka.roboticsAPI.geometricModel.CartDOF;
59 import com.kuka.roboticsAPI.geometricModel.LoadData;
60 import com.kuka.roboticsAPI.geometricModel.PhysicalObject;
61 import com.kuka.roboticsAPI.geometricModel.Tool;
62 import com.kuka.roboticsAPI.geometricModel.math.Vector;
63 import com.kuka.roboticsAPI.motionModel.HandGuidingMotion;
64 import com.kuka.roboticsAPI.motionModel.IMotion;
65 import com.kuka.roboticsAPI.motionModel.IMotionContainer;
66 import com.kuka.roboticsAPI.motionModel.IMotionContainerListener;
67 import com.kuka.roboticsAPI.motionModel.MotionBatch;
68 import com.kuka.roboticsAPI.motionModel.controlModeModel.AbstractMotionControlMode;
69 import com.kuka.roboticsAPI.motionModel.controlModeModel.CartesianImpedanceControlMode;
70 import com.kuka.roboticsAPI.motionModel.controlModeModel.CartesianSineImpedanceControlMode;
71 import com.kuka.roboticsAPI.motionModel.controlModeModel.HandGuidingControlMode;
72 import com.kuka.roboticsAPI.motionModel.controlModeModel.JointImpedanceControlMode;
73 import com.kuka.roboticsAPI.motionModel.controlModeModel.PositionControlMode;
74 import static com.kuka.roboticsAPI.motionModel.MMCMotions.*;
75 
76 /**
77  * Creates a FRI Session.
78  */
79 public class GRL_Driver extends RoboticsAPIApplication
80 {
81  private ProcessDataManager _processDataManager = null; // Stores variables that can be modified by teach pendant in "Process Data" Menu
82  private Controller _lbrController;
83  private LBR _lbr;
84  private StartStopSwitchUI _startStopUI = null;
85 
86  /// The interface on which commands are being sent to the robot controller (this program),
87  /// includes SmartServo, DirectServo, and FRI
88  private byte _commandInterface = KUKAiiwaInterface.SmartServo;
89 
90  /// The interface on which monitor data is being sent to the Laptop (C++ program over network)
91  /// This can be FRI (udp packets over KONI port for monitoring state) (works by default)
92  /// or SmartServo/DirectServo (JAVA UDP interface will be used to send position/torques back (not yet implemented)
93  private byte _monitorInterface = KUKAiiwaInterface.SmartServo;
94 
95  private FRIConfiguration _friConfiguration = null;
96  private FRISession _friSession = null;
97  private FRIJointOverlay _motionOverlay = null;
98  private FRIMode _FRIModeRunnable = null;
99  private Thread _FRIModeThread = null;
100  boolean waitingForUserToEndFRIMode = false;
101 
102  private SmartServo _smartServoMotion = null;
103  private ISmartServoRuntime _smartServoRuntime = null;
104 
105  private grl.flatbuffer.KUKAiiwaState _currentKUKAiiwaState = null;
106  private grl.flatbuffer.KUKAiiwaState _previousKUKAiiwaState = null;
107  private AbstractMotionControlMode _activeMotionControlMode;
108  private AbstractMotionControlMode _smartServoMotionControlMode;
109  private UpdateConfiguration _updateConfiguration;
110  private IRecovery _pausedApplicationRecovery = null;
111  private PhysicalObject _toolAttachedToLBR;
112  private HandGuidingMotion _handGuidingMotion;
113  /**
114  * gripper, tool or other physically attached object
115  * see "Template Data" panel in top right pane
116  * of Sunrise Workbench. This can't be created
117  * at runtime so we create one for you.
118  */
119  private Tool _flangeAttachment;
120  private JointLimits _jointLimits;
121  private double[] _maxAllowedJointLimits;
122  private double[] _minAllowedJointLimits;
123  private JointImpedanceControlMode _teachControlMode;
124  private TeachMode _teachModeRunnable = null;
125  private Thread _teachModeThread = null;
126  boolean waitingForUserToEndTeachMode = false;
127 
128 // private MediaFlangeIOGroup _mediaFlangeIOGroup; // this is an end effector flange with a blue ring and buttons on the arm tip
129 
130  static final boolean _flexFellowPresent = false; // this is a white an orange robot cart you can attach your arm to
131  static final boolean _mediaFlangeIOPresent = false;
132 
133  private boolean _canServo = true;
134  // when we receive a message
135  int message_counter = 0;
136  int message_counter_since_last_mode_change = 0;
137 
138 // private FlexFellowIOGroup _flexFellowIOGroup;
139 
140  @Override
141  public void initialize()
142  {
143  _startStopUI = new StartStopSwitchUI(this);
144  _processDataManager = new ProcessDataManager(this);
145  _lbrController = (Controller) getContext().getControllers().toArray()[0];
146  _lbr = (LBR) _lbrController.getDevices().toArray()[0];
147 
148 // if(_flexFellowPresent) _flexFellowIOGroup = new FlexFellowIOGroup(_lbrController);
149  if(_mediaFlangeIOPresent) {
150 // _mediaFlangeIOGroup = new MediaFlangeIOGroup(_lbrController);
151 // _mediaFlangeIOGroup.setLEDBlue(true);
152  }
153 
154  _friConfiguration = FRIConfiguration.createRemoteConfiguration(_lbr, _processDataManager.get_FRI_KONI_LaptopIPAddress());
155  _friConfiguration.setSendPeriodMilliSec(4);
156 
157  _friSession = new FRISession(_friConfiguration);
158 
159  _flangeAttachment = getApplicationData().createFromTemplate("FlangeAttachment");
160  _pausedApplicationRecovery = getRecovery();
161 
162  LoadData _loadData = new LoadData();
163  _loadData.setMass(_processDataManager.getEndEffectorWeight());
164  _loadData.setCenterOfMass(_processDataManager.getEndEffectorX(),
165  _processDataManager.getEndEffectorY(),
166  _processDataManager.getEndEffectorZ());
167  //_toolAttachedToLBR = new Tool("Tool", _loadData);
168  // TODO: make configurable via C++ API?
169  _toolAttachedToLBR = _flangeAttachment;
170  _toolAttachedToLBR.attachTo(_lbr.getFlange());
171 
172  _jointLimits = _lbr.getJointLimits();
173 
174  // used when setting limits in _HandGuidingMotion
175  _maxAllowedJointLimits = _jointLimits.getMaxJointPosition().get();
176  _minAllowedJointLimits = _jointLimits.getMinJointPosition().get();
177  for (int i = 0; i < _lbr.getJointCount(); i++) {
178  _maxAllowedJointLimits[i] -= 0.05;
179  _minAllowedJointLimits[i] += 0.05;
180  }
181 
182 
183  _teachControlMode = new JointImpedanceControlMode(_lbr.getJointCount())
184  .setStiffnessForAllJoints(0.1)
185  .setDampingForAllJoints(0.7);
186 
187 
188  _teachModeRunnable = new TeachMode(
189  _flangeAttachment,
190  _maxAllowedJointLimits,
191  _minAllowedJointLimits);
192  _teachModeRunnable.setLogger(getLogger());
193  _teachModeThread = new Thread(_teachModeRunnable);
194  _teachModeThread.start();
195 
196 
197 
198  _FRIModeRunnable = new FRIMode(
199  _lbr,
200  _friSession);
201  _FRIModeRunnable.setLogger(getLogger());
202  _FRIModeThread = new Thread(_FRIModeRunnable);
203  _FRIModeThread.start();
204  }
205 
206 
207  @Override
208  public void run()
209  {
210 
211  getLogger().info("GRL_Driver from github.com/ahundt/grl starting...\nUDP Connecting to: " + _processDataManager.get_ZMQ_MASTER_URI());
212 
213  UDPManager udpMan = new UDPManager(_processDataManager.get_controllingLaptopIPAddress(), _processDataManager.get_controllingLaptopJAVAPort() ,getLogger());
214 
215  // if stop is ever set to true the program stops running and exits
216  boolean stop;
217  stop = udpMan.connect();
218 
219  IMotionContainer currentMotion = null;
220 
221  boolean newConfig = false;
222 
223  // TODO: Let user set mode (teach/joint control from tablet as a backup!)
224  //this.getApplicationData().getProcessData("DefaultMode").
225 
226 
227 
228  // TODO: add a message that we send to the driver with data log strings
229  while (!stop && !_startStopUI.is_stopped()) {
230  message_counter+=1;
231  _currentKUKAiiwaState = udpMan.waitForNextMessage();
232  _previousKUKAiiwaState = udpMan.getPrevMessage();
233 
234 
235  //////////////////////////////////////////
236  // Process Arm Configuration staring here, such as Changing from FRI to SmartServo based commanding
237  //////////////////////////////////////////
238  /// TODO: Get any configuration updates here and apply them
239  if( _currentKUKAiiwaState != null && _currentKUKAiiwaState.armConfiguration() != null
240  //&& _currentKUKAiiwaState.armConfiguration().stateType() != _previousKUKAiiwaState.armControlState().stateType())
241  )
242  {
243  /// TODO: Only change configuration when it changes, not every time
244  _commandInterface = _currentKUKAiiwaState.armConfiguration().commandInterface();
245  _monitorInterface = _currentKUKAiiwaState.armConfiguration().monitorInterface();
246  }
247 
248  //////////////////////////////////////////
249  // Process Arm Control Commands staring here, such as new joint angles or switching to teach mode
250  //////////////////////////////////////////
251 
252  // Print out a notice when switching modes
253  if( message_counter == 1 || (_previousKUKAiiwaState != null && _previousKUKAiiwaState.armControlState() != null &&
254  _currentKUKAiiwaState.armControlState().stateType() != _previousKUKAiiwaState.armControlState().stateType()))
255  {
256  getLogger()
257  .info("Switching mode: "
258  + ArmState.name(_currentKUKAiiwaState.armControlState().stateType()));
259  message_counter_since_last_mode_change = 0;
260  } else {
261 
262  message_counter_since_last_mode_change++;
263  }
264 
265  if(_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.ShutdownArm){
266  ///////////////////////////////////////////////
267  // ShutdownArm
268  getLogger()
269  .info("ShutdownArm command received, stopping GRL_Driver...");
270  stop = true;
271  } else if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.TeachArm) {
272  ///////////////////////////////////////////////
273  ///////////////////////////////////////////////
274  // TeachArm teach mode
275  ///////////////////////////////////////////////
276  ///////////////////////////////////////////////
277 
278  if(message_counter!=1 && (_previousKUKAiiwaState == null || _previousKUKAiiwaState.armControlState()==null)) {
279  continue;
280  }
281  else if(message_counter==1
282  || _currentKUKAiiwaState.armControlState().stateType()!=_previousKUKAiiwaState.armControlState().stateType()
283  || (currentMotion != null && currentMotion.isFinished()) ) {
284  // Teach mode, changing from some other mode
285 
286  if (currentMotion != null) {
287  if(!currentMotion.isFinished()) {
288  currentMotion.cancel();
289  } else {
290  getLogger().info("Hand Guiding Motion has finished!");
291  }
292  }
293 
294  if(!cancelSmartServo()) continue;
295 
296  getLogger().warn("Enabling Teach Mode with gravity compensation. mode id code = " +
297  _currentKUKAiiwaState.armControlState().stateType());
298 
299 // // comment/uncomment depending on if you have a flexfellow with lights
300 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightYellow(true);
301 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightRed(false);
302 
303  // useHandGuidingMotion==true activates the KUKA supplied HandGuidingMotion
304  // Please note that the KUKA supplied HandGuidingMotion requires configuration
305  // of a button that lets you exit HandGuidingMotion mode. Some KUKA machines
306  // come with the button on the end effector flange, but others require you to
307  // attach it to the controller box.
308  //
309  // useHandGuidingMotion==true activates a simple gravity copensation
310  // mode that lets you do something similar,
311  // though it will halt when joint limtis are reached.
312  //
313  // TODO: Move to an enum of possible handguidingmotion modes and make configurable from either the pendant or C++ interface
314  boolean useHandGuidingMotion = false;
315 
316  if(useHandGuidingMotion)
317  {
318 
319  _teachModeRunnable.enable();
320 
321  getLogger().warn("Started teach thread!");
322  }
323  else
324  {
325  currentMotion = _flangeAttachment.moveAsync(positionHold(_teachControlMode, -1, TimeUnit.SECONDS));
326  }
327  }
328 
329  }
330  else if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.MoveArmTrajectory) {
331  ///////////////////////////////////////////////
332  // MoveArmTrajectory mode (sequence of joint angles)
333  ///////////////////////////////////////////////
334  getLogger().error("MoveArmTrajectory Not Yet Implemented!");
335 
336  // create an JointPosition Instance, to play with
337  JointPosition destination = new JointPosition(
338  _lbr.getJointCount());
339  // TODO: not fully implemented
340  if(!cancelSmartServo()) continue;
341  if(!cancelTeachMode()) continue;
342 
343  if (currentMotion != null) currentMotion.cancel();
344 
345 
346 
347  MoveArmTrajectory mat;
348  if(_currentKUKAiiwaState.armControlState() != null)
349  {
350  mat = (MoveArmTrajectory)_currentKUKAiiwaState.armControlState().state(new MoveArmTrajectory());
351  } else {
352  getLogger().error("Received null armControlState in servo!");
353  continue;
354  }
355 
356  for (int j = 0; j < mat.trajLength(); j++)
357  {
358 
359  JointPosition pos = new JointPosition(_lbr.getCurrentJointPosition());
360 
361  for (int k = 0; k < destination.getAxisCount(); ++k)
362  {
363  //destination.set(k, maj.traj(j).position(k));
364  pos.set(k, mat.traj(j).position(k));
365  currentMotion = _lbr.moveAsync(ptp(pos));
366  }
367 
368  }
369  } else if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.MoveArmJointServo) {
370  ///////////////////////////////////////////////
371  ///////////////////////////////////////////////
372  // MoveArmJointServo mode
373  ///////////////////////////////////////////////
374  ///////////////////////////////////////////////
375 
376  if (currentMotion != null && _commandInterface!=grl.flatbuffer.KUKAiiwaInterface.FRI) currentMotion.cancel();
377  if(!cancelTeachMode()) continue;
378 
379  // create an JointPosition Instance, to play with
380  JointPosition destination = new JointPosition(_lbr.getJointCount());
381 
382  if(_currentKUKAiiwaState.armControlState() == null) {
383  getLogger().error("Received null armControlState in servo!");
384  continue;
385  // return;
386  }
387 
388  MoveArmJointServo mas = (MoveArmJointServo)_currentKUKAiiwaState.armControlState().state(new MoveArmJointServo());
389 
390  // start up the motion if not enabled yet
391  if( _smartServoMotion == null) {
392  // make sure this is up
393  // also make sure this is running
394  destination = new JointPosition(_lbr.getCurrentJointPosition());
395  _smartServoMotion = new SmartServo(destination);
396 
397  // TODO: support more control modes & UDP interface
398  _smartServoMotionControlMode = getMotionControlMode(grl.flatbuffer.EControlMode.CART_IMP_CONTROL_MODE);
399  /*
400  *
401  * Note: The Validation itself justifies, that in this very time
402  * instance, the load parameter setting was sufficient. This does not
403  * mean by far, that the parameter setting is valid in the sequel or
404  * lifetime of this program
405  */
406  try
407  {
408  if (!ServoMotion.validateForImpedanceMode(_flangeAttachment))
409  {
410  getLogger().info("Validation of torque model failed - correct your mass property settings");
411  getLogger().info("SmartServo will be available for position controlled mode only, until validation is performed");
412  }
413  else
414  {
415  _smartServoMotion.setMode(_smartServoMotionControlMode);
416  }
417  }
418  catch (IllegalStateException e)
419  {
420  getLogger().info("Omitting validation failure for this sample\n"
421  + e.getMessage());
422  }
423 
424  // Set the motion properties to % of system abilities. For example .2 is 20% of systems abilities
425  // TODO: load these over C++ interface
426  _smartServoMotion
427  .setSpeedTimeoutAfterGoalReach(0.1)
428  .setJointAccelerationRel(_processDataManager.get_jointAccelRel())
429  .setJointVelocityRel(_processDataManager.get_jointVelRel())
430  .setMinimumTrajectoryExecutionTime(20e-3);
431 
432  // turn on a physical green light bulb attached to the robot base
433 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightGreen(true);
434  _toolAttachedToLBR.getDefaultMotionFrame().moveAsync(_smartServoMotion);
435  getLogger().info("Setting up SmartServo");
436 
437  }
438 
439  if (_smartServoRuntime == null) {
440  getLogger().info("Setting up Smart Servo runtime");
441  try {
442  // TODO: make motion control mode configurable over UDP interface
443  _smartServoRuntime = _smartServoMotion.getRuntime();
444  _smartServoRuntime.activateVelocityPlanning(true);
445  // _smartServoRuntime.changeControlModeSettings(_smartServoMotionControlMode);
446  _activeMotionControlMode = _smartServoMotionControlMode;
447  } catch (java.lang.IllegalStateException ex) {
448  getLogger().error("Could not retrieve SmartServo runtime!");
449  _smartServoRuntime = null;
450  _smartServoMotion = null;
451  getLogger().error(ex.getMessage());
452  continue;
453  //return;
454  }
455  }
456 
457  if(_commandInterface==grl.flatbuffer.KUKAiiwaInterface.FRI){
458 
459  // only start a new motion overlay if there isn't a current one actively commanding
460  /// TODO: perhaps it is possible commands won't actually be sent and that will still be valid, modify this if statement to deal with that
461  if( _friSession.getFRIChannelInformation().getFRISessionState().compareTo(FRISessionState.COMMANDING_ACTIVE) != 0
462  && _friSession.getFRIChannelInformation().getFRISessionState().compareTo(FRISessionState.COMMANDING_WAIT) != 0)
463  {
464  getLogger().info("FRI MotionOverlay starting...");
465  _FRIModeRunnable.setControlMode(_smartServoMotionControlMode);
466  _FRIModeRunnable.enable();
467  }
468 
469  if(message_counter % 100 == 0) getLogger().info("FRI MotionOverlay Quality Sample: " + _friSession.getFRIChannelInformation().getQuality().toString());
470  } else if(_smartServoRuntime != null ) {
471 
472  grl.flatbuffer.JointState jointState = mas.goal();
473  if(jointState.positionLength()!=destination.getAxisCount()){
474  if(message_counter_since_last_mode_change % 500 == 0) getLogger().error("Didn't receive correct number of joints! skipping to start of loop...\n");
475  continue;
476  //return;
477  }
478  String pos = "pos:";
479  for (int k = 0; k < destination.getAxisCount(); ++k)
480  {
481  double position = jointState.position(k);
482  destination.set(k, position);
483  pos = pos + " " + k + ": " + position;
484  }
485 
486 
487  try {
488  if(message_counter % 1000 == 0) getLogger().info("Sample of new Smart Servo Joint destination " + pos);
489  _smartServoRuntime.setDestination(destination);
490  } catch (CommandInvalidException e) {
491  getLogger().error("Could not update smart servo destination! Clearing SmartServo.");
492  _smartServoMotion = null;
493  _smartServoRuntime = null;
494  continue;
495  } catch (java.lang.IllegalStateException ex) {
496  getLogger().error("Could not update smart servo destination and missed the real exception type! Clearing SmartServo.");
497  _smartServoMotion = null;
498  _smartServoRuntime = null;
499  getLogger().error(ex.getMessage());
500  continue;
501  }
502  } else {
503  getLogger().error("Couldn't issue motion command, smartServo motion was most likely reset. retrying...");
504  }
505 
506  } else if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.StopArm) {
507 
508  _smartServoRuntime.stopMotion();
509  if (currentMotion != null) {
510  currentMotion.cancel();
511  }
512  if(!cancelTeachMode()) continue;
513 
514  //tm.setActive(false);
515  } else if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.PauseArm) {
516 
517  if (currentMotion != null) currentMotion.cancel();
518  if(!cancelTeachMode()) continue;
519  if(!cancelSmartServo()) continue;
520 
521  PositionControlMode controlMode = new PositionControlMode();
522  if(message_counter_since_last_mode_change < 2 || message_counter_since_last_mode_change % 100 == 0){
523  _lbr.move(positionHold(controlMode,10,TimeUnit.MILLISECONDS));
524  }
525 
526  } else {
527  System.out.println("Unsupported Mode! stopping");
528  stop = true;
529  }
530 
531  ///////////////////////////////////////////////////////////////////////////
532  /// Sending commands back to the C++ interface here
533  /// Reading sensor values from Java Interface and sending them thrugh UDP
534  if (_currentKUKAiiwaState.armControlState().stateType() == grl.flatbuffer.ArmState.MoveArmJointServo){
535 
536 
537  /// Note: Be aware that calls like this get data from the realtime system
538  /// and are very slow, adding about 2ms each.
539  /// @todo TODO(ahundt) Move to another thread, this may help avoid the slowdown detailed above
540  Vector force = _lbr.getExternalForceTorque(_lbr.getFlange()).getForce();
541 
542  double force_x = force.getX();
543  double force_y = force.getY();
544  double force_z = force.getZ();
545  double torque_x = 0;
546  double torque_y = 0;
547  double torque_z = 0;
548 
549  FlatBufferBuilder builder = new FlatBufferBuilder(0);
550 
551  int fb_wrench = Wrench.createWrench(builder, force_x, force_y, force_z, torque_x, torque_y, torque_z, 0, 0, 0);
552 
554  KUKAiiwaMonitorState.addCartesianWrench(builder, fb_wrench);
555  int monitorStateOffset = KUKAiiwaMonitorState.endKUKAiiwaMonitorState(builder);
556 
558  KUKAiiwaState.addMonitorState(builder, monitorStateOffset);
559  int[] statesOffset = new int[1];
560  statesOffset[0] = KUKAiiwaState.endKUKAiiwaState(builder);
561 
562  int statesVector = KUKAiiwaStates.createStatesVector(builder, statesOffset);
563 
565  KUKAiiwaStates.addStates(builder, statesVector);
566  int KUKAiiwaStatesOffset = KUKAiiwaStates.endKUKAiiwaStates(builder);
567 
568 
569  builder.finish(KUKAiiwaStatesOffset);
570  byte[] msg = builder.sizedByteArray();
571 
572  try {
573  udpMan.sendMessage(msg, msg.length);
574  } catch (IOException e) {
575  // failed to send message in GRL_Driver.java
576  }
577 
578  }
579 
580  } // end primary while loop
581 
582 
583  // done
584  udpMan.stop();
585  _teachModeRunnable.stop();
586  if (_updateConfiguration!=null && _updateConfiguration.get_FRISession() != null) {
587  _updateConfiguration.get_FRISession().close();
588  }
589 
590  getLogger()
591  .info("UDP connection closed.\nExiting...\nThanks for using the\nGRL_Driver from github.com/ahundt/grl\nGoodbye!");
592  //System.exit(1);
593  }
594 
595  /**
596  *
597  * @return true if teach mode completed successfully; false if we are waiting on a user to press a physical button
598  */
599  private boolean cancelTeachMode() {
600  if (_teachModeThread != null) {
601  //getLogger().warn("Cancelling teach mode...");
602  _canServo = _teachModeRunnable.cancel();
603 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightYellow(false);
604 
605  if(!_teachModeRunnable.isEnableEnded() &&
606  _currentKUKAiiwaState.armControlState().stateType() != grl.flatbuffer.ArmState.TeachArm){
607 
608  if(message_counter % 30 == 0) getLogger().warn("Can't Exit Teach Mode Yet,\n Did You Press The Hand Guiding Button?");
609  waitingForUserToEndTeachMode = true;
610 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightRed(true);
611  return false;
612  }
613  else if(_teachModeRunnable.isEnableEnded()
614  && _currentKUKAiiwaState.armControlState().stateType() != grl.flatbuffer.ArmState.TeachArm
615  && waitingForUserToEndTeachMode)
616  {
617  PositionControlMode controlMode = new PositionControlMode();
618  _lbr.move(positionHold(controlMode,10,TimeUnit.MILLISECONDS));
619  waitingForUserToEndTeachMode = false;
620 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightRed(false);
621  }
622  }
623  return true;
624  }
625 
626 
627 
628  /**
629  *
630  * @return true if FRI mode completed successfully; false if we are waiting on a user to press a physical button
631  */
632  private boolean cancelFRIMode() {
633  if (_FRIModeThread != null) {
634  //getLogger().warn("Cancelling teach mode...");
635  _canServo = _FRIModeRunnable.cancel();
636 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightYellow(false);
637 
638  if(!_FRIModeRunnable.isEnableEnded() &&
639  _currentKUKAiiwaState.armControlState().stateType() != grl.flatbuffer.ArmState.MoveArmJointServo){
640 
641  if(message_counter % 30 == 0) getLogger().warn("Can't Exit FRI Mode Yet, waiting...");
642  waitingForUserToEndFRIMode = true;
643 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightRed(true);
644  return false;
645  }
646  else if(_FRIModeRunnable.isEnableEnded()
647  && _currentKUKAiiwaState.armControlState().stateType() != grl.flatbuffer.ArmState.MoveArmJointServo
648  && waitingForUserToEndFRIMode)
649  {
650  PositionControlMode controlMode = new PositionControlMode();
651  _lbr.move(positionHold(controlMode,10,TimeUnit.MILLISECONDS));
652  waitingForUserToEndFRIMode = false;
653 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightRed(false);
654  }
655  }
656  return true;
657  }
658 
659  /**
660  *
661  * @return true if teach mode completed successfully; false if something went wrong
662  */
663  private boolean cancelSmartServo(){
664  if (_smartServoRuntime != null) {
665  _smartServoRuntime.stopMotion();
666  _smartServoMotion = null;
667  _smartServoRuntime = null;
668 // if(_flexFellowPresent) _flexFellowIOGroup.setSignalLightGreen(false);
669  getLogger().info("Ending smart servo!");
670  }
671  cancelFRIMode();
672  return true;
673  }
674 
675  /**
676  * Initialize the appropriate control mode based on passed parameters
677  *
678  * @param controlMode grl.flatbuffer.EControlMode
679  * @return
680  */
681  public AbstractMotionControlMode getMotionControlMode(byte controlMode)
682  {
683  AbstractMotionControlMode mcm = null;
684 
686  mcm = new PositionControlMode();
687  } else if(controlMode==grl.flatbuffer.EControlMode.CART_IMP_CONTROL_MODE){
688 
689  // TODO: make motion control mode configurable over UDP interface
690  /// @note setMaxCartesianVelocity STOPS THE ROBOT ABOVE THAT VELOCITY RATHER THAN CAPPING THE VELOCITY
691  CartesianImpedanceControlMode cicm = new CartesianImpedanceControlMode()
692  .setMaxCartesianVelocity(1000, 1000, 1000, 6.3, 6.3, 6.3)
693  .setMaxPathDeviation(1000, 1000, 1000, 5, 5, 5)
694  .setNullSpaceDamping(0.5)
695  .setNullSpaceStiffness(2)
696  .setMaxControlForce(200, 200, 200, 200, 200, 200, true);
697 
698  cicm.parametrize(CartDOF.X).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessX());
699  cicm.parametrize(CartDOF.Y).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessY());
700  cicm.parametrize(CartDOF.Z).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessZ());
701  cicm.parametrize(CartDOF.A).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessA());
702  cicm.parametrize(CartDOF.B).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessB());
703  cicm.parametrize(CartDOF.C).setStiffness(_processDataManager.get_CartesianImpedenceStiffnessC());
704 
705  cicm.parametrize(CartDOF.X).setDamping(_processDataManager.get_CartesianImpedenceDampingX());
706  cicm.parametrize(CartDOF.Y).setDamping(_processDataManager.get_CartesianImpedenceDampingY());
707  cicm.parametrize(CartDOF.Z).setDamping(_processDataManager.get_CartesianImpedenceDampingZ());
708  cicm.parametrize(CartDOF.A).setDamping(_processDataManager.get_CartesianImpedenceDampingA());
709  cicm.parametrize(CartDOF.B).setDamping(_processDataManager.get_CartesianImpedenceDampingB());
710  cicm.parametrize(CartDOF.C).setDamping(_processDataManager.get_CartesianImpedenceDampingC());
711 
712  mcm = cicm;
713  } else if(controlMode==grl.flatbuffer.EControlMode.JOINT_IMP_CONTROL_MODE){
714 
715  JointImpedanceControlMode jicm = new JointImpedanceControlMode(_lbr.getJointCount())
716  .setStiffnessForAllJoints(_processDataManager.get_JointImpedenceStiffness())
717  .setDampingForAllJoints(_processDataManager.get_JointImpedenceDamping());
718  // TODO: read relevant stiffness/damping params
719  //cicm.parametrize(CartDOF.X).setStiffness(stiffnessX);
720  //cicm.parametrize(CartDOF.Y).setStiffness(stiffnessY);
721  //cicm.parametrize(CartDOF.Z).setStiffness(stiffnessZ);
722 
723  mcm = jicm;
724  }
725  return mcm;
726  }
727 
728  boolean updateConfig(grl.flatbuffer.KUKAiiwaArmConfiguration newConfig){
729 
730  if(newConfig == null) return false;
731 
732  if(_currentKUKAiiwaState.armConfiguration().controlMode()!=_previousKUKAiiwaState.armConfiguration().controlMode())
733  {
734 
735  _smartServoRuntime.changeControlModeSettings(_activeMotionControlMode);
736  }
737 
738  _commandInterface = _currentKUKAiiwaState.armConfiguration().controlMode();
739 
740  return true;
741  }
742 
743  /**
744  * main.
745  *
746  * @param args
747  * args
748  */
749  public static void main(final String[] args)
750  {
751  final GRL_Driver app = new GRL_Driver();
752  app.runApplication();
753  }
754 
755 }
void setLogger(ITaskLogger logger)
Definition: FRIMode.java:56
void setLogger(ITaskLogger logger)
Definition: TeachMode.java:60
static void addCartesianWrench(FlatBufferBuilder builder, int CartesianWrenchOffset)
grl.flatbuffer.KUKAiiwaState getPrevMessage()
boolean cancel()
Definition: TeachMode.java:95
void setControlMode(AbstractMotionControlMode teachModeControlMode)
Definition: FRIMode.java:64
static int createStatesVector(FlatBufferBuilder builder, int[] data)
boolean sendMessage(byte[] msg, int size)
boolean cancel()
Definition: FRIMode.java:95
grl.flatbuffer.KUKAiiwaState waitForNextMessage()
static void main(final String[] args)
static void addMonitorState(FlatBufferBuilder builder, int monitorStateOffset)
void enable()
Definition: FRIMode.java:68
static int createWrench(FlatBufferBuilder builder, double force_x, double force_y, double force_z, double torque_x, double torque_y, double torque_z, double force_offset_x, double force_offset_y, double force_offset_z)
void enable()
Definition: TeachMode.java:72
static void addStates(FlatBufferBuilder builder, int statesOffset)
AbstractMotionControlMode getMotionControlMode(byte controlMode)
boolean connect()
Definition: UDPManager.java:60