Fawkes API  Fawkes Development Version
naofawkes_module.cpp
00001 
00002 /***************************************************************************
00003  *  naofawkes_module.cpp - NaoQi module for Fawkes integration
00004  *
00005  *  Created: Thu Jul 03 17:59:29 2008
00006  *  Copyright  2006-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include "naoqi_broker.h"
00024 
00025 #include <baseapp/run.h>
00026 #include <baseapp/main_thread.h>
00027 #include <core/exception.h>
00028 #include <core/threading/thread.h>
00029 #include <plugin/manager.h>
00030 #include <utils/system/dynamic_module/module.h>
00031 
00032 #include <alcore/altypes.h>
00033 #include <alcommon/albroker.h>
00034 #include <alcommon/albrokermanager.h>
00035 #include <alcommon/almodule.h>
00036 #include <alproxies/allauncherproxy.h>
00037 #include <alproxies/alaudioplayerproxy.h>
00038 #include <alproxies/alloggerproxy.h>
00039 
00040 #include <dlfcn.h>
00041 
00042 using namespace std;
00043 
00044 
00045 /** Nao Fawkes Module.
00046  * This module is instantiated in NaoQi and embeds its own Fawkes instance.
00047  */
00048 class NaoFawkesModule : public AL::ALModule
00049 {
00050  public:
00051 
00052   /** Constructor.
00053    * Initializes and starts the embedded Fawkes, and loads the nao plugin
00054    * without precondition.
00055    * @param broker NaoQi broker to use, will be forwarded to the nao plugin
00056    * @param name name of the module (no idea why NaoQi wants to pass it
00057    * as a parameter)
00058    */
00059   NaoFawkesModule(AL::ALPtr<AL::ALBroker> broker, const std::string &name)
00060     : AL::ALModule(broker, name), broker(broker)
00061   {
00062     setModuleDescription("Fawkes integration module");
00063 
00064     AL::ALPtr<AL::ALLoggerProxy> logger = broker->getLoggerProxy();
00065 
00066     try {
00067       logger->info("NaoQiFawkes", "*** Initializing embedded Fawkes");
00068 
00069       // The module flags hack is required because otherwise NaoQi segfaults
00070       // due to problems with boost static initialization after a module
00071       // has been closed once, unfortunately that prevents loading a
00072       // new version of a plugin without a restart.
00073 
00074       fawkes::runtime::InitOptions init_options = 
00075         fawkes::runtime::InitOptions("naofawkes")
00076         .plugin_module_flags(fawkes::Module::MODULE_FLAGS_DEFAULT |
00077                              fawkes::Module::MODULE_NODELETE)
00078         .net_service_name("NaoQi Fawkes on %h")
00079         .loggers("console;syslog:NaoQiFawkes")
00080         .load_plugins("naoqi,webview")
00081         .default_plugin("nao_default");
00082 
00083       if (fawkes::runtime::init(init_options) != 0) {
00084         //throw AL::ALError(name, "ctor", "Initializing Fawkes failed");
00085         logger->info("NaoQiFawkes", "--- Fawkes initialization failed");
00086         play_sound(RESDIR"/sounds/naoshutdown.wav");
00087       } else {
00088 
00089         logger->info("NaoQiFawkes", "*** Starting embedded Fawkes");
00090         fawkes::runtime::main_thread->full_start();
00091         logger->info("NaoQiFawkes", "*** Embedded Fawkes initialization done");
00092         play_sound(RESDIR"/sounds/naostartup.wav");
00093       }
00094     } catch (fawkes::Exception &e) {
00095       std::string message;
00096       for (fawkes::Exception::iterator i = e.begin(); i != e.end(); ++i) {
00097         if (i != e.begin())  message += "\n";
00098         message += *i;
00099       }
00100       logger->info("NaoQiFawkes",
00101                    "--- Fawkes initialization failed, exception follows.");
00102       logger->info("NaoQiFawkes", message);
00103       play_sound(RESDIR"/sounds/naoshutdown.wav");
00104       //throw AL::ALError(name, "ctor", e.what());
00105     }
00106 
00107   }
00108 
00109   /** Destructor.
00110    * Stops the Fawkes main thread and cleans up the embedded Fawkes.
00111    */
00112   virtual ~NaoFawkesModule()
00113   {
00114     fawkes::runtime::main_thread->cancel();
00115     fawkes::runtime::main_thread->join();
00116     fawkes::runtime::cleanup();
00117   }
00118 
00119   /** Play startup sound.
00120    * @param filename name of file to play
00121    */
00122   void
00123   play_sound(const char *filename)
00124   {
00125     // Is the auplayer running ?
00126     try {
00127       AL::ALPtr<AL::ALLauncherProxy> launcher(new AL::ALLauncherProxy(broker));
00128       bool is_auplayer_available = launcher->isModulePresent("ALAudioPlayer");
00129 
00130       if (is_auplayer_available) {
00131         AL::ALPtr<AL::ALAudioPlayerProxy>
00132           auplayer(new AL::ALAudioPlayerProxy(broker));
00133         auplayer->playFile(filename);
00134       }
00135     } catch (AL::ALError& e) {} // ignored
00136   }
00137   private:
00138     AL::ALPtr<AL::ALBroker> broker;
00139 };
00140 
00141 #ifdef __cplusplus
00142 extern "C"
00143 {
00144 #endif
00145 
00146 
00147 int
00148 _createModule(AL::ALPtr<AL::ALBroker> broker)
00149 {      
00150   // init broker with the main broker inctance 
00151   // from the parent executable
00152 
00153   AL::ALPtr<AL::ALLoggerProxy> logger = broker->getLoggerProxy();
00154 
00155   logger->info("NaoQiFawkes", "*** Setting broker stuff");
00156   AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
00157   AL::ALBrokerManager::getInstance()->addBroker(broker);
00158 
00159   fawkes::naoqi::broker = broker;
00160     
00161   // create modules instance
00162   logger->info("NaoQiFawkes", "*** Instantiating Module");
00163   AL::ALModule::createModule<NaoFawkesModule>(broker, "NaoFawkesModule");
00164 
00165   return 0;
00166 }
00167 
00168 int
00169 _closeModule()
00170 {
00171   // Delete module instance
00172   return 0;
00173 }
00174 
00175 # ifdef __cplusplus
00176 }
00177 # endif