$search
00001 #include <ros/ros.h> 00002 #include <stdio.h> 00003 #include <dirent.h> 00004 #include <stdlib.h> 00005 #include <vector> 00006 #include <string> 00007 using namespace std; 00008 00009 string g_screen_cmd = "screen"; 00010 00011 bool executeCmd(const string & cmd) 00012 { 00013 int ret = system(cmd.c_str()); 00014 if(ret != 0) { 00015 perror("executeCmd"); 00016 ROS_ERROR("Command \"%s\" returned %d", cmd.c_str(), ret); 00017 return false; 00018 } 00019 return true; 00020 } 00021 00022 class ProgramEntry 00023 { 00024 public: 00025 string name; 00026 vector<string> commands; 00027 00028 void pushToScreen() { 00029 ROS_INFO("Creating screen window for \"%s\"", name.c_str()); 00030 if(!executeCmd(g_screen_cmd + " -S ros -X screen -t '" + name + "'")) 00031 return; 00032 for(vector<string>::iterator it = commands.begin(); it != commands.end(); it++) { 00033 ROS_INFO("Pushing command: \"%s\"", it->c_str()); 00034 if(!executeCmd(g_screen_cmd + " -p '" + name + "' -S ros -X eval 'stuff \"" + *it + "\"'")) 00035 return; 00036 } 00037 } 00038 }; 00039 00040 vector<ProgramEntry> programs; 00041 00042 bool load() 00043 { 00044 ros::NodeHandle nh("~"); 00045 00046 XmlRpc::XmlRpcValue xmlRpc; 00047 if(!nh.getParam("programs", xmlRpc)) { 00048 ROS_FATAL("No programs defined."); 00049 return false; 00050 } 00051 00052 if(xmlRpc.getType() != XmlRpc::XmlRpcValue::TypeArray) { 00053 ROS_FATAL("programs param should be a list."); 00054 return false; 00055 } 00056 if(xmlRpc.size() == 0) { 00057 ROS_FATAL("programs list is empty."); 00058 return false; 00059 } 00060 00061 for(int i = 0; i < xmlRpc.size(); i++) { 00062 ProgramEntry pe; 00063 00064 if(xmlRpc[i].getType() != XmlRpc::XmlRpcValue::TypeStruct) { 00065 ROS_FATAL("programs entry %d is not of type string.", i); 00066 return false; 00067 } 00068 pe.name = (string)xmlRpc[i]["name"]; 00069 XmlRpc::XmlRpcValue cmds = xmlRpc[i]["commands"]; 00070 if(cmds.getType() != XmlRpc::XmlRpcValue::TypeArray) { 00071 ROS_FATAL("commands for %s is not a list", pe.name.c_str()); 00072 return false; 00073 } 00074 for(int j = 0; j < cmds.size(); j++) { 00075 pe.commands.push_back((string)cmds[j]); 00076 } 00077 00078 programs.push_back(pe); 00079 } 00080 00081 return true; 00082 } 00083 00084 string getScreenPath() 00085 { 00086 char* user = getenv("USER"); 00087 if(!user) 00088 return ""; 00089 00090 return string("/var/run/screen/S-") + user; 00091 } 00092 00093 bool screenRunning() 00094 { 00095 string sp = getScreenPath(); 00096 if(sp.empty()) 00097 return false; 00098 00099 DIR* dir = opendir(sp.c_str()); 00100 if(!dir) 00101 return false; 00102 struct dirent* entry; 00103 while( (entry = readdir(dir)) ) { 00104 string dname = entry->d_name; 00105 if(dname.find("ros") != string::npos) 00106 return true; 00107 } 00108 return false; 00109 } 00110 00111 int main(int argc, char** argv) 00112 { 00113 ros::init(argc, argv, "screenrun"); 00114 00115 if(argc > 1) { 00116 if(strcmp(argv[1], "b") == 0) { 00117 ROS_INFO("Using byobu for screen."); 00118 g_screen_cmd = "byobu"; 00119 } 00120 } 00121 00122 ros::NodeHandle nh; 00123 00124 if(!load()) 00125 return 1; 00126 00127 if(screenRunning()) { 00128 ROS_WARN("Screen \"ros\" already running, reusing this session"); 00129 } else { 00130 ROS_INFO("Creating screen \"ros\""); 00131 if(!executeCmd(g_screen_cmd + " -S ros -d -m")) { 00132 ROS_FATAL("failed"); 00133 return 1; 00134 } 00135 } 00136 00137 for(vector<ProgramEntry>::iterator it = programs.begin(); it != programs.end(); it++) { 00138 it->pushToScreen(); 00139 } 00140 00141 return 0; 00142 }