airbus_cobot_gui_main.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # Copyright 2015 Airbus
00004 # Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License");
00007 # you may not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 #   http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS,
00014 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 # See the License for the specific language governing permissions and
00016 # limitations under the License.
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 # Minumum ui tools
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         # Extend the widget with all attributes and children from UI file
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 ## @class CobotGuiMain
00080 ## @brief Setup all graphics components (window, plugins, dashboard).
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         # Default components size
00103         self._launcher_width = 100
00104         self._dashboard_height = 80
00105         
00106         # Plugin loaded by default on app boot.
00107         self._default_view = None
00108         # Link current plugin loaded on viewer
00109         self._current_view = None
00110         # Container for plugins group instance
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         #Display Airbus Group logo
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         #Check path from configuration file
00163         if not os.path.isfile(config_xml):
00164             self._context.getLogger().critical('User config file "%s" not found !'%config_xml)
00165         
00166         #Open and parse xml file
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         #Read node window
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             # Load default user none -> open login dialog
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                         #Update splash from display the current dashboard loading
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         # Sets current plugin activity to pause
00357         if self._current_view is not None:
00358             self._current_view.tryToPause()
00359             
00360         # Sets new plugin activity to resume
00361         view.tryToResume()
00362         
00363         if self._current_view is not None:
00364             # Remove current plugin view
00365             self.viewer.takeWidget()
00366             
00367         # Sets new plugin view on viewer
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 #End of file
00421 


airbus_cobot_gui
Author(s): Martin Matignon
autogenerated on Thu Jun 6 2019 17:59:19