Posts: 21
Threads: 8
Joined: Feb 2019
Reputation:
1
How do the processing speeds compare for the following items?
-RoboDK native GUI robot programming
-Python API
-C++ API
-C++ Plugin Interface
I'm looking to create simulations and would like to avoid having choppy motions when multiple part objects are loaded.
Posts: 3,457
Threads: 2
Joined: Apr 2018
Reputation:
165
The short answer is in the following order:
- C++ Plugin Interface
- C++ API
- Python API
The long answer is:
Every time you trigger a specific action (either through the GUI, the API or the plugin interface), the action takes the same amount of time in all scenarios.
The Plugin interface is an order of magnitude faster if you need to do a lot of interactions through the API. More information here:
https://robodk.com/doc/en/PlugIns/index.html
The native GUI is as fast as the user can be. Once an action is triggered, the speed is the same for all platforms.
If you compare among the different implementations of the API, C++ is much faster than Python or Matlab as a programming language.
Posts: 21
Threads: 8
Joined: Feb 2019
Reputation:
1
My understanding of your long answer is that while the speed of each action is the same for all platforms, the time to trigger the event is different. Is this correct?
Is a program created using only GUI commands faster than the python or c++ API? In other words, is it on par with the c++ plugin interface?
I want to use whichever interface has the least amount of communication lag, so that sounds like the C++ api or the C++ plugin interface.
Lastly, is a robot program (start to finish), created using the plug in interface an intended use of the interface? It just seems a little backwards to need to load a .dll to create a robot simulation using c++.
Posts: 3,457
Threads: 2
Joined: Apr 2018
Reputation:
165
Your first assumption is correct: the time to trigger an event is different depending on the programming language (and, if you use the C++ plug-in interface it is much faster).
If you create a program using the RoboDK API or the plugin-interface, the result will be the same as if you created it manually using the GUI.
The fastest communication lag is the plug-in interface (by far). In this case you generate a DLL that is loaded by RoboDK and you have access to the low level functions RoboDK as immediate calls. Contrary to the standard RoboDK API, you need to trigger the Update/Render calls from your code. Among other things, the plugin interface allows you to customize the appearance of RoboDK. More information and examples here:
https://github.com/RoboDK/Plug-In-Interface
Posts: 21
Threads: 8
Joined: Feb 2019
Reputation:
1
12-18-2019, 11:35 PM
(This post was last modified: 12-18-2019, 11:40 PM by jccourtney.)
Albert,
I don't think you answered my question regarding how the total processing time for a program created using GUI program instructions compares to a program created using the C++ API and a program created using the C++ plugin interface.
I have been trying to create a simulation, and I initially created this program using the GUI instructions and then recreated it using the C++ API. I'm finding that the C++ program isn't as smooth as the GUI program, and it completes the 360 degree rotational motion at 4X faster than the program created using the GUI.
Additionally, the robot is reaching the position to spin 360 degrees 10 seconds after the program created using the GUI. As you can also see, the commands to switch the display a different tool results in flickers unlike the GUI program.
Program created using GUI program instructions:
Program created using C++ API:
Can you assist?
Thanks!
Posts: 3,457
Threads: 2
Joined: Apr 2018
Reputation:
165
I'm not sure I understand what you mean. The simulation speed should be the same in all situations. Even if you create a simulation/program using the C++ API (using AddProgram).
Maybe you changed the simulation speed?
Can you share the RDK file and/or part of the code?
I may be able to help you better.
Posts: 21
Threads: 8
Joined: Feb 2019
Reputation:
1
12-27-2019, 06:47 PM
(This post was last modified: 12-27-2019, 06:55 PM by jccourtney.)
Albert,
I created a side by side video of the same program being executed by the built-in GUI program instructions and the C++ api. The videos are synchronized to start when both robots begin moving. As you can see in the video, the GUI program simulation is finished well before the C++ api simulation is complete. Additionally, it appears the C++ program is so slow that it is skipping program steps, such as speed changes and move instructions.
Also, see attached code. The RDK file is too large to post (157 MB)
Code: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include "UR10Simulate.h"
UR10Simulate::UR10Simulate(){
this->RDK = NULL;
}
//Method Name: UR10Simulate constructor
//Goals: Pass the current instance of RDK and configure variables for all station items
// used with this simulation
//Input: RoboDK_API::RoboDK* RDK_instance
//Output: None
//Steps: Initialize all members to default values
UR10Simulate::UR10Simulate(RoboDK_API::RoboDK* RDK_instance){
//Pointer to RoboDK
this->RDK = RDK_instance;
//Pointer to Active Robot
this->active_robot = RDK->getItem("UR10e");
//Pointer to Pick/Place objects
this->i_2084m61_blade = RDK->getItem("2084M61");
this->i_2084m61_cup = RDK->getItem("2084M61 VPA TOOL B 10-22-19");
//Pointer to Reference Frames
this->r_input_tray = RDK->getItem("M61 Input Tray");
this->r_input_tray_active = RDK->getItem("Active Input Bin");
this->r_output_tray = RDK->getItem("M61 Output Tray");
this->r_output_tray_active = RDK->getItem("Active Output Bin");
this->r_stationary_gripper = RDK->getItem("Stationary Gripper");
//Pointer to Standby Positions
this->p_home = RDK->getItem("Home");
this->p_input_cup_standby = RDK->getItem("Input Cup Standby");
this->p_input_blade_standby = RDK->getItem("Input Standby");
this->p_output_blade_standby = RDK->getItem("Output Standby");
this->p_stationary_cup_standby = RDK->getItem("Stationary Cup Standby");
this->p_stationary_blade_standby = RDK->getItem("Stationary Blade Standby");
//Pointer to Tray Cup Targets
this->p_tray_cup_0 = RDK->getItem("Cup Pick 0");
this->p_tray_cup_1 = RDK->getItem("Cup Pick 1");
this->p_tray_cup_2 = RDK->getItem("Cup Pick 2");
//Pointer to Tray Blade Targets
this->p_tray_blade_0 = RDK->getItem("Blade Pick 0");
this->p_tray_blade_1 = RDK->getItem("Blade Pick 1");
this->p_tray_blade_2 = RDK->getItem("Blade Pick 2");
//Pointer to Stationary Gripper Cup Targets
this->p_stationary_cup_0 = RDK->getItem("Stationary Cup 0");
this->p_stationary_cup_1 = RDK->getItem("Stationary Cup 1");
this->p_stationary_cup_2 = RDK->getItem("Statopmaru Cup 2");
//Pointer to Stationary Gripper Blade Targets
this->p_stationary_blade_0 = RDK->getItem("Stationary Blade 0");
this->p_stationary_blade_1 = RDK->getItem("Stationary Blade 1");
this->p_stationary_blade_2 = RDK->getItem("Stationary Blade 2");
//Pointer to Blast Joint targets
this->p_blast_position = RDK->getItem("Blast Position");
this->p_blast_position_finish = RDK->getItem("Blast Position Finish");
//Pointer to Display Tools
this->t_cup_closed_airfoil_closed = RDK->getItem("DGATC Cup Closed Airfoil Closed");
this->t_cup_closed_airfoil_open = RDK->getItem("DGATC Cup Closed Airfoil Open");
this->t_cup_open_airfoil_closed = RDK->getItem("DGATC Cup Open Airfoil Closed");
this->t_cup_open_airfoil_open = RDK->getItem("DGATC Cup Open Airfoil Open");
this->t_stationary_gripper_closed = RDK->getItem("Stationary Gripper Closed");
this->t_stationary_gripper_open = RDK->getItem("Stationary Gripper Open");
//Pointer to Active Tools
this->t_airfoil_tool = RDK->getItem("Airfoil Tool");
this->t_cup_tool = RDK->getItem("Cup Tool");
//Program Variables
this->current_part = 0;
this->part_count = 0;
this->part_count_x = 1;
this->part_count_y = 1;
}
UR10Simulate::~UR10Simulate(){
}
//Method Name: SetTraySize
//Goals: Establish Size of Tray
//Input: int x_size, int y_size, int count
//Output: None
//Steps: Set part_count_x, part_count_y, and part_count equal to inputs
void UR10Simulate::SetTraySize(int x_size, int y_size, int count){
this->part_count_x = x_size;
this->part_count_y = y_size;
this->part_count = count;
}
//Method Name:
//Goals:
//Input:
//Output:
//Steps:
void UR10Simulate::GenerateObjects(){
}
//Method Name:
//Goals:
//Input:
//Output:
//Steps:
void UR10Simulate::ClearObjects(){
}
//Method Name:
//Goals:
//Input:
//Output:
//Steps:
void UR10Simulate::MoveActiveReferenceFrames(){
}
//Method Name:
//Goals:
//Input:
//Output:
//Steps:
void UR10Simulate::RunProgram(){
if(RDK->Connected()){
RDK->setSimulationSpeed(1.0);
//Reset object displays and active tool
t_cup_open_airfoil_open.setVisible(true);
t_cup_closed_airfoil_open.setVisible(false);
t_cup_open_airfoil_closed.setVisible(false);
t_cup_closed_airfoil_closed.setVisible(false);
t_stationary_gripper_open.setVisible(true);
t_stationary_gripper_closed.setVisible(false);
active_robot.setPoseTool(t_cup_tool);
//Move Home
//active_robot.setSpeed(100, 1200, 30, 80);
active_robot.setRounding(20);
//active_robot.MoveJ(p_home);
//For each part, do the following
//while(current_part < part_count){
//Move to input area to pick cup-blade assembly
active_robot.setPoseTool(t_cup_tool);
active_robot.setPoseFrame(r_input_tray_active);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_input_blade_standby);
active_robot.MoveJ(p_input_cup_standby);
active_robot.MoveJ(p_tray_cup_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_tray_cup_1);
//active_robot.setSpeed(100, 600, 60, 80);
active_robot.MoveL(p_tray_cup_0);
//Pick Cup-Blade assembly from input tray
active_robot.Pause(0.25);
t_cup_open_airfoil_open.setVisible(false);
t_cup_closed_airfoil_open.setVisible(true);
active_robot.Pause(0.25);
//Move back to Input Cup Standby area
active_robot.MoveL(p_tray_cup_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_tray_cup_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_input_cup_standby);
//Move to Stationary gripper to transfer cup-blade assembly
active_robot.setPoseFrame(r_stationary_gripper);
active_robot.MoveJ(p_stationary_cup_standby);
active_robot.MoveJ(p_stationary_cup_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_stationary_cup_1);
active_robot.MoveL(p_stationary_cup_0);
//Transfer Cup-Blade assembly to stationary gripper
active_robot.Pause(0.25);
t_cup_open_airfoil_open.setVisible(true);
t_cup_closed_airfoil_open.setVisible(false);
t_stationary_gripper_open.setVisible(false);
t_stationary_gripper_closed.setVisible(true);
active_robot.Pause(0.25);
//Move to stationary blade standby position
active_robot.MoveL(p_stationary_cup_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_stationary_cup_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_stationary_cup_standby);
//Move to stationary blade picking position
active_robot.setPoseTool(t_airfoil_tool);
active_robot.MoveJ(p_stationary_blade_standby);
active_robot.MoveJ(p_stationary_blade_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_stationary_blade_1);
active_robot.MoveL(p_stationary_blade_0);
//Pull Blade from Cup-Blade assembly
active_robot.Pause(0.25);
t_cup_open_airfoil_open.setVisible(false);
t_cup_open_airfoil_closed.setVisible(true);
active_robot.Pause(0.25);
//Move to stationary blade standby position
active_robot.MoveL(p_stationary_blade_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_stationary_blade_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_stationary_blade_standby);
//Clean Blade
active_robot.setRounding(0);
active_robot.MoveJ(p_blast_position);
active_robot.Pause(1);
active_robot.setSpeed(300, 1200, 18, 80);
active_robot.MoveJ(p_blast_position_finish);
//active_robot.setRounding(20);
//Move back to stationary blade standby position
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_stationary_blade_standby);
//Move to stationary cup position
active_robot.setPoseTool(t_cup_tool);
active_robot.MoveJ(p_stationary_cup_standby);
active_robot.MoveJ(p_stationary_cup_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_stationary_cup_1);
active_robot.MoveL(p_stationary_cup_0);
//Pick cup from stationary gripper
active_robot.Pause(0.25);
t_cup_open_airfoil_closed.setVisible(false);
t_cup_closed_airfoil_closed.setVisible(true);
t_stationary_gripper_open.setVisible(true);
t_stationary_gripper_closed.setVisible(false);
active_robot.Pause(0.25);
//Move to stationary cup standby position
active_robot.MoveL(p_stationary_cup_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_stationary_cup_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_stationary_cup_standby);
//Move to input tray cup position again to place cup back into input tray
active_robot.setPoseFrame(r_input_tray_active);
active_robot.MoveJ(p_input_cup_standby);
active_robot.MoveJ(p_tray_cup_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_tray_cup_1);
active_robot.MoveL(p_tray_cup_0);
//Place cup in input tray
active_robot.Pause(0.25);
t_cup_closed_airfoil_closed.setVisible(false);
t_cup_open_airfoil_closed.setVisible(true);
active_robot.Pause(0.25);
//Move to input blade standby position
active_robot.MoveL(p_tray_cup_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_tray_cup_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_input_cup_standby);
active_robot.MoveJ(p_input_blade_standby);
//Move to output blade place position
active_robot.setPoseTool(t_airfoil_tool);
active_robot.setPoseFrame(r_output_tray_active);
active_robot.MoveJ(p_tray_blade_2);
active_robot.setSpeed(100, 1200, 120, 80);
active_robot.MoveL(p_tray_blade_1);
active_robot.MoveL(p_tray_blade_0);
//Place blade in output tray
active_robot.Pause(0.25);
t_cup_open_airfoil_closed.setVisible(false);
t_cup_open_airfoil_open.setVisible(true);
active_robot.Pause(0.25);
//Move to output blade standby postion
active_robot.MoveL(p_tray_blade_1);
//active_robot.setSpeed(300, 600, 60, 80);
active_robot.MoveL(p_tray_blade_2);
active_robot.setSpeed(600, 1200, 120, 80);
active_robot.MoveJ(p_output_blade_standby);
//}
//Move back to Home
//active_robot.setSpeed(100, 1200, 30, 80);
//active_robot.setRounding(20);
//active_robot.MoveJ(p_home);
}
}
//Method Name:
//Goals:
//Input:
//Output:
//Steps:
|