Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import rospy
00020 import os
00021 import time
00022
00023 from roslib.packages import get_pkg_dir
00024 from xml.etree import ElementTree
00025
00026 from python_qt_binding.QtGui import *
00027 from python_qt_binding.QtCore import *
00028
00029 from python_qt_binding import loadUi
00030
00031 from airbus_pyqt_extend.QtAgiCore import get_pkg_dir_from_prefix
00032
00033 from context import Context
00034
00035 from plugin.plugin_provider import PluginProvider, PluginsGroup
00036 from dashboard import DashboardProvider
00037
00038 from util import CobotGuiException
00039 from emergency import EmergencyStopButton, EmergencyStopState
00040 from diagnostics import DiagnosticsWidget
00041 from account import User, \
00042 Privilege, \
00043 LoginDialog, \
00044 UserAccountsWidget
00045
00046
00047 from airbus_cobot_gui.control_mode import ControlModeWidget, ControlMode
00048 from airbus_cobot_gui.translator import TranslatorUi
00049 from airbus_cobot_gui.timestamp import Timestamp
00050
00051 from alarm import AlarmManagerWidget, Alarm
00052
00053 from std_msgs.msg import String
00054
00055 from airbus_cobot_gui.res import R
00056
00057 class CobotGuiSplash(QSplashScreen):
00058
00059 def __init__(self):
00060 QSplashScreen.__init__(self)
00061
00062
00063 loadUi(R.layouts.welcome, self)
00064
00065 self.setPixmap(R.getPixmapById("wellcome_background").scaled(600, 400,
00066 Qt.KeepAspectRatio,
00067 Qt.SmoothTransformation))
00068
00069 self.loading_progess.setText("Loading ...")
00070
00071 def start(self):
00072 self.show()
00073 self.showMessage(" ")
00074
00075 def update(self, txt):
00076 self.loading_progess.setText("Loading %s ..."%txt)
00077 self.showMessage(" ")
00078
00079
00080
00081 class CobotGuiMain(QWidget):
00082 """! CobotGuiMain class inherit QWidget.
00083 This class setup all graphics components difinit on your config file:
00084 - Setup default rules : Language, size, account, ...
00085 - Setup dashboard : load widgets on dashboard registered in section <dashboard>,
00086 - Setup launchers : load plugins on launchers registered in section <launcher>.
00087 """
00088 APP_MODE_RELEASE = 'release'
00089 APP_MODE_DEBUG = 'debug'
00090
00091 def __init__(self, splash):
00092 """! The constructor.
00093 @param config: Config file (*.xml).
00094 """
00095 QWidget.__init__(self)
00096
00097 loadUi(R.layouts.mainwindow, self)
00098 self.setAttribute(Qt.WA_AcceptTouchEvents)
00099
00100 self._splash = splash
00101 self.display_mode = ''
00102
00103 self._launcher_width = 100
00104 self._dashboard_height = 80
00105
00106
00107 self._default_view = None
00108
00109 self._current_view = None
00110
00111 self._plugins_group_list = []
00112
00113 self._context = Context(self)
00114
00115 self._context.addViewManagerEventListner(self.onManageView)
00116 self._context.addUserConnectionEventListener(self.onUserChanged)
00117 self._context.addControlModeEventListener(self.onControlModeChanged)
00118 self._context.addLanguageEventListner(self.onTranslate)
00119
00120 self._context.addEmergencyStopEventListner(self.onEmergencyStop)
00121
00122 self.setupMinimumTools()
00123
00124 def setupMinimumTools(self):
00125
00126 self.control_mode_widget = ControlModeWidget(self._context)
00127 self.ctrl_layout.addWidget(self.control_mode_widget)
00128
00129 self.user_account = UserAccountsWidget(self._context)
00130 self.user_account.onCreate(None)
00131 self.user_layout.addWidget(self.user_account)
00132
00133 self.timestamp_widget = Timestamp(self._context)
00134 self.timestamp_widget.onCreate(None)
00135 self.user_layout.addWidget(self.timestamp_widget)
00136
00137 self.translator_widget = TranslatorUi(self._context)
00138 self.user_layout.addWidget(self.translator_widget)
00139
00140 self.diagnostic_widget = DiagnosticsWidget(self._context)
00141 self.user_layout.addWidget(self.diagnostic_widget)
00142
00143 self.emergency_stop = EmergencyStopButton(self._context)
00144 self.interruption_layout.addWidget(self.emergency_stop)
00145
00146 self.alarms_manager = AlarmManagerWidget(self._context)
00147 self.alarm_layout.addWidget(self.alarms_manager)
00148
00149
00150 self.logo_label.setPixmap(R.getPixmapById('logo_airbus_group').scaled(
00151 self.logo_label.width()-2,
00152 self.logo_label.height()-2,
00153 Qt.KeepAspectRatio,
00154 Qt.SmoothTransformation))
00155
00156 def setupUserConfig(self, config_xml):
00157 """! Parser xml configuration file.
00158 @param config_xml: airbus_cobot_gui configuration path.
00159 @type config_xml: string.
00160 """
00161
00162
00163 if not os.path.isfile(config_xml):
00164 self._context.getLogger().critical('User config file "%s" not found !'%config_xml)
00165
00166
00167 xconfig = ElementTree.parse(config_xml).getroot()
00168
00169 app_mode = self.APP_MODE_RELEASE
00170
00171 try:
00172 app_mode = xconfig.attrib['mode'].lower()
00173 except:
00174 pass
00175
00176 lng = Context.DEFAULT_LNG
00177
00178 try:
00179 lng = xconfig.find('translate').attrib['type'].lower()
00180 except:
00181 pass
00182
00183 xwindow = xconfig.find('window')
00184
00185 if xwindow is None:
00186 self._context.getLogger().critical('Cannot found "<window>" tag into config file !')
00187 return
00188
00189 try:
00190 self.display_mode = xwindow.attrib['display-mode'].lower()
00191 except:
00192 self.display_mode = ""
00193
00194
00195 for node in xwindow:
00196
00197 if node.tag == 'default-size':
00198
00199 try:
00200 width = int(node.find('width').text)
00201 height = int(node.find('height').text)
00202 self.resize(width, height)
00203 except:
00204 self.resize(1920, 1080)
00205
00206 elif node.tag == 'header':
00207 self.installHeader(node)
00208 elif node.tag == 'launcher':
00209 self.installLauncher(node)
00210 else:
00211 self.getContext().getLogger().warn('Invalid tag "%s" into user configuration !'%node.tag)
00212
00213 self.getContext().switchLanguage(lng)
00214
00215 if app_mode == self.APP_MODE_DEBUG:
00216 self.getContext().switchUser(User('Airbus Group', Privilege.EXPERT))
00217 else:
00218
00219 self.getContext().switchUser(User())
00220 login = LoginDialog(self, False)
00221 QTimer.singleShot(1000, login.show)
00222
00223 def installHeader(self, xheader):
00224 """! Setup all widgets on dashbord registered on config file.
00225 @param tree: node dashbord.
00226 @type tree: ElementTree.
00227 """
00228
00229 for node in xheader:
00230
00231 if node.tag == 'dashboards':
00232
00233 register_dir = node.attrib['src']
00234 register_dir = get_pkg_dir_from_prefix(register_dir)
00235
00236 if not os.path.isfile(register_dir):
00237 self._context.getLogger().critical('Dashboards register file "%s" not found !'%register_dir)
00238 return
00239
00240 dashboard_provider = DashboardProvider(self, register_dir)
00241
00242 for child in node:
00243
00244 if child.tag == 'dashboard':
00245
00246 dashboard_name = child.attrib['name']
00247
00248
00249 self._splash.update(dashboard_name)
00250
00251 try:
00252 dashboard = dashboard_provider.getInstance(dashboard_name, child)
00253
00254 self.dashboard_layout.addWidget(dashboard)
00255
00256 except Exception as ex:
00257 self._context.getLogger().err('Try to provide "%s" instance failed !\n%s'
00258 %(dashboard_name, str(ex)))
00259 continue
00260
00261
00262 def installLauncher(self, xlaunchers):
00263 """! Setup plugins and launcher.
00264 @param xlaunchers: node launcher.
00265 @type xlaunchers: ElementTree.
00266 """
00267
00268 default_plugin_name = ""
00269 default_plugin = None
00270 control_mode = ControlMode.MANUAL
00271
00272 try:
00273 default_plugin_name = xlaunchers.attrib['default-view']
00274 except:
00275 pass
00276
00277 try:
00278 control_mode = ControlMode.TOLEVEL[xlaunchers.attrib['default-mode'].lower()]
00279 except:
00280 self._context.getLogger().warn("Invalid 'default-mode' attribute into config file !")
00281 control_mode = ControlMode.MANUAL
00282
00283 for node in xlaunchers:
00284
00285 if node.tag == 'plugins':
00286
00287 plugins_register_dir = node.attrib['src']
00288 plugins_register_dir = get_pkg_dir_from_prefix(plugins_register_dir)
00289
00290 if not os.path.isfile(plugins_register_dir):
00291 self._context.getLogger().critical('Plugins register file "%s" not found !'%plugins_register_dir)
00292 return
00293
00294 provider = PluginProvider(self, plugins_register_dir)
00295
00296 for xplugin in node:
00297
00298 if xplugin.tag == 'plugin':
00299
00300 plugin_name = xplugin.attrib['name']
00301
00302 self._splash.update(plugin_name)
00303
00304 try:
00305 plugin = provider.getInstance(plugin_name, xplugin)
00306 plugin.tryToPause()
00307
00308 if plugin_name == default_plugin_name:
00309 default_plugin = plugin
00310
00311 self.launcher_layout.addWidget(plugin.getLauncher())
00312
00313 except Exception as ex:
00314 self._context.getLogger().err('Try to provide "%s" instance failed !\n%s'
00315 %(plugin_name, str(ex)))
00316 continue
00317
00318 elif xplugin.tag == 'group':
00319
00320 plugins_group = PluginsGroup(self, xplugin)
00321
00322 for xsubplugin in xplugin:
00323
00324 plugin_name = xsubplugin.attrib['name']
00325 self._splash.update(plugin_name)
00326
00327 try:
00328
00329 plugin = provider.getInstance(plugin_name, xsubplugin)
00330 plugin.tryToPause()
00331
00332 plugins_group.add(plugin.getLauncher())
00333
00334 if plugin_name == default_plugin_name:
00335 default_plugin = plugin
00336
00337 except Exception as ex:
00338 self._context.getLogger().err('Try to provide "%s" instance failed !\n%s'
00339 %(plugin_name, str(ex)))
00340 continue
00341
00342 self.launcher_layout.addWidget(plugins_group)
00343
00344 if default_plugin is not None:
00345 default_plugin.onRequestDisplayView()
00346
00347 self.control_mode_widget.setDefaultMode(control_mode)
00348
00349 def getContext(self):
00350 return self._context
00351
00352 def getDisplayMode(self):
00353 return self.display_mode
00354
00355 def onManageView(self, view):
00356
00357 if self._current_view is not None:
00358 self._current_view.tryToPause()
00359
00360
00361 view.tryToResume()
00362
00363 if self._current_view is not None:
00364
00365 self.viewer.takeWidget()
00366
00367
00368 self.viewer.setWidget(view)
00369
00370 self._current_view = view
00371
00372 def onUserChanged(self, user):
00373
00374 if self._current_view is not None:
00375
00376 if user.getUserPrivilege() == Privilege.NONE:
00377
00378 self.viewer.takeWidget()
00379
00380 elif self._current_view.getLauncher().getAccessRights() > user.getUserPrivilege():
00381
00382 self.viewer.takeWidget()
00383
00384 else:
00385 pass
00386 else:
00387 pass
00388
00389 def onControlModeChanged(self, mode):
00390 pass
00391
00392 def onTranslate(self, lng):
00393 pass
00394
00395 def onEmergencyStop(self, state):
00396 """! Called when emergency stop status changed.
00397 @param status: emergency stop status.
00398 @type status: bool.
00399 """
00400
00401 if state == EmergencyStopState.LOCKED:
00402 self.dashboard_widget.setStyleSheet(R.values.styles.background_estop_locked)
00403 self.logo_label.setStyleSheet(R.values.styles.background_estop_locked)
00404 else:
00405 self.dashboard_widget.setStyleSheet(R.values.styles.background_estop_unlocked)
00406 self.logo_label.setStyleSheet(R.values.styles.background_estop_unlocked)
00407
00408 def resizeEvent(self, event):
00409 """! Resize application.
00410 @param event: event object.
00411 @type event: QEvent.
00412 """
00413 pass
00414
00415 def shutdown(self):
00416 """! This methode call shutdown from all airbus_cobot_gui instances.
00417 """
00418 self._context.requestShutdown()
00419
00420
00421