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