RoboDK Plug-In Interface
Loading...
Searching...
No Matches
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 false;
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 false;
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 {
135 case EventRender:
139 break;
140
141 case EventMoved:
145 break;
146
147 case EventChanged:
151
153 //if (RDK->getActiveStation() != STATION){
154 // SetDefaultSettings();
155 // STATION = RDK->getActiveStation();
156 // LoadSettings(); // will select the robot if there are settings.
157 //}
158 qDebug() << "==== EventChanged ====";
159 if (form_robotpilot != nullptr) {
161 }
162 break;
163
165 qDebug() << "==== EventChangedStation ====";
166
167 if (dock_robotpilot) {
168 dock_robotpilot->close();
169 dock_robotpilot = nullptr;
170 }
171 break;
172
173 case EventAbout2Save:
174 qDebug() << "==== EventAbout2Save ====";
177 //SaveSettings();
178 break;
179
182 qDebug() << "==== EventAbout2ChangeStation ====";
183 //SaveSettings();
184 if (dock_robotpilot) {
185 dock_robotpilot->close();
186 dock_robotpilot = nullptr;
187 }
188 break;
189
192 qDebug() << "==== EventAbout2CloseStation ====";
193 //SaveSettings();
194 //ROBOT = nullptr;
195 if (dock_robotpilot) {
196 dock_robotpilot->close();
197 dock_robotpilot = nullptr;
198 }
199 break;
200
202 qDebug() << "==== EventTrajectoryStep ====";
203 break;
204
205 default:
206 if (event_type < EventApiMask) {
207 qDebug() << "Unknown/future event: " << event_type;
208 return;
209 }
210 break;
211 }
212
213 if (event_type < EventApiMask) {
214 return;
215 }
216
217 int apiEvent = event_type & (EventApiMask - 1);
218
219 // API Events
220 switch (apiEvent)
221 {
222 case EVENT_SELECTIONTREE_CHANGED:
223 qDebug() << "EVENT_SELECTIONTREE_CHANGED";
224 break;
225
226 case EVENT_ITEM_MOVED:
227 qDebug() << "EVENT_ITEM_MOVED";
228 break;
229
230 case EVENT_REFERENCE_PICKED:
231 qDebug() << "EVENT_REFERENCE_PICKED";
232 break;
233
234 case EVENT_REFERENCE_RELEASED:
235 qDebug() << "EVENT_REFERENCE_RELEASED";
236 break;
237
238 case EVENT_TOOL_MODIFIED:
239 qDebug() << "EVENT_TOOL_MODIFIED";
240 break;
241
242 case EVENT_CREATED_ISOCUBE:
243 qDebug() << "EVENT_CREATED_ISOCUBE";
244 break;
245
246 case EVENT_SELECTION3D_CHANGED:
247 qDebug() << "EVENT_SELECTION3D_CHANGED";
248 break;
249
250 case EVENT_VIEWPOSE_CHANGED:
251 qDebug() << "EVENT_VIEWPOSE_CHANGED";
252 break;
253
254 case EVENT_ROBOT_MOVED:
255 qDebug() << "EVENT_ROBOT_MOVED";
256 break;
257
258 case EVENT_KEY:
259 qDebug() << "EVENT_KEY";
260 break;
261
262 case EVENT_ITEM_MOVED_POSE:
263 qDebug() << "EVENT_ITEM_MOVED_POSE";
264 break;
265
266 case EVENT_COLLISIONMAP_RESET:
267 qDebug() << "EVENT_COLLISIONMAP_RESET";
268 break;
269
270 case EVENT_COLLISIONMAP_TOO_LARGE:
271 qDebug() << "EVENT_COLLISIONMAP_TOO_LARGE";
272 break;
273
274 case EVENT_CALIB_MEASUREMENT:
275 qDebug() << "EVENT_CALIB_MEASUREMENT";
276 break;
277
279 qDebug() << "EVENT_SELECTION3D_CLICK";
280 break;
281
282 case EVENT_CHANGED:
283 qDebug() << "EVENT_CHANGED";
284 break;
285
286 case EVENT_RENAME:
287 qDebug() << "EVENT_RENAME";
288 break;
289
290 case EVENT_SETVISIBLE:
291 qDebug() << "EVENT_SETVISIBLE";
292 break;
293
295 qDebug() << "EVENT_STATIONCHANGED";
296 break;
297
299 qDebug() << "EVENT_PROGSLIDER_CHANGED";
300 break;
301
303 qDebug() << "EVENT_PROGSLIDER_SET";
304 break;
305
306 default:
307 qDebug() << "Unknown/future API event: " << apiEvent;
308 break;
309 }
310}
311
312//----------------------------------------------------------------------------------
313// Define your own button callbacks here
314
316
317 // Perform some timing tests using the RoboDK API
318 RDK->ShowMessage("Starting timing tests", false);
319 QString text_message_html("<strong>Plugin Timing Tests Summary on " + QDateTime::currentDateTime().toString() + ":</strong><br>");
320
321 int ntests=10000;
322 //Item robot = RDK->getItem("", IItem::ITEM_TYPE_ROBOT);
323 Item robot = RDK->ItemUserPick("Pick a robot", IItem::ITEM_TYPE_ROBOT);
324 if (ItemValid(robot)){
325 Mat pose_fk;
326 tJoints joints_ik;
327 QList<tJoints> joints_ik_all;
328 qint64 tstart;
329 qint64 tend;
330
331 text_message_html += + "<br>" + QString("Using robot %1").arg(robot->Name());
332
333 // Test Forward Kinematics
334 tstart = QDateTime::currentMSecsSinceEpoch();
335 for (int i=0; i<ntests; i++){
336 pose_fk = robot->SolveFK(robot->Joints());
337 }
338 tend = QDateTime::currentMSecsSinceEpoch();
339 text_message_html += + "<br>" + QString("Forward Kinematics: %1 micro seconds").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
340
341 // Test Inverse Kinematics
342 tstart = QDateTime::currentMSecsSinceEpoch();
343 for (int i=0; i<ntests; i++){
344 joints_ik = robot->SolveIK(pose_fk);
345 }
346 tend = QDateTime::currentMSecsSinceEpoch();
347 text_message_html += "<br>" + QString("Inverse Kinematics: %1 micro seconds").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
348
349 // Test Forward Kinematics
350 tstart = QDateTime::currentMSecsSinceEpoch();
351 for (int i=0; i<ntests; i++){
352 joints_ik_all = robot->SolveIK_All(pose_fk);
353 }
354 tend = QDateTime::currentMSecsSinceEpoch();
355 text_message_html += "<br>" + QString("Inverse Kinematics: %1 micro seconds (all solutions)").arg(((double)(tend-tstart)*1000)/ntests, 0, 'f', 2);
356 } else {
357 text_message_html += + "<br>No robot available to run Kinematic tests";
358 }
359
360
361 // output through debug console
362 qDebug() << text_message_html;
363
364
365 RDK->ShowMessage("Retrieving all station items", false);
366 QStringList item_list_names = RDK->getItemListNames();
367 qDebug() << "Available items in the current station: " << item_list_names;
368
369 QList<Item> item_list = RDK->getItemList();
370
371 RDK->ShowMessage("Displaying list of station items", false);
372 text_message_html += QString("<br>Open station <strong>%1</strong> items:").arg(RDK->getActiveStation()->Name());
373 foreach (Item itm, item_list){
374 Item item_parent = itm->Parent();
375 if (!ItemValid(item_parent)){
376 // station items do not have a parent
377 text_message_html += QString("<br>%1 (station)").arg(itm->Name());
378 } else {
379 text_message_html += QString("<br>%1 -> <i>parent: %2</i>").arg(itm->Name()).arg(item_parent->Name());
380 }
381
382 }
383
384
385 QTextEdit *text_editor = new QTextEdit("Plugin timing summary");
386 text_editor->setHtml(text_message_html);
387
388 AddDockWidget(MainWindow, text_editor, "Dock Plugin timing summary");
389}
390
392 if (dock_robotpilot != nullptr){
393 // prevent opening more than 1 form
394 RDK->ShowMessage("Robot pilot form is already open", false);
395 return;
396 }
397 RDK->ShowMessage("Opening robot pilot form...", false);
399 dock_robotpilot = AddDockWidget(MainWindow, form_robotpilot, "Robot Pilot");
400 connect(form_robotpilot, SIGNAL(destroyed()), this, SLOT(callback_robotpilot_closed()));
401}
403 // it is important to reset pointers when the form is closed (deleted)
404 dock_robotpilot = nullptr;
405 form_robotpilot = nullptr;
406 RDK->ShowMessage("Closed robot pilot", false);
407}
409 QDesktopServices::openUrl(QUrl("https://robodk.com/CreatePlugin"));
410}
411
412
bool SelectRobot()
Select a robot in the Robot variable.
@ EVENT_PROGSLIDER_CHANGED
A program slider was opened, changed, or closed (RoboDK 5.6.4 required).
Definition iapprobodk.h:306
@ EVENT_ITEM_MOVED
Obsolete after RoboDK 4.2.0. Use EVENT_ITEM_MOVED_POSE instead.
Definition iapprobodk.h:274
@ EVENT_PROGSLIDER_SET
The index of a program slider changed (RoboDK 5.6.4 required).
Definition iapprobodk.h:309
@ EVENT_RENAME
The name of an item changed (RoboDK 5.6.3 required).
Definition iapprobodk.h:297
@ EVENT_STATIONCHANGED
A new robodk station was loaded (RoboDK 5.6.3 required).
Definition iapprobodk.h:303
@ EVENT_SETVISIBLE
The visibility state of an item changed (RoboDK 5.6.3 required).
Definition iapprobodk.h:300
@ EVENT_SELECTION3D_CLICK
An object in the 3D view was clicked on (right click, left click or double click),...
Definition iapprobodk.h:290
TypeEvent
Event types for PluginEvent function.
Definition iapprobodk.h:233
@ EventAbout2ChangeStation
The current RoboDK station is about to loose focus because the user requested to open a new station (...
Definition iapprobodk.h:254
@ EventAbout2CloseStation
Definition iapprobodk.h:258
@ EventTrajectoryStep
Definition iapprobodk.h:262
@ EventChangedStation
This event is triggered when we change the active station and a new station gains focus (IRoboDK::get...
Definition iapprobodk.h:247
@ EventMoved
Moved event: Something has moved, such as a robot, reference frame, object or tool....
Definition iapprobodk.h:240
TypeClick
Types of clicks for PluginItemClick function.
Definition iapprobodk.h:214
The Item class represents an item in RoboDK station. An item can be a robot, a frame,...
Definition iitem.h:14
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...
@ 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 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...
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.
void callback_robotpilot()
Called when the robot pilot button/action is selected.
FormRobotPilot * form_robotpilot
Pointer to the robot pilot form.
QToolBar * toolbar1
Pointer to the customized toolbar.
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.
QString PluginName(void) override
Return the plugin name. Try to be creative and make sure the name is unique.
QMainWindow * MainWindow
RoboDK's main window pointer.
QStatusBar * StatusBar
RoboDK's main status bar pointer.
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...
QMenu * menu1
Pointer to the customized menu.
RoboDK * RDK
Pointer to the RoboDK API interface.
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...
virtual 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...
The Joints class represents a joint position of a robot (robot axes).
Definition joints.h:51
The Matrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition matrix4x4.h:70