RoboDK Plug-In Interface
pluginexample.cpp
1#include "pluginexample.h"
2#include "robodktools.h"
3#include "irobodk.h"
4#include "iitem.h"
5
6#include "formrobotpilot.h"
7
8#include <QMainWindow>
9#include <QToolBar>
10#include <QDebug>
11#include <QAction>
12#include <QStatusBar>
13#include <QMenuBar>
14#include <QTextEdit>
15#include <QDateTime>
16#include <QIcon>
17#include <QDesktopServices>
18
19//------------------------------- RoboDK Plug-in commands ------------------------------
20
21
23 return "Example Plugin";
24}
25
26
27QString PluginExample::PluginLoad(QMainWindow *mw, QMenuBar *menubar, QStatusBar *statusbar, RoboDK *rdk, const QString &settings){
28 RDK = rdk;
29 MainWindow = mw;
30 StatusBar = statusbar;
31 qDebug() << "Loading plugin " << PluginName();
32 qDebug() << "Using settings: " << settings; // reserved for future compatibility
33
34 // it is highly recommended to use the statusbar for debugging purposes (pass /DEBUG as an argument to see debug result in RoboDK)
35 qDebug() << "Setting up the status bar";
36 StatusBar->showMessage(tr("RoboDK Plugin %1 is being loaded").arg(PluginName()));
37
38 // initialize resources for the plugin (if required):
39 Q_INIT_RESOURCE(resources1);
40
41 // Here you can add all the "Actions": these actions are callbacks from buttons selected from the menu or the toolbar
42 action_information = new QAction(QIcon(":/resources/information.png"), tr("Plugin Speed Information"));
43 action_robotpilot = new QAction(QIcon(":/resources/code.png"), tr("Robot Pilot Form"));
44 action_help = new QAction(QIcon(":/resources/help.png"), tr("RoboDK Plugins - Help"));
45 // Make sure to connect the action to your callback (slot)
46 connect(action_information, SIGNAL(triggered()), this, SLOT(callback_information()), Qt::QueuedConnection);
47 connect(action_robotpilot, SIGNAL(triggered()), this, SLOT(callback_robotpilot()), Qt::QueuedConnection);
48 connect(action_help, SIGNAL(triggered()), this, SLOT(callback_help()), Qt::QueuedConnection);
49
50 // Here you can add one or more actions in the menu
51 menu1 = menubar->addMenu("Plugin Example Menu");
52 qDebug() << "Setting up the menu bar";
53 menu1->addAction(action_information);
54 menu1->addAction(action_robotpilot);
55 menu1->addAction(action_help);
56
57 // Important: reset the robot pilot dock/form pointer so that it is created the first time
58 dock_robotpilot = nullptr;
59 form_robotpilot = nullptr;
60
61 // return string is reserverd for future compatibility
62 return "";
63};
64
65
67 // Cleanup the plugin
68 qDebug() << "Unloading plugin " << PluginName();
69
70 // remove the menu
71 menu1->deleteLater();
72 menu1 = nullptr;
73 // remove the toolbar
74 toolbar1->deleteLater();
75 toolbar1 = nullptr;
76
77 if (dock_robotpilot != nullptr){
78 dock_robotpilot->close();
79 dock_robotpilot = nullptr;
80 form_robotpilot = nullptr;
81 }
82
83 // remove resources
84 Q_CLEANUP_RESOURCE(resources1);
85}
86
87void PluginExample::PluginLoadToolbar(QMainWindow *mw, int icon_size){
88 // Create a new toolbar:
89 toolbar1 = mw->addToolBar("Plugin Example Toolbar");
90 toolbar1->setIconSize(QSize(icon_size, icon_size));
91
92 // Important: It is highly recommended to set an object name on toolbars. This allows saving the preferred location of the toolbar by the user
93 toolbar1->setObjectName(PluginName() + "-Toolbar1");
94
95 // Add a new button to the toolbar
96 toolbar1->addAction(action_information);
97 toolbar1->addAction(action_robotpilot);
98 toolbar1->addAction(action_help);
99}
100
101
102bool PluginExample::PluginItemClick(Item item, QMenu *menu, TypeClick click_type){
103 qDebug() << "Selected item: " << item->Name() << " of type " << item->Type() << " click type: " << click_type;
104
105 if (item->Type() == IItem::ITEM_TYPE_OBJECT){
106 //menu->actions().insert(0, action_btn1); // add action at the beginning
107 menu->addAction(action_information); // add action at the end
108 qDebug() << "Done";
109 return true;
110 } else if (item->Type() == IItem::ITEM_TYPE_ROBOT){
111 //menu->actions().insert(0, action_robotpilot); // add action at the beginning
112 menu->addAction(action_robotpilot); // add action at the end
113 qDebug() << "Done";
114 return true;
115 }
116 return false;
117}
118
119QString PluginExample::PluginCommand(const QString &command, const QString &value){
120 qDebug() << "Sent command: " << command << " With value: " << value;
121 if (command.compare("Information", Qt::CaseInsensitive) == 0){
123 return "Done";
124 } else if (command.compare("RobotPilot", Qt::CaseInsensitive) == 0){
126 return "Done";
127 }
128
129 return "";
130}
131
133 switch (event_type) {
134 case EventRender:
137 //qDebug() << "(EventRender)";
138 break;
139 case EventMoved:
143 break;
144 case EventChanged:
148
150 //if (RDK->getActiveStation() != STATION){
151 // SetDefaultSettings();
152 // STATION = RDK->getActiveStation();
153 // LoadSettings(); // will select the robot if there are settings.
154 //}
155 qDebug() << "==== EventChanged ====";
156 if (form_robotpilot != nullptr){
158 }
159 break;
160 case EventAbout2Save:
161 qDebug() << "==== EventAbout2Save ====";
164 //SaveSettings();
165 break;
168 qDebug() << "==== EventAbout2ChangeStation ====";
169 //SaveSettings();
170 break;
173 qDebug() << "==== EventAbout2CloseStation ====";
174 //SaveSettings();
175 //ROBOT = nullptr;
176 break;
177 default:
178 qDebug() << "Unknown/future event: " << event_type;
179
180 }
181}
182
183//----------------------------------------------------------------------------------
184// Define your own button callbacks here
185
187
188 // Perform some timing tests using the RoboDK API
189 RDK->ShowMessage("Starting timing tests", false);
190 QString text_message_html("<strong>Plugin Timing Tests Summary on " + QDateTime::currentDateTime().toString(Qt::SystemLocaleLongDate) + ":</strong><br>");
191
192 int ntests=10000;
193 //Item robot = RDK->getItem("", IItem::ITEM_TYPE_ROBOT);
194 Item robot = RDK->ItemUserPick("Pick a robot", IItem::ITEM_TYPE_ROBOT);
195 if (ItemValid(robot)){
196 Mat pose_fk;
197 tJoints joints_ik;
198 QList<tJoints> joints_ik_all;
199 qint64 tstart;
200 qint64 tend;
201
202 text_message_html += + "<br>" + QString("Using robot %1").arg(robot->Name());
203
204 // Test Forward Kinematics
205 tstart = QDateTime::currentMSecsSinceEpoch();
206 for (int i=0; i<ntests; i++){
207 pose_fk = robot->SolveFK(robot->Joints());
208 }
209 tend = QDateTime::currentMSecsSinceEpoch();
210 text_message_html += + "<br>" + QString("Forward Kinematics: %1 micro seconds").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
211
212 // Test Inverse Kinematics
213 tstart = QDateTime::currentMSecsSinceEpoch();
214 for (int i=0; i<ntests; i++){
215 joints_ik = robot->SolveIK(pose_fk);
216 }
217 tend = QDateTime::currentMSecsSinceEpoch();
218 text_message_html += "<br>" + QString("Inverse Kinematics: %1 micro seconds").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
219
220 // Test Forward Kinematics
221 tstart = QDateTime::currentMSecsSinceEpoch();
222 for (int i=0; i<ntests; i++){
223 joints_ik_all = robot->SolveIK_All(pose_fk);
224 }
225 tend = QDateTime::currentMSecsSinceEpoch();
226 text_message_html += "<br>" + QString("Inverse Kinematics: %1 micro seconds (all solutions)").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
227 } else {
228 text_message_html += + "<br>No robot available to run Kinematic tests";
229 }
230
231
232 // output through debug console
233 qDebug() << text_message_html;
234
235
236 RDK->ShowMessage("Retrieving all station items", false);
237 QStringList item_list_names = RDK->getItemListNames();
238 qDebug() << "Available items in the current station: " << item_list_names;
239
240 QList<Item> item_list = RDK->getItemList();
241
242 RDK->ShowMessage("Displaying list of station items", false);
243 text_message_html += QString("<br>Open station <strong>%1</strong> items:").arg(RDK->getActiveStation()->Name());
244 foreach (Item itm, item_list){
245 Item item_parent = itm->Parent();
246 if (!ItemValid(item_parent)){
247 // station items do not have a parent
248 text_message_html += QString("<br>%1 (station)").arg(itm->Name());
249 } else {
250 text_message_html += QString("<br>%1 -> <i>parent: %2</i>").arg(itm->Name()).arg(item_parent->Name());
251 }
252
253 }
254
255
256 QTextEdit *text_editor = new QTextEdit("Plugin timing summary");
257 QDockWidget *dockwidget = AddDockWidget(MainWindow, text_editor, "Dock Plugin timing summary");
258 text_editor->setHtml(text_message_html);
259 //text_editor->show();
260
261 // close the dock:
262 //dockwidget->close();
263
264}
265
267 if (dock_robotpilot != nullptr){
268 // prevent opening more than 1 form
269 RDK->ShowMessage("Robot pilot form is already open", false);
270 return;
271 }
272 RDK->ShowMessage("Opening robot pilot form...", false);
274 dock_robotpilot = AddDockWidget(MainWindow, form_robotpilot, "Robot Pilot");
275 connect(form_robotpilot, SIGNAL(destroyed()), this, SLOT(callback_robotpilot_closed()));
276}
278 // it is important to reset pointers when the form is closed (deleted)
279 dock_robotpilot = nullptr;
280 form_robotpilot = nullptr;
281 RDK->ShowMessage("Closed robot pilot", false);
282}
284 QDesktopServices::openUrl(QUrl("https://robodk.com/CreatePlugin"));
285}
286
287
bool SelectRobot()
Select a robot in the Robot variable.
TypeEvent
Event types for PluginEvent function.
Definition: iapprobodk.h:212
@ EventAbout2ChangeStation
The current RoboDK station is about to loose focus because the user requested to open a new station (...
Definition: iapprobodk.h:233
@ EventAbout2Save
Definition: iapprobodk.h:230
@ EventAbout2CloseStation
Definition: iapprobodk.h:237
@ EventMoved
Moved event: Something has moved, such as a robot, reference frame, object or tool....
Definition: iapprobodk.h:219
virtual QString PluginName()=0
Return the plugin name. Try to be creative and make sure the name is unique.
TypeClick
Types of clicks for PluginItemClick function.
Definition: iapprobodk.h:193
The Item class represents an item in RoboDK station. An item can be a robot, a frame,...
Definition: iitem.h:14
@ ITEM_TYPE_ROBOT
Item of type robot (.robot file)
Definition: iitem.h:26
@ ITEM_TYPE_OBJECT
Item of type object (.stl, .step or .iges for example)
Definition: iitem.h:35
virtual int Type()=0
Item type (object, robot, tool, reference, robot machining project, ...)
virtual tJoints SolveIK(const Mat &pose, const tJoints *joints_close=nullptr, const Mat *tool_pose=nullptr, const Mat *reference_pose=nullptr)=0
Computes the inverse kinematics for the specified robot and pose. The joints returned are the closest...
virtual QString Name()=0
Returns the name of an item. The name of the item is always displayed in the RoboDK station tree
virtual Mat SolveFK(const tJoints &joints, const Mat *tool_pose=nullptr, const Mat *reference_pose=nullptr)=0
Computes the forward kinematics of the robot for the provided joints. The tool and the reference fram...
virtual Item Parent()=0
Return the parent item of this item
virtual QList< tJoints > SolveIK_All(const Mat &pose, const Mat *tool_pose=nullptr, const Mat *reference_pose=nullptr)=0
Computes the inverse kinematics for the specified robot and pose. The function returns all available ...
virtual tJoints Joints()=0
Returns the current joints of a robot or the joints of a target. If the item is a cartesian target,...
This class is the iterface to the RoboDK API. With the RoboDK API you can automate certain tasks and ...
Definition: irobodk.h:14
virtual Item ItemUserPick(const QString &message="Pick one item", int itemtype=-1)=0
Shows a RoboDK popup to select one object from the open RoboDK station. An item type can be specified...
virtual void ShowMessage(const QString &message, bool popup=true)=0
Show a message in RoboDK (it can be blocking or non blocking in the status bar)
virtual Item getActiveStation()=0
Returns the active station item (station currently visible).
virtual QStringList getItemListNames(int filter=-1)=0
Returns a list of items (list of names or Items) of all available items in the currently open station...
virtual QList< Item > getItemList(int filter=-1)=0
Returns a list of items (list of names or pointers) of all available items in the currently open stat...
The Mat class represents a 4x4 pose matrix. The main purpose of this object is to represent a pose in...
Definition: robodktypes.h:361
virtual void PluginEvent(TypeEvent event_type) override
This function is called every time there is a new RoboDK event such as rendering the screen,...
void callback_information()
Called when the information button/action is selected.
QDockWidget * dock_robotpilot
Pointer to the docked window.
Definition: pluginexample.h:89
void callback_robotpilot()
Called when the robot pilot button/action is selected.
FormRobotPilot * form_robotpilot
Pointer to the robot pilot form.
Definition: pluginexample.h:92
QToolBar * toolbar1
Pointer to the customized toolbar.
Definition: pluginexample.h:74
void callback_help()
Called when the user select the button/action for help.
virtual void PluginUnload() override
This function is called once only when the plugin is being unloaded.
QMainWindow * MainWindow
RoboDK's main window pointer.
Definition: pluginexample.h:48
QStatusBar * StatusBar
RoboDK's main status bar pointer.
Definition: pluginexample.h:51
void callback_robotpilot_closed()
Called when the robot pilot window is closed (event triggered by the dock window)
QAction * action_robotpilot
Open robot pilot form action. callback_robotpilot is triggered with this action. Actions are required...
Definition: pluginexample.h:83
QMenu * menu1
Pointer to the customized menu.
Definition: pluginexample.h:77
RoboDK * RDK
Pointer to the RoboDK API interface.
Definition: pluginexample.h:54
virtual QString PluginCommand(const QString &command, const QString &value) override
Specific commands can be passed from the RoboDK API. For example, a parent application can rely on a ...
virtual bool PluginItemClick(Item item, QMenu *menu, TypeClick click_type) override
This function is called every time a new context menu is created for an item.
QAction * action_help
Open help action. callback_help is triggered with this action. Actions are required to populate toolb...
Definition: pluginexample.h:86
virtual Q_PLUGIN_METADATA(IID "RoboDK.IAppRoboDK") public QString PluginLoad(QMainWindow *mw, QMenuBar *menubar, QStatusBar *statusbar, RoboDK *rdk, const QString &settings="") override
Load the plugin. This function is called only once when the plugin is loaded (or RoboDK is started wi...
virtual void PluginLoadToolbar(QMainWindow *mw, int icon_size) override
This function is called every time the toolbar is set up. This function is called at least once right...
QAction * action_information
Information action. callback_information is triggered with this action. Actions are required to popul...
Definition: pluginexample.h:80
The tJoints class represents a joint position of a robot (robot axes).
Definition: robodktypes.h:239