From 97d1091f784da5602b08da30b3067087073a4428 Mon Sep 17 00:00:00 2001 From: Modi1987 Date: Sat, 2 Mar 2019 21:32:04 +0000 Subject: [PATCH] Simulink iiwa interface --- .../SimulinkIIWADirectServoCartesian.java | 343 +++++++++++ .../iiwa/SimulinkIIWASmartServoCartesian.java | 381 +++++++++++++ .../simulink/smartDirectServoCartesian.slx | Bin 0 -> 24688 bytes .../simulink/smartDirectServoCartesian.slxc | Bin 0 -> 5365 bytes .../SimulinkFIIWADirectServoCartesian.java | 467 +++++++++++++++ .../SimulinkFIIWASmartServoCartesian.java | 506 ++++++++++++++++ .../feedBackSmartDirectServoCartesian1.slx | Bin 0 -> 27806 bytes .../feedBackSmartDirectServoCartesian1.slxc | Bin 0 -> 5381 bytes .../simulink/freeHandGuiding_01.slx | Bin 0 -> 38734 bytes .../simulink/freeHandGuiding_01.slxc | Bin 0 -> 5355 bytes .../iiwa/SimulinkIIWA_impedanceJoints.java | 266 +++++++++ .../simulink/impedanceJoints.slx | Bin 0 -> 23833 bytes .../simulink/impedanceJoints.slxc | Bin 0 -> 5358 bytes .../iiwa/SimulinkFIIWA_impedanceJoints.java | 395 +++++++++++++ .../simulink/feedbackImpedanceJoints.slx | Bin 0 -> 28959 bytes .../simulink/feedbackImpedanceJoints.slxc | Bin 0 -> 5366 bytes .../iiwa/SimulinkIIWADirectServoJoints.java | 382 +++++++++++++ .../iiwa/SimulinkIIWASmartServoJoints.java | 413 ++++++++++++++ .../simulink/smartDirectServoJoints.slx | Bin 0 -> 23901 bytes .../simulink/smartDirectServoJoints.slxc | Bin 0 -> 5353 bytes .../iiwa/SimulinkFIIWADirectServoJoints.java | 509 +++++++++++++++++ .../iiwa/SimulinkFIIWASmartServoJoints.java | 539 ++++++++++++++++++ .../feedBackSmartDirectServoJoints.slx | Bin 0 -> 26400 bytes .../feedBackSmartDirectServoJoints.slxc | Bin 0 -> 5379 bytes README.md | 47 +- 25 files changed, 4245 insertions(+), 3 deletions(-) create mode 100644 Cartesian motion open loop/iiwa/SimulinkIIWADirectServoCartesian.java create mode 100644 Cartesian motion open loop/iiwa/SimulinkIIWASmartServoCartesian.java create mode 100644 Cartesian motion open loop/simulink/smartDirectServoCartesian.slx create mode 100644 Cartesian motion open loop/simulink/smartDirectServoCartesian.slxc create mode 100644 Cartesian motion with feedback/iiwa/SimulinkFIIWADirectServoCartesian.java create mode 100644 Cartesian motion with feedback/iiwa/SimulinkFIIWASmartServoCartesian.java create mode 100644 Cartesian motion with feedback/simulink/feedBackSmartDirectServoCartesian1.slx create mode 100644 Cartesian motion with feedback/simulink/feedBackSmartDirectServoCartesian1.slxc create mode 100644 Cartesian motion with feedback/simulink/freeHandGuiding_01.slx create mode 100644 Cartesian motion with feedback/simulink/freeHandGuiding_01.slxc create mode 100644 Impedance control open loop/iiwa/SimulinkIIWA_impedanceJoints.java create mode 100644 Impedance control open loop/simulink/impedanceJoints.slx create mode 100644 Impedance control open loop/simulink/impedanceJoints.slxc create mode 100644 Impedance control with feedback/iiwa/SimulinkFIIWA_impedanceJoints.java create mode 100644 Impedance control with feedback/simulink/feedbackImpedanceJoints.slx create mode 100644 Impedance control with feedback/simulink/feedbackImpedanceJoints.slxc create mode 100644 Joint space motion open loop/iiwa/SimulinkIIWADirectServoJoints.java create mode 100644 Joint space motion open loop/iiwa/SimulinkIIWASmartServoJoints.java create mode 100644 Joint space motion open loop/simulink/smartDirectServoJoints.slx create mode 100644 Joint space motion open loop/simulink/smartDirectServoJoints.slxc create mode 100644 Joint space motion with feedback/iiwa/SimulinkFIIWADirectServoJoints.java create mode 100644 Joint space motion with feedback/iiwa/SimulinkFIIWASmartServoJoints.java create mode 100644 Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slx create mode 100644 Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slxc diff --git a/Cartesian motion open loop/iiwa/SimulinkIIWADirectServoCartesian.java b/Cartesian motion open loop/iiwa/SimulinkIIWADirectServoCartesian.java new file mode 100644 index 0000000..405d86b --- /dev/null +++ b/Cartesian motion open loop/iiwa/SimulinkIIWADirectServoCartesian.java @@ -0,0 +1,343 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; +import java.nio.ByteBuffer; + + +/* + * SimulinkIIWA interface, soft real-time control in Cartesian position mode + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (smartDirectServoCartesian.slx) + * + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 only, modifications in Simulink schematic are required for 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class to a new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the Direct/SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (smartDirectServoCartesian.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + + +public class SimulinkIIWADirectServoCartesian extends RoboticsAPIApplication +{ + private LBR _lbr; + + + public static double EEfServoPos[]; + + public static boolean loopFlag; + + public static double jDispMax[]; + public static double updateCycleJointPos[]; + private UDPServer udpServer; + int _port; + + ServerSocket ss; + Socket soc; + + + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + EEfServoPos=new double[6]; + for(int i=0;i<6;i++) + { + EEfServoPos[i]=0; + } + loopFlag=true; + } + + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., Math.PI / 180 * 30.,0.,-Math.PI / 180 * 80.,0.,Math.PI / 180 * 70., 0.).setJointVelocityRel(0.15)); + /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + directServoStartCartezian(); + + } + + + private void directServoStartCartezian() { + + boolean doDebugPrints = false; + + DirectServo aDirectServoMotion = new DirectServo( + _lbr.getCurrentJointPosition()); + + aDirectServoMotion.setMinimumTrajectoryExecutionTime(40e-3); + + getLogger().info("Starting DirectServo motion in position control mode"); + _lbr.moveAsync(aDirectServoMotion); + + getLogger().info("Get the runtime of the DirectServo motion"); + IDirectServoRuntime theDirectServoRuntime = aDirectServoMotion + .getRuntime(); + + Frame aFrame = theDirectServoRuntime.getCurrentCartesianDestination(_lbr.getFlange()); + Frame destFrame = aFrame.copyWithRedundancy(); + // Initiate the initial position + EEfServoPos[0]=aFrame.getX(); + EEfServoPos[1]=aFrame.getY(); + EEfServoPos[2]=aFrame.getZ(); + EEfServoPos[3]=aFrame.getAlphaRad(); + EEfServoPos[4]=aFrame.getBetaRad(); + EEfServoPos[5]=aFrame.getGammaRad(); + + try + { + // do a cyclic loop + // Do some timing... + // in nanosec + + while(loopFlag==true) + { + + // /////////////////////////////////////////////////////// + // Insert your code here + // e.g Visual Servoing or the like + // Synchronize with the realtime system + theDirectServoRuntime.updateWithRealtimeSystem(); + Frame msrPose = theDirectServoRuntime + .getCurrentCartesianDestination(_lbr.getFlange()); + + if (doDebugPrints) + { + getLogger().info("Current cartesian goal " + aFrame); + getLogger().info("Current joint destination " + + theDirectServoRuntime.getCurrentJointDestination()); + } + + Thread.sleep(1); + + for(int kk=0;kk<6;kk++) + { + EEfServoPos[kk]=udpServer.EEFpos[kk]; + } + // update Cartesian positions + destFrame.setX(EEfServoPos[0]); + destFrame.setY(EEfServoPos[1]); + destFrame.setZ(EEfServoPos[2]); + destFrame.setAlphaRad(EEfServoPos[3]); + destFrame.setBetaRad(EEfServoPos[4]); + destFrame.setGammaRad(EEfServoPos[5]); + + if (doDebugPrints) + { + getLogger().info("New cartesian goal " + destFrame); + getLogger().info("LBR position " + + _lbr.getCurrentCartesianPosition(_lbr + .getFlange())); + getLogger().info("Measured cartesian pose from runtime " + + msrPose); + } + + theDirectServoRuntime.setDestination(destFrame); + + } + } + catch (Exception e) + { + getLogger().info(e.getLocalizedMessage()); + e.printStackTrace(); + //Print statistics and parameters of the motion + getLogger().info("Simple Cartesian Test \n" + theDirectServoRuntime.toString()); + + getLogger().info("Stop the DirectServo motion"); + + } + theDirectServoRuntime.stopMotion(); + getLogger().info("Stop the DirectServo motion for the stop instruction was sent"); + + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkIIWADirectServoCartesian app = new SimulinkIIWADirectServoCartesian(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] EEFpos={575.87,0.05,397.56,Math.PI,0,Math.PI}; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=6; + int packetCounter=0; + + byte[] buffer=new byte[8*7]; + UDPServer(int port) + { + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int index=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + EEFpos[index]=bytesToDouble(daB); + index=index+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkIIWADirectServoCartesian.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Cartesian motion open loop/iiwa/SimulinkIIWASmartServoCartesian.java b/Cartesian motion open loop/iiwa/SimulinkIIWASmartServoCartesian.java new file mode 100644 index 0000000..7e0ffc6 --- /dev/null +++ b/Cartesian motion open loop/iiwa/SimulinkIIWASmartServoCartesian.java @@ -0,0 +1,381 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.common.ThreadUtil; +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.SmartServo; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; +import com.kuka.roboticsAPI.geometricModel.LoadData; +import com.kuka.roboticsAPI.geometricModel.ObjectFrame; +import com.kuka.roboticsAPI.geometricModel.Tool; +import com.kuka.roboticsAPI.geometricModel.math.XyzAbcTransformation; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; +import java.nio.ByteBuffer; + +/* + * SimulinkIIWA interface, soft real-time control in Cartesian position mode + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (smartDirectServoCartesian.slx) + * + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800, modifications are required for the Simulink schematics for 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class to a new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the Direct/SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * * TRANSLATION_OF_TOOL: translation of tool center point with respect to flange frame. + * * massOfTool: mass of the tool + * * toolsCOMCoordiantes: coordinates of center of mass of tool with regards to the frame of the flange. + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (smartDirectServoCartesian.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + +public class SimulinkIIWASmartServoCartesian extends RoboticsAPIApplication +{ + private LBR _lbr; + + + public static double EEfServoPos[]; + + public static boolean loopFlag; + + + public static double updateCycleJointPos[]; + private UDPServer udpServer; + // Tool Data + private Tool _toolAttachedToLBR; + private LoadData _loadData; + private static final String TOOL_FRAME = "toolFrame"; + private static final double[] TRANSLATION_OF_TOOL = { 0, 0, 0 }; + private static final double MASS = 0.4; + private static final double[] CENTER_OF_MASS_IN_MILLIMETER = { 0, 0, 75 }; + + private static final int MILLI_SLEEP_TO_EMULATE_COMPUTATIONAL_EFFORT = 1; + + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + EEfServoPos=new double[6]; + for(int i=0;i<6;i++) + { + EEfServoPos[i]=0; + } + loopFlag=true; + addLoadData(); + } + + private void addLoadData() + { + // Create a Tool by Hand this is the tool we want to move with some mass + // properties and a TCP-Z-offset of 100. + _loadData = new LoadData(); + _loadData.setMass(MASS); + _loadData.setCenterOfMass( + CENTER_OF_MASS_IN_MILLIMETER[0], CENTER_OF_MASS_IN_MILLIMETER[1], + CENTER_OF_MASS_IN_MILLIMETER[2]); + _toolAttachedToLBR = new Tool("Tool", _loadData); + + XyzAbcTransformation trans = XyzAbcTransformation.ofTranslation( + TRANSLATION_OF_TOOL[0], TRANSLATION_OF_TOOL[1], + TRANSLATION_OF_TOOL[2]); + ObjectFrame aTransformation = _toolAttachedToLBR.addChildFrame(TOOL_FRAME + + "(TCP)", trans); + _toolAttachedToLBR.setDefaultMotionFrame(aTransformation); + // Attach tool to the robot + _toolAttachedToLBR.attachTo(_lbr.getFlange()); + } + + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., Math.PI / 180 * 30.,0.,-Math.PI / 180 * 80.,0.,Math.PI / 180 * 70., 0.).setJointVelocityRel(0.15)); + /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + smartServoStartCartezian(); + + } + + + private void smartServoStartCartezian() { + + boolean doDebugPrints = false; + + SmartServo aSmartServoMotion = new SmartServo( + _lbr.getCurrentJointPosition()); + + aSmartServoMotion.useTrace(true); + + aSmartServoMotion.setMinimumTrajectoryExecutionTime(5e-3); + + getLogger().info("Starting SmartServo motion in position control mode"); + _toolAttachedToLBR.moveAsync(aSmartServoMotion); + + getLogger().info("Get the runtime of the SmartServo motion"); + ISmartServoRuntime theServoRuntime = aSmartServoMotion + .getRuntime(); + + Frame aFrame = theServoRuntime.getCurrentCartesianDestination(_toolAttachedToLBR.getDefaultMotionFrame()); + Frame destFrame = aFrame.copyWithRedundancy(); + // Initiate the initial position + EEfServoPos[0]=aFrame.getX(); + EEfServoPos[1]=aFrame.getY(); + EEfServoPos[2]=aFrame.getZ(); + EEfServoPos[3]=aFrame.getAlphaRad(); + EEfServoPos[4]=aFrame.getBetaRad(); + EEfServoPos[5]=aFrame.getGammaRad(); + + + try + { + // do a cyclic loop + // Do some timing... + // in nanosec + while(loopFlag) + { + // Insert your code here + // e.g Visual Servoing or the like + + // Synchronize with the realtime system + theServoRuntime.updateWithRealtimeSystem(); + + // Get the measured position + Frame msrPose = theServoRuntime + .getCurrentCartesianDestination(_lbr.getFlange()); + + if (doDebugPrints) + { + getLogger().info("Current cartesian goal " + aFrame); + getLogger().info("Current joint destination " + + theServoRuntime.getCurrentJointDestination()); + } + + // Do some Computation + // emulate some computational effort - or waiting for external + // stuff + ThreadUtil.milliSleep(MILLI_SLEEP_TO_EMULATE_COMPUTATIONAL_EFFORT); + + // compute a new commanded position + for(int kk=0;kk<6;kk++) + { + EEfServoPos[kk]=udpServer.EEFpos[kk]; + } + // update Cartesian positions + destFrame.setX(EEfServoPos[0]); + destFrame.setY(EEfServoPos[1]); + destFrame.setZ(EEfServoPos[2]); + destFrame.setAlphaRad(EEfServoPos[3]); + destFrame.setBetaRad(EEfServoPos[4]); + destFrame.setGammaRad(EEfServoPos[5]); + + if (doDebugPrints) + { + getLogger().info("New cartesian goal " + destFrame); + getLogger().info("LBR position " + + _lbr.getCurrentCartesianPosition(_lbr + .getFlange())); + getLogger().info("Measured cartesian pose from runtime " + + msrPose); + } + + theServoRuntime.setDestination(destFrame); + } + } + catch (Exception e) + { + getLogger().error(e.toString()); + e.printStackTrace(); + } + + //Print statistics and parameters of the motion + getLogger().info("Simple cartesian test " + theServoRuntime.toString()); + + getLogger().info("Stop the SmartServo motion"); + theServoRuntime.stopMotion(); + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkIIWASmartServoCartesian app = new SimulinkIIWASmartServoCartesian(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] EEFpos={575.87,0.05,397.56,Math.PI,0,Math.PI}; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=6; + int packetCounter=0; + + byte[] buffer=new byte[8*7]; + UDPServer(int port) + { + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int index=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + EEFpos[index]=bytesToDouble(daB); + index=index+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkIIWASmartServoCartesian.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Cartesian motion open loop/simulink/smartDirectServoCartesian.slx b/Cartesian motion open loop/simulink/smartDirectServoCartesian.slx new file mode 100644 index 0000000000000000000000000000000000000000..6cffc020f19330adf303e0f65b41b18c8105e7a1 GIT binary patch literal 24688 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 fjllm5oRV8%8Kvsi1gFHsK}yR0K2DP<4YitKx~ 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 z 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 O{1%1*07T9H`1N0l(iHaq literal 0 HcmV?d00001 diff --git a/Cartesian motion with feedback/simulink/feedBackSmartDirectServoCartesian1.slxc b/Cartesian motion with feedback/simulink/feedBackSmartDirectServoCartesian1.slxc new file mode 100644 index 0000000000000000000000000000000000000000..b7eba1e48a22d1cfaa92e90995b0fb106354a2ad GIT binary patch literal 5381 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 z zVKOO^dqBn=S(2Z$mdG^vq>(b!!xcJIH-7)_gezl8*XtosOu8iAPJ~+!dwX>QV%sj;{$>(5!*Ey=v=kL!`ytxc zr%8oe){o)#7F_oEo{dtX&dETtJ=l@phT6r5fD+={#4K5ycAszu)QP^%DL zpd;=t)4xpECiRV?LfkwjJ%YI^Z;!f+X=7&_B=m>O1Z?}}UiSCS6QFx%Uuq)huop1< z0i+PfX<+uZYgGL-gC(dS!4I?4b@kZ+s|18_D{a{OA-;m?{YiXGl0rJ7)!M75>SkDK z{!Ff!D|KbhT`CvNw9=-&kYUx{kTkk>GQ&58s>))Hq2%(LF?utsBsQnW6Y`VaR%AyZ{(()PVyC{NFU0SrU16|=o9$ga?1EAIHL zFIS%0?uwuINpFHkfIv*Tx!3~qaax{Q4c`W|E|1vGf?nqusU~@{OT|04PnPMNSYrm? z>^kKP9^Yh7j7<`ng(NTpA+W67p3n9w?3#^i4eA5&iST zb9_)u!8(VM!& z<82wsMJ8FSTc1`@)4dUojuUcWV4VscduiVbhgx0Auk$ML%MZcu_`9zSSe2QqEmq~Q zxGM$Yt#q?O&CxA#hu~7>=S2Q`tbrISF9@o*qjdN?Ydq-5NhqDYUjW#Q1+X9I@3#9b zsQzI*WJr}Q(6#*!z*$!CusnTmB%`?MPrEfpy*5j@{@JMR=T2tvsx`r@0Tr5?&dadu zQk}?{kJW!pRne@;C{i=D00+h0MLJGsI=)q7a6D~JJw#B?w(~lL5wN7IwzP13ev>^Y zk@wsL`sDk!oZZ8*!4l>!J}!3%g|pxE6OX+>#^yHqw%!cuUq+Po_BHTcMoki4tE^-uLys4?28eP--x}%Y#e{MsxrIp#xMThiughnPBeGM9=`i zKp_M|4g7cS%f=1Tz8M%3h7Cb>pYBs2`d4J%zqCAJ_4^0farj9wfIr) zV2}pKv$8s1m=Z9W?(!cXz?|$;7}UaGtY6n%YhJ70&)s z)&s_Z^Nk&B8IVMy z1F(G}ZZH5G!|ecK9_)$ezyrbI$Id{8;9Y9`OE3Z^f)~XdVn@ht#O}yZhiU>83=}6 literal 0 HcmV?d00001 diff --git a/Cartesian motion with feedback/simulink/freeHandGuiding_01.slxc b/Cartesian motion with feedback/simulink/freeHandGuiding_01.slxc new file mode 100644 index 0000000000000000000000000000000000000000..68536608ac836f0cfbbe5af880d4a722a7d7dae0 GIT binary patch literal 5355 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 literal 0 HcmV?d00001 diff --git a/Impedance control open loop/iiwa/SimulinkIIWA_impedanceJoints.java b/Impedance control open loop/iiwa/SimulinkIIWA_impedanceJoints.java new file mode 100644 index 0000000..63bf16b --- /dev/null +++ b/Impedance control open loop/iiwa/SimulinkIIWA_impedanceJoints.java @@ -0,0 +1,266 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.common.StatisticTimer; +import com.kuka.common.ThreadUtil; +import com.kuka.common.StatisticTimer.OneTimeStep; +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.SmartServo; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; +import com.kuka.roboticsAPI.geometricModel.LoadData; +import com.kuka.roboticsAPI.geometricModel.ObjectFrame; +import com.kuka.roboticsAPI.geometricModel.Tool; +import com.kuka.roboticsAPI.geometricModel.math.XyzAbcTransformation; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; +import java.nio.ByteBuffer; + +import lbrExampleApplications.SimulinkIIWADirectServoJoints.UDPServer; + + +/* + * SimulinkIIWA interface, soft real-time control with impedence + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (impedanceJoints.slx) + * + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 or 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class and the class (SmartServoWithImpedenceSimulinkIIWAinterface.java) + * to new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your tool and stiffness preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * * TRANSLATION_OF_TOOL: translation of tool center point with respect to flange frame. + * * massOfTool: mass of the tool + * * toolsCOMCoordiantes: coordinates of center of mass of tool with regards to the frame of the flange. + * * cStiffness: Cartesian stiffness + * * rStiffness: rotational stiffness + * * nStiffness: null space stiffness + * + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (impedanceJoints.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + +public class SimulinkIIWA_impedanceJoints extends RoboticsAPIApplication +{ + private LBR _lbr; + private Controller kuka_Sunrise_Cabinet_1; + private int _count = 0; + + private int _steps = 0; + + private UDPServer udpServer; + + // Tool data + private static double[] TRANSLATION_OF_TOOL = { 0, 0, 100 }; + private static double massOfTool = 1.1; + private static double[] toolsCOMCoordiantes = { 0, 0, 45 }; + + // stiffness data + private static double cStiffness=450; // cartesian stiffness + private static double rStiffness=40; // rotational stiffness + private static double nStiffness=20; // null space stiffness + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + kuka_Sunrise_Cabinet_1=getController("KUKA_Sunrise_Cabinet_1"); + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoMotionFlag=true; + } + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., Math.PI / 180 * 30.,0.,-Math.PI / 180 * 80.,0.,Math.PI / 180 * 70., 0.).setJointVelocityRel(0.15)); /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + try { + SmartServoWithImpedenceSimulinkIIWAinterface.startRealTimeWithImpedence(_lbr, kuka_Sunrise_Cabinet_1, massOfTool, + toolsCOMCoordiantes, cStiffness, + rStiffness, nStiffness); + } catch (Exception e) { + // TODO Bloco catch gerado automaticamente + e.printStackTrace(); + } + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkIIWA_impedanceJoints app = new SimulinkIIWA_impedanceJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoJpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoMotionFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Impedance control open loop/simulink/impedanceJoints.slx b/Impedance control open loop/simulink/impedanceJoints.slx new file mode 100644 index 0000000000000000000000000000000000000000..b04c8d55030014620334aeb12da32b61dac7499a GIT binary patch literal 23833 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 literal 0 HcmV?d00001 diff --git a/Impedance control with feedback/iiwa/SimulinkFIIWA_impedanceJoints.java b/Impedance control with feedback/iiwa/SimulinkFIIWA_impedanceJoints.java new file mode 100644 index 0000000..f0b4fc8 --- /dev/null +++ b/Impedance control with feedback/iiwa/SimulinkFIIWA_impedanceJoints.java @@ -0,0 +1,395 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.common.StatisticTimer; +import com.kuka.common.ThreadUtil; +import com.kuka.common.StatisticTimer.OneTimeStep; +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.SmartServo; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; +import com.kuka.roboticsAPI.geometricModel.LoadData; +import com.kuka.roboticsAPI.geometricModel.ObjectFrame; +import com.kuka.roboticsAPI.geometricModel.Tool; +import com.kuka.roboticsAPI.geometricModel.World; +import com.kuka.roboticsAPI.geometricModel.math.XyzAbcTransformation; +import com.kuka.roboticsAPI.sensorModel.ForceSensorData; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import lbrExampleApplications.SimulinkFIIWADirectServoCartesian.UDPPublisher; +import lbrExampleApplications.SimulinkIIWADirectServoJoints.UDPServer; + +/* + * SimulinkIIWA interface, soft real-time control with impedence + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (feedbackImpedanceJoints.slx) + * + * Also this script returns back a feedback about the (1)actual joints positions, + * (2)the external torques and (3)the measured torques of all the joints to Simulink. + * (4) EEF force moment. + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 or 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class and the class (SmartServoWithImpedenceSimulinkIIWAinterface.java) + * to new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your tool and stiffness preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * * TRANSLATION_OF_TOOL: translation of tool center point with respect to flange frame. + * * massOfTool: mass of the tool + * * toolsCOMCoordiantes: coordinates of center of mass of tool with regards to the frame of the flange. + * * cStiffness: Cartesian stiffness + * * rStiffness: rotational stiffness + * * nStiffness: null space stiffness + * + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (feedbackImpedanceJoints.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + +public class SimulinkFIIWA_impedanceJoints extends RoboticsAPIApplication +{ + + private static String externa_PC_IP="172.31.69.55"; + private LBR _lbr; + private Controller kuka_Sunrise_Cabinet_1; + private int _count = 0; + + private int _steps = 0; + + private UDPServer udpServer; + + // Tool data + private static double[] TRANSLATION_OF_TOOL = { 0, 0, 100 }; + private static double massOfTool = 1.1; + private static double[] toolsCOMCoordiantes = { 0, 0, 45 }; + + // stiffness data + private static double cStiffness=450; // cartesian stiffness + private static double rStiffness=40; // rotational stiffness + private static double nStiffness=20; // null space stiffness + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + kuka_Sunrise_Cabinet_1=getController("KUKA_Sunrise_Cabinet_1"); + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoMotionFlag=true; + } + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., Math.PI / 180 * 30.,0.,-Math.PI / 180 * 80.,0.,Math.PI / 180 * 70., 0.).setJointVelocityRel(0.15)); /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + new UDPPublisher(externa_PC_IP); + try { + SmartServoWithImpedenceSimulinkIIWAinterface.startRealTimeWithImpedence(_lbr, kuka_Sunrise_Cabinet_1, massOfTool, + toolsCOMCoordiantes, cStiffness, + rStiffness, nStiffness); + } catch (Exception e) { + // TODO Bloco catch gerado automaticamente + e.printStackTrace(); + } + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkFIIWA_impedanceJoints app = new SimulinkFIIWA_impedanceJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 10 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoJpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SmartServoWithImpedenceSimulinkIIWAinterface.smartServoMotionFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + + public class UDPPublisher implements Runnable{ + + String ip; + UDPPublisher(String ip) + { + this.ip=ip; + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + } + public void run() + { + broadcastData(); + } + private void broadcastData() { + // TODO Auto-generated method stub + String message="Publishing robot state using UDP at port 30008 to destination: "+ ip; + System.out.println(message); + message="Streamed message: 7 actual joint angles, 7 measured torques, 7 external torques,"; + System.out.println(message); + message="State streaming frequency is approximatly at 25HZ"; + System.out.println(message); + int port=30008; + InetAddress host; + int numOfDoubles=7+7+7+6;// 7 actual joint angles, 7 measured torques, 7 external torques, 7 force at flange + double[] doubleVals=new double[numOfDoubles]; + + byte[] buffer= new byte[8*numOfDoubles]; + + try { + host = InetAddress.getByName(ip); + DatagramSocket soc=new DatagramSocket(); + while(SmartServoWithImpedenceSimulinkIIWAinterface.smartServoMotionFlag) + { + // Feedback of actual joints positions + JointPosition jpos=_lbr.getCurrentJointPosition(); + int valsCounter=0; + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=jpos.get(i); + valsCounter=valsCounter+1; + } + // Feedback of measured torques + double[] m_tor=_lbr.getMeasuredTorque().getTorqueValues(); + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=m_tor[i]; + valsCounter=valsCounter+1; + } + // Feedback of external torques + double[] ex_tor=_lbr.getExternalTorque().getTorqueValues(); + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=ex_tor[i]; + valsCounter=valsCounter+1; + } + // Feedback of forces at flange + ForceSensorData f_at_flange=_lbr.getExternalForceTorque(_lbr.getFlange(),World.Current.getRootFrame()); + doubleVals[valsCounter]=f_at_flange.getForce().getX(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getForce().getY(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getForce().getZ(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getX(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getY(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getZ(); + valsCounter=valsCounter+1; + + int count=0; + for(int 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

CF@M?SFxwkD6ceW|yXso{_m&4buQ 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 S2nhM@_bWIM(17_L|NR$s6@VT9 literal 0 HcmV?d00001 diff --git a/Impedance control with feedback/simulink/feedbackImpedanceJoints.slxc b/Impedance control with feedback/simulink/feedbackImpedanceJoints.slxc new file mode 100644 index 0000000000000000000000000000000000000000..904de2a780bfcac5116cb17eff2c8f2f0795c083 GIT binary patch literal 5366 zcmc&&XIN9&7EM5UN17BBL5czi0UZIQNilQ+0#c0-YA}$36boIj4M+{WDS}FqNRi%D zgg6EPL69n_fHW29@1pY1j5BZiG2gp|nA38;o@h_gC#M^r zoK^F@(bE#_F!6X{u~7A}{NtT8+|}mEPPEeGqwtK^(-Y!>OLO%Ua@)0T73>PpeIgVU zH%c^4Q5EBJM(*6(LzbNAO!0TR<3EQa*W4D)@{ixUUqrL~;o6?d^RTd9U#pK5>gg+u zoD;qVd(w-BcH_jCKn-%~eL}d;xjp-G^l;G-8i5ZO7mimUcMF zx7N&TgnL?a*80m91gA*BOwEsnPhMl7)O3m1yv;g0falux?93~HGdEUg4>Zs(#>B(B z4nE6=nEW6?M$;#R2(0qs;UnIW(~Gknqp?=)q61ebw7fwYnkj9%;u9~2axnR?0T8Op#7 zO&>kIhhUU8JU(N1#~cbnKov6Ht|$>u6I#6u z+*GB`N^?h@b@(1gUW{j+)@>nWC8sH6W+iKKIJjxlyhs(C@tLj*K^4@PtZ+U6&+U_&tH_4ZxIc_*<@Rom^=yMyTf9qIrb3csKp zuyHn;*1t%DC-^H3SH95@;>rn%oTn`gFglMoW#oI_)W=)n6m}o2^wOU)zWyO(a<1JN zu3eG_{+2K3TRV1W%P|iEa+Re6fwlwr+5npzk2;NaF!%F9;p{fLFDcg0m`0v6e7*Ii zWdom*K$eU|mbiVal>gqCelEdEPX!Uxl?8I8p1P^&Y?sjhaXfVj|G?!oMS>;Awd%=p z(_REqWgmZwA&j6VsHn0plC=OdA>#awDO->1-~Y_4F7a5&WnvQS;`Y0as?FS|-q9*6 z`F${_c@i(7tgafu^v>rt;SO$EK;*ZI{7nCTmb0N1uX7w8-lh%wrVBo%uu82Sgi4CsI##df)9X=TQ#~!UV_p5qxmYR10 z`0r8zl6u}3E%w^&>vT}`cGpBloMhRZ>y2qBn`*u2oU`9DAgYw3${kWJRAC3BTZ>M3 z8Yvzy=oy4JI=>^@eUvkzFf%r*H$tRZpSZKjfO9mJcxX@w+2`qKGp|6K-iLY5lpHh~ z`(ko1{*ehNq#(4B^uDYebLwJ%$&=R?u-!4F+8{z}P~k31gChB*WMlhd4r+^RBZOm@ z^LG*#2m|Pegj&1l9bfz5reZpZ)-1(enj++)t+409qyp|x$zf3lIfwm*?HdXJn^(R9v2E?SX^HqGXkG}H9 zKIhC`P>$nSW|<|4NBTGxmf95f%$X7Uuk;8BjooM% zm}3KRL%*x@cMdORf41c<%sCHURP-U~M(tf9_vcmdeh&NN_)VOl!ic2uxX$Pe9{2m! zXMGR7&Q_j~uxYVj=e%Pal^w<-Gjlf0wZR6<6wT{;mcPRyVq&G?R=v3;x|yl0uEN&J z{J8E)_{5-1K^%Vn$x^V_M5!`KxbW>XuUa@i0i$CnoENz^u(NNPd@i$7%gM1+1**x= zKU+w+q=KUp_8C9((#g4X#koXg6>@sDnW}p|F}*%o!XC`(-A&CeI$M z&Z%8kLbT_TWt9(%l;{e71D1d?d;4^^$z+tBVY!>L+`J4a?5h<{j?}t1xZlb}NnpdKZG17{?m&w?%)Cbg9|$jNnRi1XJ931a$jcB6AX61`2j*@nsoaV|1doN%-V( z%p>pq8dZ0NTFS()1DRz3^((lUp(hfDM}6s@-;I2Ps3-1?P)_ZIMdr-vJ!&~G=zDtT z5MKP5tAWvn-3?JaRz_~?HQ1ymM1)VHEm=f_v@R&T*rfC!yU?xDP)Y;SQm}wIaPFK^ z(e?MqSKT=t518vEvx)9IL^~!@CL2mOo?SL_xQ-j{w3t?OlVc$^<>@&~Gg`Wg0&#tr zV-h}6i3O!7gbN>xD0y5??szflDr`YuEz|f7C(V6mf1)3~cICvj?UYyptLzg@dyu=e z-Eh(*xxv;e&mY&9q=^W68O<&Wte2@CSm#sBm4WMUsbjhL6n$R=@^?8$qtZUih zBiQ!PJF$osGvhY7%FR=&YZ0=NnI)B~JJHVZs^wn1M4uoVX4=7wKuEEPJB8_^xLw?;)Klo@CL~MWwb_nA zt3NtV#Hk)p{rrB&AkuuuHYY_oqq`c+?F{BH|F z8Jk%4V6pkchgBldFtt^3yUNYJXZ8l#U`kvDsND02<2EkQB2B+Q>%(}{0(*|aU9%qr zUwTAEUO%0+fIlY^xbE}xbIb3!55gqVEl9Z(C+zcu5!y0t_A(#R;Rq5qRrEeiae!Ue zsii7I$B!ad#&fv?xqhppXYD@!j)wj=gOVesoI4%7Zl`Fwp@$l@b5>L*B^x**d@Wwq z@Y{}yu5m0N`E~a)kF=0q%*_%rr9^mn`%B^`7Tf)xuL5u%h3^Up6VIWiB8J`xUL9?J zWY4tYW{}0>B-PHaS;a|n4Dn-2xZw)j8KDH3;dJ}Y;{gNfG(XC%Gw0{S1IP^lERql) zw zE|$H4KFbS~UZ0N1vDuMxHIjA781_nShrz0M20tt5t1lb{u`_KDXCj~gZLB^2buJDC>2|WWrtlB!ujejc=bAjK6Dc0 zu$MI-Sa7Qqtnj^{^J?e&^oO|;t*j1v!3m2wW0W99lWeI$HU8w7?#?MYQZq`YM>(?_ z9)EoDl3A<5r?eQgWy#EI{gcntuG~90>E&K?R?tVwh zfY6Pm`d>0V&-|HAR8;+j(bT%oJXbC6rTIwyqMk4p%@WwgMf=VRk0&17a|@qMj>7|9 z+O;R|xT{(d%rEBb6K!4Lc@VL?=Y^7g>D3b_G8ys}58cl@q zUzEw`@ZP_SplC?nKSDn!q5d{Ek>NC&bzhLkV32!R&->>|2|6#2(dG4xhtebF$eMX~ zpC9XQxM=6=uiH3%GSk_Ol#^hQI~k>{mM)r6u?iiY-&IO^n>0SOd}(LUGh2_LBd(;H zuGOd8+k}3kApL4}ZX%F61-K>tjsk68VD!U%Gu?LA>e+*#oOBm%^gNK2;yS=%ga&hX}Hzx!!oe?)5hCe?DS0JsWj~{z4 z1imaZ68Q8XB>!-$fdp(o^1)%q^Ca2j!t52`L;(Z);;%m_011Kst-oFW z!~%gr0O0Qsf6*=fU7QVPyLHI}8UE8aKl8bN7iq)fZCyjZ5a}lll{yf$o7@T%Mf=ZF z`iZxs4n*zKwgROChvYxy?mO4E8DMkFrZz?!0lt>i?|@bMiA|ygpq|sW05lkWnA$gA z-26gDJqB*QD8%$XhC*s6>UnDmYIPIpr_W4;YqEAP^@g6(y7Y!7jG3UmA F{{a^8HcS8j literal 0 HcmV?d00001 diff --git a/Joint space motion open loop/iiwa/SimulinkIIWADirectServoJoints.java b/Joint space motion open loop/iiwa/SimulinkIIWADirectServoJoints.java new file mode 100644 index 0000000..bf79c46 --- /dev/null +++ b/Joint space motion open loop/iiwa/SimulinkIIWADirectServoJoints.java @@ -0,0 +1,382 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; +import java.nio.ByteBuffer; + +/* + * SimulinkIIWA interface, soft real-time control in joints position mode + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (smartDirectServoJoints.slx) + * + * Also this script returns back a feedback about the (1)actual joints positions, + * (2)the external torques and (3)the measured torques of all the joints to Simulink. + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 or 14R820 + * 2- External PC + * 3- A netwrok between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class to a new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the Direct/SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your tool and stiffness preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (smartDirectServoJoints.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + +public class SimulinkIIWADirectServoJoints extends RoboticsAPIApplication +{ + private LBR _lbr; + + + public static double jpos[]; + + public static boolean loopFlag; + + public static double jDispMax[]; + public static double updateCycleJointPos[]; + private UDPServer udpServer; + int _port; + + ServerSocket ss; + Socket soc; + + + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + jpos=new double[7]; + jDispMax=new double[7]; + updateCycleJointPos=new double[7]; + for(int i=0;i<7;i++) + { + jpos[i]=0; + jDispMax[i]=0; + updateCycleJointPos[i]=0; + } + loopFlag=true; + _port=30003; + } + + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., 0.,0.,0.,0.,0., 0.).setJointVelocityRel(0.15)); + /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + public void moveToSomePosition() + { + _lbr.move( + ptp(0., Math.PI / 180 * 20., 0., -Math.PI / 180 * 60., 0., + Math.PI / 180 * 90., 0.)); + } + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + + startDirectServo(); + } + + + private void startDirectServo() + { + boolean doDebugPrints = false; + + JointPosition initialPosition = new JointPosition( + _lbr.getCurrentJointPosition()); + + + for(int i=0;i<7;i++) + { + jpos[i]=initialPosition.get(i); + } + DirectServo aDirectServoMotion = new DirectServo(initialPosition); + + aDirectServoMotion.setMinimumTrajectoryExecutionTime(40e-3); + + getLogger().info("Starting DirectServo motion in position control mode"); + _lbr.moveAsync(aDirectServoMotion); + + getLogger().info("Get the runtime of the DirectServo motion"); + IDirectServoRuntime theDirectServoRuntime = aDirectServoMotion + .getRuntime(); + + JointPosition destination = new JointPosition( + _lbr.getJointCount()); + double disp; + double temp; + double absDisp; + + try + { + // do a cyclic loop + // Do some timing... + // in nanosec + + while(loopFlag==true) + { + + // /////////////////////////////////////////////////////// + // Insert your code here + // e.g Visual Servoing or the like + // Synchronize with the realtime system + //theDirectServoRuntime.updateWithRealtimeSystem(); + + if (doDebugPrints) + { + getLogger().info("Current fifth joint position " + jpos[5]); + getLogger().info("Current joint destination " + + theDirectServoRuntime.getCurrentJointDestination()); + } + + + Thread.sleep(1); + + JointPosition currentPos = new JointPosition( + _lbr.getCurrentJointPosition()); + + + + for (int k = 0; k < destination.getAxisCount(); ++k) + { + + jpos[k]=udpServer.jpos[k]; + double dj=jpos[k]-currentPos.get(k); + disp= getTheDisplacment( dj); + temp=currentPos.get(k)+disp; + absDisp=Math.abs(disp); + if(absDisp>jDispMax[k]) + { + jDispMax[k]=absDisp; + } + destination.set(k, temp); + updateCycleJointPos[k]=temp; + + } + + /*terminateFlag=checkCollisionWithEEF(updateCycleJointPos); + if(terminateFlag==true) + { + dabak.terminateBool=true; + dabak.soc.close(); + dabak.ss.close(); + + break; + }*/ + + theDirectServoRuntime.setDestination(destination); + + } + } + catch (Exception e) + { + getLogger().info(e.getLocalizedMessage()); + e.printStackTrace(); + //Print statistics and parameters of the motion + getLogger().info("Simple Cartesian Test \n" + theDirectServoRuntime.toString()); + + getLogger().info("Stop the DirectServo motion"); + + + } + theDirectServoRuntime.stopMotion(); + + } + + + double getTheDisplacment(double dj) + { + + return dj; + /* + double a=0.07; + double b=a*0.75; + double exponenet=-Math.pow(dj/b, 2); + return Math.signum(dj)*a*(1-Math.exp(exponenet)); + */ + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkIIWADirectServoJoints app = new SimulinkIIWADirectServoJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] jpos=new double[7]; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + for(int i=0;i<7;i++) + { + jpos[i]=0; + } + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + jpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkIIWADirectServoJoints.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Joint space motion open loop/iiwa/SimulinkIIWASmartServoJoints.java b/Joint space motion open loop/iiwa/SimulinkIIWASmartServoJoints.java new file mode 100644 index 0000000..2b6d11d --- /dev/null +++ b/Joint space motion open loop/iiwa/SimulinkIIWASmartServoJoints.java @@ -0,0 +1,413 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.common.StatisticTimer; +import com.kuka.common.ThreadUtil; +import com.kuka.common.StatisticTimer.OneTimeStep; +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.SmartServo; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; +import com.kuka.roboticsAPI.geometricModel.LoadData; +import com.kuka.roboticsAPI.geometricModel.ObjectFrame; +import com.kuka.roboticsAPI.geometricModel.Tool; +import com.kuka.roboticsAPI.geometricModel.math.XyzAbcTransformation; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; +import java.nio.ByteBuffer; + +import lbrExampleApplications.SimulinkIIWADirectServoJoints.UDPServer; + +/* + * SimulinkIIWA interface, soft real-time control in joint position mode + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (smartDirectServoJoints.slx) + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 or 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class to a new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the Direct/SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * * TRANSLATION_OF_TOOL: translation of tool center point with respect to flange frame. + * * massOfTool: mass of the tool + * * toolsCOMCoordiantes: coordinates of center of mass of tool with regards to the frame of the flange. + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (smartDirectServoJoints.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + + +public class SimulinkIIWASmartServoJoints extends RoboticsAPIApplication +{ + private LBR _lbr; + private ISmartServoRuntime _theSmartServoRuntime = null; + + // Tool Data + private Tool _toolAttachedToLBR; + private LoadData _loadData; + private static final String TOOL_FRAME = "toolFrame"; + private static final double[] TRANSLATION_OF_TOOL = { 0, 0, 100 }; + private static final double MASS = 0.4; + private static final double[] CENTER_OF_MASS_IN_MILLIMETER = { 0, 0, 100 }; + + private int _count = 0; + + private static final int MILLI_SLEEP_TO_EMULATE_COMPUTATIONAL_EFFORT = 1; + private int _steps = 0; + + public static boolean loopFlag; + public static double[] jpos; + private UDPServer udpServer; + + + + + + @Override + public void initialize() + { + _lbr = getContext().getDeviceFromType(LBR.class); + jpos=new double[7]; + for(int i=0;i<7;i++) + { + jpos[i]=0; + } + loopFlag=true; + addLoadData(); + } + + private void addLoadData() + { + // Create a Tool by Hand this is the tool we want to move with some mass + // properties and a TCP-Z-offset of 100. + _loadData = new LoadData(); + _loadData.setMass(MASS); + _loadData.setCenterOfMass( + CENTER_OF_MASS_IN_MILLIMETER[0], CENTER_OF_MASS_IN_MILLIMETER[1], + CENTER_OF_MASS_IN_MILLIMETER[2]); + _toolAttachedToLBR = new Tool("Tool", _loadData); + + XyzAbcTransformation trans = XyzAbcTransformation.ofTranslation( + TRANSLATION_OF_TOOL[0], TRANSLATION_OF_TOOL[1], + TRANSLATION_OF_TOOL[2]); + ObjectFrame aTransformation = _toolAttachedToLBR.addChildFrame(TOOL_FRAME + + "(TCP)", trans); + _toolAttachedToLBR.setDefaultMotionFrame(aTransformation); + // Attach tool to the robot + _toolAttachedToLBR.attachTo(_lbr.getFlange()); + } + + /** + * Move to an initial Position WARNING: MAKE SURE, THAT the pose is collision free. + */ + private void moveToInitialPosition() + { + _lbr.move( + ptp(0., 0.,0.,0.,0.,0., 0.).setJointVelocityRel(0.15)); + /* Note: The Validation itself justifies, that in this very time instance, the load parameter setting was + * sufficient. This does not mean by far, that the parameter setting is valid in the sequel or lifetime of this + * program */ + try + { + + } + catch (IllegalStateException e) + { + getLogger().info("Omitting validation failure for this sample\n" + + e.getMessage()); + } + } + + /** + * Main Application Routine + */ + @Override + public void run() + { + moveToInitialPosition(); + System.out.print("You have ten seconds to establish a connection with iiwa"); + int portTemp=30002; + udpServer=new UDPServer(portTemp); + startSmartServo(); + } + + private void startSmartServo(){ + + boolean doDebugPrints = false; + + JointPosition initialPosition = new JointPosition( + _lbr.getCurrentJointPosition()); + SmartServo aSmartServoMotion = new SmartServo(initialPosition); + + // Set the motion properties to 20% of systems abilities + aSmartServoMotion.setJointAccelerationRel(0.2); + aSmartServoMotion.setJointVelocityRel(0.2); + + aSmartServoMotion.setMinimumTrajectoryExecutionTime(20e-3); + + getLogger().info("Starting SmartServo motion in position control mode"); + _toolAttachedToLBR.getDefaultMotionFrame().moveAsync(aSmartServoMotion); + + getLogger().info("Get the runtime of the SmartServo motion"); + _theSmartServoRuntime = aSmartServoMotion.getRuntime(); + + // create an JointPosition Instance, to play with + JointPosition destination = new JointPosition( + _lbr.getJointCount()); + for(int i=0;i<7;i++){ + jpos[i]=destination.get(i); + } + getLogger().info("Start loop"); + // For Roundtrip time measurement... + StatisticTimer timing = new StatisticTimer(); + try + { + // do a cyclic loop + // Refer to some timing... + // in nanosec + + long startTimeStamp = System.nanoTime(); + while(loopFlag==true) + { + _steps=_steps+1; + // Timing - draw one step + OneTimeStep aStep = timing.newTimeStep(); + // /////////////////////////////////////////////////////// + // Insert your code here + // e.g Visual Servoing or the like + // emulate some computational effort - or waiting for external + // stuff + ThreadUtil.milliSleep(MILLI_SLEEP_TO_EMULATE_COMPUTATIONAL_EFFORT); + _theSmartServoRuntime.updateWithRealtimeSystem(); + // Get the measured position + JointPosition curMsrJntPose = _theSmartServoRuntime + .getAxisQMsrOnController(); + + for (int k = 0; k < destination.getAxisCount(); ++k) + { + jpos[k]=udpServer.jpos[k]; + destination.set(k, jpos[k]); + } + _theSmartServoRuntime.setDestination(destination); + + // //////////////////////////////////////////////////////////// + if (doDebugPrints) + { + getLogger().info("Step " + _steps + " New Goal " + + destination); + getLogger().info("Fine ipo finished " + _theSmartServoRuntime.isDestinationReached()); + if (_theSmartServoRuntime.isDestinationReached()) + { + _count++; + } + getLogger().info("Ipo state " + _theSmartServoRuntime.getFineIpoState()); + getLogger().info("Remaining time " + _theSmartServoRuntime.getRemainingTime()); + getLogger().info("LBR Position " + + _lbr.getCurrentJointPosition()); + getLogger().info(" Measured LBR Position " + + curMsrJntPose); + if (_steps % 100 == 0) + { + // Some internal values, which can be displayed + getLogger().info("Simple Joint Test - step " + _steps + _theSmartServoRuntime.toString()); + + } + } + aStep.end(); + + } + } + catch (Exception e) + { + getLogger().info(e.getLocalizedMessage()); + e.printStackTrace(); + } + ThreadUtil.milliSleep(1000); + + //Print statistics and parameters of the motion + getLogger().info("Displaying final states after loop "); + getLogger().info(getClass().getName() + _theSmartServoRuntime.toString()); + // Stop the motion + + getLogger().info("Stop the SmartServo motion"); + _theSmartServoRuntime.stopMotion(); + + getLogger().info(_count + " times was the destination reached."); + getLogger().info("Statistic Timing of Overall Loop " + timing); + if (timing.getMeanTimeMillis() > 150) + { + getLogger().info("Statistic Timing is unexpected slow, you should try to optimize TCP/IP Transfer"); + getLogger().info("Under Windows, you should play with the registry, see the e.g. the SmartServo Class javaDoc for details"); + } + } + + + double getTheDisplacment(double dj) + { + + return dj; + /* + double a=0.07; + double b=a*0.75; + double exponenet=-Math.pow(dj/b, 2); + return Math.signum(dj)*a*(1-Math.exp(exponenet)); + */ + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkIIWASmartServoJoints app = new SimulinkIIWASmartServoJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] jpos=new double[7]; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + for(int i=0;i<7;i++) + { + jpos[i]=0; + } + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + jpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkIIWASmartServoJoints.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Joint space motion open loop/simulink/smartDirectServoJoints.slx b/Joint space motion open loop/simulink/smartDirectServoJoints.slx new file mode 100644 index 0000000000000000000000000000000000000000..9e69a1a82bc323c220572dbfed39fd16cd4afb4b GIT binary patch literal 23901 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 YzODwwjqZYiLVEL2yzvjwjsN)df2M7=uK)l5 literal 0 HcmV?d00001 diff --git a/Joint space motion open loop/simulink/smartDirectServoJoints.slxc b/Joint space motion open loop/simulink/smartDirectServoJoints.slxc new file mode 100644 index 0000000000000000000000000000000000000000..4eabd5a65976156e7f327259ff016eef5d7cb3bf GIT binary patch literal 5353 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[k]) + { + jDispMax[k]=absDisp; + } + destination.set(k, temp); + updateCycleJointPos[k]=temp; + + } + + /*terminateFlag=checkCollisionWithEEF(updateCycleJointPos); + if(terminateFlag==true) + { + dabak.terminateBool=true; + dabak.soc.close(); + dabak.ss.close(); + + break; + }*/ + + theDirectServoRuntime.setDestination(destination); + + } + } + catch (Exception e) + { + getLogger().info(e.getLocalizedMessage()); + e.printStackTrace(); + //Print statistics and parameters of the motion + getLogger().info("Simple Cartesian Test \n" + theDirectServoRuntime.toString()); + + getLogger().info("Stop the DirectServo motion"); + + + } + theDirectServoRuntime.stopMotion(); + + } + + + double getTheDisplacment(double dj) + { + + return dj; + /* + double a=0.07; + double b=a*0.75; + double exponenet=-Math.pow(dj/b, 2); + return Math.signum(dj)*a*(1-Math.exp(exponenet)); + */ + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkFIIWADirectServoJoints app = new SimulinkFIIWADirectServoJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] jpos=new double[7]; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + for(int i=0;i<7;i++) + { + jpos[i]=0; + } + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + jpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkFIIWADirectServoJoints.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Joint space motion with feedback/iiwa/SimulinkFIIWASmartServoJoints.java b/Joint space motion with feedback/iiwa/SimulinkFIIWASmartServoJoints.java new file mode 100644 index 0000000..b74856a --- /dev/null +++ b/Joint space motion with feedback/iiwa/SimulinkFIIWASmartServoJoints.java @@ -0,0 +1,539 @@ +package lbrExampleApplications; + + +import static com.kuka.roboticsAPI.motionModel.BasicMotions.ptp; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import com.kuka.common.StatisticTimer; +import com.kuka.common.ThreadUtil; +import com.kuka.common.StatisticTimer.OneTimeStep; +import com.kuka.connectivity.motionModel.directServo.DirectServo; +import com.kuka.connectivity.motionModel.directServo.IDirectServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.ISmartServoRuntime; +import com.kuka.connectivity.motionModel.smartServo.SmartServo; +import com.kuka.generated.ioAccess.MediaFlangeIOGroup; +import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication; +import com.kuka.roboticsAPI.controllerModel.Controller; +import com.kuka.roboticsAPI.deviceModel.JointPosition; +import com.kuka.roboticsAPI.deviceModel.LBR; +import com.kuka.roboticsAPI.geometricModel.Frame; +import com.kuka.roboticsAPI.geometricModel.LoadData; +import com.kuka.roboticsAPI.geometricModel.ObjectFrame; +import com.kuka.roboticsAPI.geometricModel.Tool; +import com.kuka.roboticsAPI.geometricModel.World; +import com.kuka.roboticsAPI.geometricModel.math.XyzAbcTransformation; +import com.kuka.roboticsAPI.sensorModel.ForceSensorData; + + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import lbrExampleApplications.SimulinkFIIWADirectServoJoints.UDPPublisher; +import lbrExampleApplications.SimulinkIIWADirectServoJoints.UDPServer; + +/* + * SimulinkIIWA interface, soft real-time control in joint position mode + * Copyright: Mohammad SAFEEA, 22nd/May/2018 + * License: MIT license + * + * This is a UDP server that receives motion commands from Simulink. + * This server works together with the Simulink example: (feedBackSmartDirectServoJoints.slx) + * + * Also this script returns back a feedback about the (1)actual joints positions, + * (2)the external torques and (3)the measured torques of all the joints to Simulink. + * (4) EEF force moment. + * + * Below you can find quick start instructions, for more info, please refer to the youtube + * video tutorials, a link for which is available in the repository main page. + * + * Hardware setup: + * 1- KUKA iiwa 7R800 or 14R820 + * 2- External PC + * 3- A network between the PC and the robot, the connector X66 + * of the robot shall be used + * + * Required software: + * 1- MATLAB with Simulink, the code was written using MATLAB2018a, it + * is recommended to use the same version. + * 2- Sunrise.Workbench, this program will be used to synchronize the java + * code to the robot. + * 3- The Sunrise code was tested on (KUKA Sunrise.OS 1.11.0.7) + * + * Setup instructions: + * 1- Add this class to a new project using kuka's Sunrsie.Workbench. + * 2- Add reference to the Direct/SmartServo from inside the (StationSetup.cat) file. + * 3- Change the following variables according to your preference: + * * externa_PC_IP: change this variable according to the IP of the PC used for control. + * * TRANSLATION_OF_TOOL: translation of tool center point with respect to flange frame. + * * massOfTool: mass of the tool + * * toolsCOMCoordiantes: coordinates of center of mass of tool with regards to the frame of the flange. + * + * + * Utilization instructions: + * 1- Synchronize the project to the controller of the robot. + * 2- Run this application from the teach-pad of the robot, + * This application has a time out of 10 seconds, if a connection + * is not established during the 10 seconds interval the server will + * turn off. + * 3- Start the Simulink example (feedBackSmartDirectServoJoints.slx) + * from the external PC. + * 4- To change the timeout value, change the argument for the instruction + * soc.setSoTimeout(10000), the argument is in milliseconds. + * + */ + +public class SimulinkFIIWASmartServoJoints extends RoboticsAPIApplication +{ + private static String externa_PC_IP="172.31.69.55"; + private LBR _lbr; + private ISmartServoRuntime _theSmartServoRuntime = null; + + // Tool Data + private Tool _toolAttachedToLBR; + private LoadData _loadData; + private static final String TOOL_FRAME = "toolFrame"; + private static final double[] TRANSLATION_OF_TOOL = { 0, 0, 100 }; + private static final double MASS = 0.4; + private static final double[] CENTER_OF_MASS_IN_MILLIMETER = { 0, 0, 100 }; + + private int _count = 0; + + private static final int MILLI_SLEEP_TO_EMULATE_COMPUTATIONAL_EFFORT = 1; + private int _steps = 0; + + public static boolean loopFlag; + public static double[] jpos; + private UDPServer udpServer; + + + + public class UDPPublisher implements Runnable{ + + String ip; + UDPPublisher(String ip) + { + this.ip=ip; + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + } + public void run() + { + broadcastData(); + } + private void broadcastData() { + // TODO Auto-generated method stub + String message="Publishing robot state using UDP at port 30008 to destination: "+ ip; + System.out.println(message); + message="Streamed message: 7 actual joint angles, 7 measured torques, 7 external torques,"; + System.out.println(message); + message="State streaming frequency is approximatly at 25HZ"; + System.out.println(message); + int port=30008; + InetAddress host; + int numOfDoubles=7+7+7+6;// 7 actual joint angles, 7 measured torques, 7 external torques, 7 force at flange + double[] doubleVals=new double[numOfDoubles]; + + byte[] buffer= new byte[8*numOfDoubles]; + + try { + host = InetAddress.getByName(ip); + DatagramSocket soc=new DatagramSocket(); + while(loopFlag) + { + // Feedback of actual joints positions + JointPosition jpos=_lbr.getCurrentJointPosition(); + int valsCounter=0; + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=jpos.get(i); + valsCounter=valsCounter+1; + } + // Feedback of measured torques + double[] m_tor=_lbr.getMeasuredTorque().getTorqueValues(); + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=m_tor[i]; + valsCounter=valsCounter+1; + } + // Feedback of external torques + double[] ex_tor=_lbr.getExternalTorque().getTorqueValues(); + for(int i=0;i<7;i++) + { + doubleVals[valsCounter]=ex_tor[i]; + valsCounter=valsCounter+1; + } + // Feedback of forces at flange + ForceSensorData f_at_flange=_lbr.getExternalForceTorque(_lbr.getFlange(),World.Current.getRootFrame()); + doubleVals[valsCounter]=f_at_flange.getForce().getX(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getForce().getY(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getForce().getZ(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getX(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getY(); + valsCounter=valsCounter+1; + doubleVals[valsCounter]=f_at_flange.getTorque().getZ(); + valsCounter=valsCounter+1; + + int count=0; + for(int i=0;i 150) + { + getLogger().info("Statistic Timing is unexpected slow, you should try to optimize TCP/IP Transfer"); + getLogger().info("Under Windows, you should play with the registry, see the e.g. the SmartServo Class javaDoc for details"); + } + } + + + double getTheDisplacment(double dj) + { + + return dj; + /* + double a=0.07; + double b=a*0.75; + double exponenet=-Math.pow(dj/b, 2); + return Math.signum(dj)*a*(1-Math.exp(exponenet)); + */ + } + + + /** + * Main routine, which starts the application + */ + public static void main(String[] args) + { + SimulinkFIIWASmartServoJoints app = new SimulinkFIIWASmartServoJoints(); + app.runApplication(); + } + + public class UDPServer implements Runnable{ + + public double[] jpos=new double[7]; + + double stime=0; + double endtime=0; + + int _port; + int vectorSize=7; + int packetCounter=0; + + byte[] buffer=new byte[8*vectorSize]; + UDPServer(int port) + { + for(int i=0;i<7;i++) + { + jpos[i]=0; + } + Thread t=new Thread(this); + t.setDaemon(true); + t.start(); + _port=port; + } + + public void run() + { + System.out.println("Program will terminate if comuncation is not established in 10 seconds"); + DatagramSocket soc=null; + try { + soc = new DatagramSocket(_port); + soc.setSoTimeout(10000); // 5 seconds, if a time out occurred, turn off program + DatagramPacket response=new DatagramPacket(buffer, buffer.length); + while(true) + { + soc.receive(response); + packetCounter=packetCounter+1; + // String s= new String(buffer,0,response.getLength()) + // System.out.println(response.getLength()); + if(response.getLength()==8*vectorSize) + { + if(packetCounter==1) + { + stime=System.currentTimeMillis(); + } + else + { + endtime=System.currentTimeMillis(); + } + byte[] daB=new byte[8]; + int counter=0; + int jointNum=0; + while(counter <8*vectorSize) + { + for(int i=0;i<8;i++) + { + daB[7-i]=buffer[counter]; + counter=counter+1; + } + jpos[jointNum]=bytesToDouble(daB); + jointNum=jointNum+1; + //System.out.println(bytesToDouble(daB)); + } + } + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + System.out.println(e.toString()); + } + if(soc==null) + {} + else + { + if(soc.isClosed()) + {} + else + { + soc.close(); + } + } + SimulinkFIIWASmartServoJoints.loopFlag=false; //Turn off main loop + double time=(endtime-stime)/1000; + double rate=packetCounter/time; + System.out.println("update rate, packets/second"); + System.out.println(rate); + } + } + + + public double bytesToDouble(byte[] b) + { + return ByteBuffer.wrap(b).getDouble(); + } + +} diff --git a/Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slx b/Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slx new file mode 100644 index 0000000000000000000000000000000000000000..645ad1b90f15f84ed0d3315abb6b7cdd0e013432 GIT binary patch literal 26400 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 M02EZ8!5{zqKQ3B}=Kufz literal 0 HcmV?d00001 diff --git a/Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slxc b/Joint space motion with feedback/simulink/feedBackSmartDirectServoJoints.slxc new file mode 100644 index 0000000000000000000000000000000000000000..3f8c0722b4dcecf369d7466f46cb1c66f34df778 GIT binary patch literal 5379 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 TXz4cZV*@^MK=WCHH~;+$XYoMl literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 6841117..103fd00 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,50 @@ The Simulink-iiwa is an interface that allows the user to control KUKA iiwa manipulaotrs from Simulink. Unlike the ![KUKA Sunrise Toolbox or KST](https://github.com/Modi1987/KST-Kuka-Sunrise-Toolbox), the Simulink interface is built upon UDP protocol instead of TCP/IP protocol. +-------------------------------------- + +# Requirments: + The project in this rpository was tested using: -Matlab 2018a -KUKA iiwa 7R800 with Sunrise.OS 1.11.0.7 +* Matlab 2018a, running under Windows 10. +* KUKA iiwa 7R800 with Sunrise.OS 1.11.0.7 + +-------------------------------------- +# Installation +There are various steps that you shall dow on the Matlab side and on the iiwa side: + +## Matlab side: +* First open Matlab 2018a +* Then, you shall install the Simulink Desktop Real-time Kernel by ![following the instructions in here](https://www.mathworks.com/help/sldrt/ug/real-time-windows-target-kernel.html). +* Note: Mathworks provides the (Simulink Desktop Real-time) under Windows and Mac operating systems. Though the provided scripts were tested only under Windows. To check the installation status of the kernel type (rtwho) in the command window of Matlab 2018a. + +## IIWA side: +* You will need a computer connected to the robot through an ethernet cable on X66 connector. +* Open the Sunrise.Workbench on the computer side. +* Download the repository into your computer, unzip it inside a folder (SimulinkIIWA) for example. +* Then from inside the (SimulinkIIWA) pick up one of the operation modes available, for example (Cartesian motion open loop). Each operation mode is provided in separate folder, which contains the corresponding Sunrise.Workbench code along with the Simulink interface. +* Inside the (Cartesian motion open loop) folder, open the (iiwa) sub-folder. +* You shall copy the available (java) file into a project inside the Sunrise.Workbench then synchronise into the robot controller. +* The newly added application shall show up in the application list on the smart pad of the robot. +-------------------------------------- + +# Operation: +First run the server on IIWA side using the smart pad, then you shall run the Simulink project in Matlab 2018a. + +## IIWA side: +* Run the server application from the smart pad, you find it in the applications list under the name (SimulinkIIWADirectServoCartesian). +* You will have 10 seconds to connect, if a connection was not initiated during the time limit the program will be terminated automatically. +* If the connection is terminated, you have to run the server again before initiating a connection. + +## Matlab side: +* Inside the (Cartesian motion open loop) folder, open the (iiwa) sub-folder. +* You shall find the simulink application, run it using Matlab 2018a. +* After runnng the (SimulinkIIWADirectServoCartesian) on the robot side, you shall run the simulink project from matlab. +* The robot shall move according to the motion command from simulink. + +-------------------------------------- + +Copyright: Mohammad Safeea. -Copyright: Mohammad Safeea +The project is a work in progress, use it under your own responsibility, check the license.