Skip to content

Instantly share code, notes, and snippets.

@bhomaidan1990
Created October 29, 2021 13:49
Show Gist options
  • Save bhomaidan1990/f2b3ab3b301d4813b7225124f35a0ff2 to your computer and use it in GitHub Desktop.
Save bhomaidan1990/f2b3ab3b301d4813b7225124f35a0ff2 to your computer and use it in GitHub Desktop.
RWS in Java
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import java.util.Map;
import static org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.digest;
/**
* This the main class distributed in this package.
* It is the implementation of a REST Client for using ABB Robot Web Services 1.0 API for the robot Yumi.
* <br/>The reference for this API is found on ABB's website @see <a href="https://developercenter.robotstudio.com/api/rwsApi/">here</a>.
* It implements most of the methods useful for controlling Yumi via RWS.
*
* <br/>It is used as follows:
* <br/><code>
* import javax.ws.rs.core.Response;
*
* <br/>public class myAppUsingRWS {
* <br/>
* <br/> public static void main(String[] args) {
* <br/> RWS4Yumi cl = new RWS4Yumi("id","pass");
* <br/> Response response20 = cl.connect("yumi","Test_API","bbb","local");
* <br/> System.out.println(response20);
* <br/> }
* <br/>}
* </code><br/>
*/
public class RWS4Yumi {
/**
* The IPv4 address of your robot on the network.
* The default address is set in here.
*/
protected String REST_URI = "http://192.168.125.1";
protected String username;
protected String password;
protected final HttpAuthenticationFeature digestAuth;
protected final Client client;
protected String cookie;
/**
* This is the main constructor for this class.
* It takes as parameters your identification credentials on the robot:
* @param username The username of your account on the robot.
* @param password The password of your account on the robot.
*/
public RWS4Yumi(String username, String password) {
this.digestAuth = digest(username, password);
this.client = ClientBuilder.newBuilder().register(this.digestAuth).build();
getCookie();
}
/**
* This is the another constructor for this class that asks for the ip address of the robot.
* It takes as parameters your identification credentials on the robot:
* @param ip The ip of your robot on the network
* @param username The username of your account on the robot.
* @param password The password of your account on the robot.
*/
public RWS4Yumi(String ip, String username, String password) {
this.REST_URI = ip;
this.digestAuth = digest(username, password);
this.client = ClientBuilder.newBuilder().register(this.digestAuth).build();
getCookie();
}
//------------------API FUNCTIONS------------------
/**
* Gets the cookie and sets it in the client
*/
private void getCookie() {
Invocation.Builder builder = client.target(REST_URI).request();
Response response = builder.get();
Map<String, NewCookie> cookie1 = response.getCookies();
StringBuilder mapAsString = new StringBuilder();
for (String key : cookie1.keySet()) {
mapAsString.append(key).append("=").append(cookie1.get(key).getValue()).append("; ");
}
mapAsString.delete(mapAsString.length()-2, mapAsString.length());
cookie = mapAsString.toString();
}
/**
* Gets the user ID generated by the robot's web server. It is needed to be able to grant a RMMP request
* @return A string: the user ID
*/
public String userID() {
String response = getRMMPState().readEntity(String.class);
Document doc = Jsoup.parse(response);
Elements elements = doc.getElementsByClass("userid");
return elements.text();
}
/**
* Performs the necessary functions to connect with the robot to operate in "manual" mode.
* <br/>1. registerTheUser
* <br/>2. requestRMMP
* <br/>3. grantOrDenyRMMPrequest
* <br/>4. mastershipRequest<br/>
* @param username The username to register
* @param application The application name to register
* @param location The location of the user
* @param ulocale {local | remote} must be local
* @return A Response type
*/
public Response connect(String username, String application, String location, String ulocale ) {
registerTheUser (username, application, location, ulocale);
Response response = requestRMMP();
if (response.getStatus()==202) {
grantOrDenyRMMPrequest(userID(), "modify");
Response response1 = mastershipRequest();
if (response1.getStatus()==204)
System.out.println("Successful connection");
else {
System.out.println(response1);
System.out.println(response1.readEntity(String.class));
}
}
else {
System.out.println(response);
System.out.println(response.readEntity(String.class));
}
return response;
}
//------------------------------------------------------
//------------------------------------------------------
//------------------GET REQUESTS------------------------
//------------------------------------------------------
//------------------------------------------------------
//------------------USER SERVICE------------------
/**
* Shows the data of who has the remote control.
* @return A Response type
*/
public Response getRMMPState() {
Invocation.Builder builder = client.target(REST_URI).path("/users/rmmp").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty()) {
getCookie();
}
return response;
}
//------------------MOTION SYSTEM------------------
/**
* Shows the position in coordinates of the last axis of the mechunit selected.
* @param mechunit {ROB_R | ROB_L}
* @param tool {tool_name}
* @param wobj {wobj_name}
* @param coordinate {Base | Word | Tool | Wobj}
* @return A Response type
*/
public Response getCartesianValue(String mechunit, String tool, String wobj, String coordinate) {
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/"+mechunit+"/cartesian").queryParam("tool",tool).queryParam("wobj",wobj).queryParam("coordinate",coordinate).queryParam("elog-at-err",0).request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Incremental value every time the mechunit for jogging is changed, this value is required for jogging requests.
* @return String with the change count number
*/
public String getChangeCount() {
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem").queryParam("resource","change-count").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
Document doc = Jsoup.parse(response.readEntity(String.class));
Elements elements = doc.getElementsByClass("ms");
return elements.first().text();
}
/**
* Show the position in angles of the 7 axes of the selected mechunit
* @param mechunit {ROB_R | ROB_L}
* @return A Response type
*/
public Response getAngles(String mechunit) {
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/"+mechunit+"/jointtarget").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets the status of the Lead Through
* @param mechunit {ROB_R | ROB_L | ROB_R_7 | ROB_L_7}
* @return A Response type
*/
public Response getComplianceLeadThrough(String mechunit) {
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/"+mechunit).queryParam("resource", "lead-through").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets the mechanical unit properties info
* @param mechunit {ROB_R | ROB_L | ROB_R_7 | ROB_L_7}
* @return A Response type
*/
public Response getMechunit(String mechunit) {
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/"+mechunit).queryParam("continue-on-err", "1").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
//------------------RAPID SERVICE------------------
/**
* Gets the rapid execution state
* @return A Response type
*/
public Response getRapidExecState() {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/execution").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets the data from a defined rapid variable
* @param symbolurl URL path to the targeted variable for example "RAPID/T_ROB_L/tool0"
* @return A Response type
*/
public Response getDataFromRapidVariable(String symbolurl) {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/symbol/data/"+symbolurl).request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Get a list of actions that can be invoked on a RAPID data resource.
* @param symbolurl URL path to the targeted resource
* @return A Response type
*/
public Response getRAPIDSymbolDataActions(String symbolurl) {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/symbol/data/"+symbolurl).queryParam("action", "show").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets a list of targets that are currently synchronized and can be modified
* @return A Response type
*/
public Response getRAPIDPossibleModules() {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/modules").queryParam("resource", "mod-possible-all").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets a list of all rapid tasks
* @return A Response type
*/
public Response getRAPIDTasks() {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/tasks").queryParam("continue-on-err", "0").request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Gets the text from a RAPID Module
* @param moduleName String that represents the name of the targeted module
* @param taskName String that represents the name of the targeted task
* @return A Response type
*/
public Response getModuleText(String moduleName, String taskName) {
Invocation.Builder builder = client.target(REST_URI).path("rw/rapid/modules/"+moduleName).queryParam("resource", "module-text").queryParam("task", taskName).request();
Response response = builder.header("Cookie",cookie).get();
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
//------------------------------------------------------
//------------------------------------------------------
//------------------POST REQUESTS------------------------
//------------------------------------------------------
//------------------------------------------------------
//------------------USER SERVICE------------------
/**
* Registers the user. ulocale must be "local" in order to be able to operate the robot
* @param username The username to register
* @param application The application name to register
* @param location The location of the user
* @param ulocale {local | remote}
* @return A Response type
*/
public Response registerTheUser(String username, String application, String location, String ulocale) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("username" , username);
body.param("application", application);
body.param("location", location);
body.param("ulocale", ulocale);
Invocation.Builder builder = client.target(REST_URI).path("/users").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Requests remote control. Control lasts 5 minutes of inactivity.
* @return A Response type
*/
public Response requestRMMP() {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("privilege", "modify");
Invocation.Builder builder = client.target(REST_URI).path("/users/rmmp").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Grants or denies an RMMP request
* @param uid The id of the user who made the request for rmmp. This is automatically generated by the robot's web server. It can be obtain calling the function userID.
* @param privilege {modify | exec | deny} To operate it must be in "modify".
* @return A Response type
*/
public Response grantOrDenyRMMPrequest(String uid, String privilege) {
Form body = new Form();
body.param("uid", uid);
body.param("privilege", privilege);
Invocation.Builder builder = client.target(REST_URI).path("/users/rmmp").queryParam("action", "set").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Requestss mastership on all domains i.e. CFG, Motion, and RAPID
* @return A Response type
*/
public Response mastershipRequest() {
Form body = new Form();
Invocation.Builder builder = client.target(REST_URI).path("/rw/mastership").queryParam("action", "request").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Cancels held or requested RMMP
* @return A Response type
*/
public Response cancelHeldOrRequestedRMMP() {
Form body = new Form();
Invocation.Builder builder = client.target(REST_URI).path("/users/rmmp").queryParam("action", "cancel").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Releases the mastership on the robot
* @return A response type
*/
public Response mastershipRelease() {
//Release the mastership
Form body = new Form();
Invocation.Builder builder = client.target(REST_URI).path("/rw/mastership").queryParam("action", "release").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
//------------------MOTION SYSTEM------------------
/**
* Sets the Mechunit for jogging.
* @param mechunit {ROB_R | ROB_L | ROB_R_7 | ROB_L_7} The selected mechunit to jog.
* @return A Response type
*/
public Response setMechunitForJogging(String mechunit) {
Form body = new Form();
body.param("mechunit-name" , mechunit);
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem").queryParam("action", "set-mechunit").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Performs jogging on the selected mechunit
* When jogging the mech units ROB_R or ROB_L, each parameter corresponds to each of the 6 axes.
* When jogging the mech units ROB_R_7 or ROB_L_7, "axis1" corresponds to the 7th axis of the robot. The parameters of the axis2 to axis6 don’t do anything.
* The value of each axis must be between -2048 and 2048. With the maximum value (2048), it moves 6,15 degrees.
* @param axis1 String of the value between -2048 and 2048
* @param axis2 String of the value between -2048 and 2048
* @param axis3 String of the value between -2048 and 2048
* @param axis4 String of the value between -2048 and 2048
* @param axis5 String of the value between -2048 and 2048
* @param axis6 String of the value between -2048 and 2048
* @return A Response type
*/
public Response PerformJogging(String axis1, String axis2, String axis3, String axis4, String axis5, String axis6) {
String ccount = getChangeCount();
Form body = new Form();
body.param("axis1" , axis1);
body.param("axis2" , axis2);
body.param("axis3" , axis3);
body.param("axis4" , axis4);
body.param("axis5" , axis5);
body.param("axis6" , axis6);
body.param("ccount" , ccount);
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem").queryParam("action", "jog").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Sets the Lead-Through mode ON/OFF on target mechanical unit
* @param mechunit {ROB_R | ROB_L | ROB_R_7 | ROB_L_7} Mechunit targeted
* @param status {active|inactive}
* @return A Response type
*/
public Response setComplianceLeadThrough(String mechunit, String status) {
Form body = new Form();
body.param("status" , status);
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/").path(mechunit).queryParam("action", "set-lead-through").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Configures tool, wobj, payload, total-payload, mode, coord-system, jog-mode of the selected mechunit
* @param mechunit {ROB_R | ROB_L} The selected mechunit
* @param tool {tool_name} The name of the chosen tool, for example tool0.
* @param wobj {wobj_name} Wobjdata for the mechunit
* @param payload {payload_name} Loaddata for the mechunit
* @param total_payload {payload_name} Total Loaddata for the mechunit
* @param mode {Activated|Deactivated} Activation status of the mechunit
* @param jog_mode {AxisGroup1|AxisGroup2|Align|GoToPos|ConfigurationJog|Cartesian} Jogging mode of the mechunit. The modes each perform differently:
* <br/>In AxisGroup1 each axis moves independently.
* <br/>In Cartesian, it moves the whole arm.
* <br/>In ConfigurationJog, it moves the axis but it maintain the gripper in the same position
* <br/>In GoToPos, makes "Perform Jogging" stop working and the motors must be turned off and on to restart
* <br/>In other modes, it does not work.
* @param coord_system {Wobj|Base|Tool|Word} Coordinate system used by the mechunit
* @return A Response type
*/
public Response setMechunit(String mechunit, String tool, String wobj, String payload, String total_payload, String mode, String jog_mode, String coord_system) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("tool" , tool);
body.param("wobj" , wobj);
body.param("payload" , payload);
body.param("total-payload" , total_payload);
body.param("mode" , mode);
body.param("jog-mode" , jog_mode);
body.param("coord-system" , coord_system);
Invocation.Builder builder = client.target(REST_URI).path("/rw/motionsystem/mechunits/"+mechunit).queryParam("action", "set").queryParam("continue-on-err", "1").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
//------------------PANEL SERVICE------------------
/**
* Sets the controller state either Motors ON or Motors OFF
* @param state {motoron | motoroff} Target state
* @return A Response type
*/
public Response setControllerState(String state) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("ctrl-state" , state);
Invocation.Builder builder = client.target(REST_URI).path("/rw/panel/ctrlstate").queryParam("action", "setctrlstate").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
//------------------RAPID SERVICE------------------
/**
* Sets number of execution cycles
* @param cycle {once | forever} Repetition of the program
* @return A Response type
*/
public Response setNumberOfExecutionCycles(String cycle) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("cycle" , cycle);
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/execution").queryParam("action", "setcycle").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Starts the rapid execution. The operation mode must be in automatic.
* @param regain {continue | regain | clear}
* @param execmode {continue | stepin | stepover | stepout | stepback | steplast | stepmotion}
* @param cycle {forever | asis | once} Overrides the number of executions
* @param condition {none | callchain}
* @param stopatbp {disabled | enabled} Stop at breakpoint status
* @param alltaskbytsp {true | false}
* @return A Response type
*/
public Response startRAPIDExecution(String regain, String execmode, String cycle, String condition, String stopatbp, String alltaskbytsp) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("regain" , regain);
body.param("execmode" , execmode);
body.param("cycle" , cycle);
body.param("condition" , condition);
body.param("stopatbp" , stopatbp);
body.param("alltaskbytsp" , alltaskbytsp);
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/execution").queryParam("action", "start").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Stops the rapid execution
* @param stopmode {cycle | instr | stop | qstop}
* @param usetsp {normal | alltsk}
* @return A Response type
*/
public Response stopRAPIDExecution(String stopmode, String usetsp) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("stopmode" , stopmode);
body.param("usetsp" , usetsp);
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/execution").queryParam("action", "stop").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Resets rapid program pointer to main
* @return A Response type
*/
public Response resetRAPIDProgramPointerToMain() {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/execution").queryParam("action", "resetpp").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Updates the value of a RAPID variable
* @param symbolurl URL path to the targeted variable
* @param value Value you want to set to the variable
* @return A Response type
*/
public Response setRAPIDVariable(String symbolurl, String value) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("value" , value);
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/symbol/data/"+symbolurl).queryParam("action", "set").request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
/**
* Updates text in a given RAPID module
* @param moduleName String that represents the name of the targeted module
* @param taskName String that represents the name of the targeted task
* @param value Value of the text to set to the chosen module.
* @return A Response type
*/
public Response setModuleText(String moduleName, String taskName, String value) {
Invocation.Builder builder1 = client.target(REST_URI).request();
Response response1 = builder1.header("Cookie",cookie).get();
if (!response1.getCookies().isEmpty())
getCookie();
Form body = new Form();
body.param("text" , value);
Invocation.Builder builder = client.target(REST_URI).path("/rw/rapid/modules/"+moduleName).queryParam("action", "set-module-text").queryParam("task", taskName).request();
Response response = builder.header("Cookie",cookie).post(Entity.form(body));
if (!response.getCookies().isEmpty())
getCookie();
return response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment