$search
00001 00002 /*************************************************************************** 00003 * skiller.cpp - Skiller main application 00004 * 00005 * Created: Tue Aug 3 12:16:10 2010 00006 * Copyright 2010 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. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <ros/ros.h> 00025 00026 #include <lua_utils/context.h> 00027 #include <lua_utils/context_watcher.h> 00028 00029 static int lua_add_watchfile(lua_State *L); 00030 00031 class SkillerMain : public fawkes::LuaContextWatcher 00032 { 00033 friend int lua_add_watchfile(lua_State *L); 00034 public: 00035 SkillerMain(ros::NodeHandle &n, int argc, char **argv) 00036 : __lua(/* watch files */ false, /* tracebacks */ true), 00037 __n(n), __argc(argc), __argv(argv) 00038 { 00039 __lua.add_watcher(this); 00040 } 00041 00042 // for LuaContextWatcher 00043 void 00044 lua_init(fawkes::LuaContext *context) {} 00045 00046 void 00047 lua_finalize(fawkes::LuaContext *context) 00048 { 00049 __lua.get_global("roslua"); // roslua 00050 __lua.get_field(-1, "finalize"); // roslua roslua.finalize 00051 try { 00052 __lua.pcall(); // roslua 00053 } catch (Exception &e) { 00054 printf("Finalize failed: %s", e.what()); 00055 } 00056 __lua.pop(1); // --- 00057 } 00058 00059 void 00060 lua_restarted(fawkes::LuaContext *context) 00061 { 00062 // Restarted will _not_ be called on the very first initialization, because 00063 // the watcher is not yet registered. For each reload, we need to run the 00064 // start script after contexts have been swaped. 00065 __lua.do_file(LUADIR"/skiller/ros/start.lua"); 00066 } 00067 00068 void 00069 init_lua() 00070 { 00071 std::string skill_space = "herb_skills"; 00072 if (__argc == 2) { 00073 skill_space = __argv[1]; 00074 } else if (__n.hasParam("/skiller/skillspace")) { 00075 __n.getParam("/skiller/skillspace", skill_space); 00076 } 00077 00078 __lua.set_cfunction("add_watchfile", lua_add_watchfile); 00079 __lua.add_package_dir(LUADIR); 00080 __lua.add_package("roslua"); 00081 00082 __lua.set_string("SKILLSPACE", skill_space.c_str()); 00083 __lua.set_string("ROS_MASTER_URI", ros::master::getURI().c_str()); 00084 00085 // Cannot do this for proper reloading, calling this manually 00086 //__lua.set_start_script(LUADIR"/skiller/ros/start.lua"); 00087 __lua.do_file(LUADIR"/skiller/ros/start.lua"); 00088 } 00089 00090 int run() 00091 { 00092 init_lua(); 00093 00094 ros::Rate rate(25); 00095 bool quit = false; 00096 // run until skiller stopped 00097 while (! quit && __n.ok() ) { 00098 __lua.get_global("roslua"); // roslua 00099 try { 00100 // Spin! 00101 __lua.get_field(-1, "spin"); // roslua roslua.spin 00102 try { 00103 __lua.pcall(); // roslua 00104 } catch (Exception &e) { 00105 printf("%s", e.what()); 00106 } 00107 00108 // get quite flag 00109 __lua.get_field(-1, "quit"); // roslua roslua.quit 00110 quit = __lua.to_boolean(-1); 00111 __lua.pop(2); // --- 00112 00113 __lua.process_fam_events(); 00114 } catch (Exception &e) { 00115 printf("%s\n", e.what()); 00116 } 00117 rate.sleep(); 00118 } 00119 return 0; 00120 } 00121 00122 private: 00123 fawkes::LuaContext __lua; 00124 ros::NodeHandle &__n; 00125 int __argc; 00126 char **__argv; 00127 }; 00128 00129 static SkillerMain *skiller; 00130 00131 int 00132 lua_add_watchfile(lua_State *L) 00133 { 00134 const char *s = luaL_checkstring(L, 1); 00135 if (s == NULL) luaL_error(L, "Directory argument missing"); 00136 try { 00137 skiller->__lua.add_watchfile(s); 00138 } catch (Exception &e) { 00139 luaL_error(L, "Adding watch directory failed: %s", e.what()); 00140 } 00141 return 0; 00142 } 00143 00144 00145 void 00146 print_usage(const char *program_name) 00147 { 00148 printf("Usage: %s [skill_space]\n\n" 00149 "skill_space is the Lua module name that configures a skill space.\n" 00150 "It defaults to \"herb_skills\". It can also be set via the" 00151 "/skiller/skill_space paramete and rosparam/launch file.\n\n", 00152 program_name); 00153 } 00154 00155 00156 int 00157 main(int argc, char **argv) 00158 { 00159 ros::init(argc, argv, "skillermain"); 00160 ros::NodeHandle n; 00161 00162 if (argc > 2) { 00163 print_usage(argv[0]); 00164 exit(-1); 00165 } 00166 00167 skiller = new SkillerMain(n, argc, argv); 00168 int rv = 0; 00169 try { 00170 rv = skiller->run(); 00171 } catch (Exception &e) { 00172 printf("Running skiller failed: %s\n", e.what()); 00173 rv = -1; 00174 } 00175 delete skiller; 00176 return rv; 00177 }