command_gui_rviz_panel.cpp
Go to the documentation of this file.
00001 #include "cob_command_gui_rviz/command_gui_rviz_panel.h"
00002 
00003 #include <wx/event.h>
00004 #include <XmlRpcValue.h>
00005 
00006 namespace rviz
00007 {       
00008         
00009         //constructor
00010         CommandGuiRvizPanel::CommandGuiRvizPanel(wxWindow *parent, const wxString& title):
00011         wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, title),
00012         planning_enabled(false),
00013         base_diff_enabled(false)
00014         {               
00015                 //try to load button parameters from ROS parameter server
00016                 if(false != Getparams())
00017                 {
00018                         //create graphical user interface
00019                         Creategui();            
00020                 
00021                         //initialze the action client
00022                         action_client_ = new actionlib::SimpleActionClient<cob_script_server::ScriptAction>("cob_command_gui_rviz", true);              
00023                 }
00024                 else
00025                 {
00026                         //no parameter available -> Error message
00027                         statuslabel_ = new wxStaticText(this, wxID_ANY, wxT("\n\tstatus: Error! - parameter does not exist on ROS parameter server! \n\n"));    
00028                 }       
00029         }
00030 
00031         //destructor
00032         CommandGuiRvizPanel::~CommandGuiRvizPanel() 
00033         {
00034         }
00035         
00036         //try to load button parameters from ROS parameter server
00037         bool CommandGuiRvizPanel::Getparams()
00038         {       
00039                 std::string param_prefix = "/control_buttons";          
00040                 
00041                 if(false == (ros::param::has(param_prefix)))
00042                 {
00043                         ROS_DEBUG_ONCE("parameter '%s' does not exist on ROS parameter server, aborting...\n", param_prefix.c_str());                   
00044                         return false;                   
00045                 }
00046                 
00047                 XmlRpc::XmlRpcValue group_param;
00048                 ros::param::get(param_prefix, group_param);
00049                                 
00050                 XmlRpc::XmlRpcValue current_group;
00051                 XmlRpc::XmlRpcValue buttons;
00052                 XmlRpc::XmlRpcValue group_name;
00053                 XmlRpc::XmlRpcValue component_name;
00054                 
00055                 std::string groupkey = "groupx";
00056 
00057                 //create groups
00058                 for(int i = 0; i < group_param.size(); i++)
00059                 {       
00060                         groupkey[5] = (i+'0'+1);  
00061                          
00062                         current_group = group_param[groupkey];
00063                          
00064                         buttons  = current_group["buttons"];
00065                         group_name = current_group["group_name"];
00066                         component_name  = current_group["component_name"];      
00067                         static int id = 101;                                                
00068                          
00069                         Buttonlist current_buttons;     
00070                                          
00071                         // create buttons in group               
00072                         for(int j=0; j < buttons.size(); j++)
00073                         {
00074                                 if(buttons[j][1] == "move")
00075                                 {
00076                                         current_buttons.push_back(Descripe_button(id, buttons[j], component_name));
00077                                 }                               
00078                                 else if(buttons[j][1] == "move_base_rel")
00079                                 {
00080                                         current_buttons.push_back(Descripe_button(id, buttons[j], component_name));
00081                                 }
00082                                 else if(buttons[j][1] == "trigger")
00083                                 {
00084                                         current_buttons.push_back(Descripe_button(id, buttons[j], component_name));
00085                                         
00086                                         if(buttons[j][2] == "stop")
00087                                         {
00088                                                 stop_buttons_.push_back(component_name);
00089                                         }
00090                                         else if(buttons[j][2] == "init")
00091                                         {
00092                                                 init_buttons_.push_back(component_name);
00093                                         }
00094                                         else if(buttons[j][2] == "recover")
00095                                         {
00096                                                 recover_buttons_.push_back(component_name);
00097                                         }
00098                                         
00099                                 }
00100                                 else if(buttons[j][1] == "stop")
00101                                 {
00102                                         current_buttons.push_back(Descripe_button(id, buttons[j], component_name));
00103                                         stop_buttons_.push_back(component_name);
00104                                 }
00105                                 else if(buttons[j][1] == "mode")
00106                                 {
00107                                         current_buttons.push_back(Descripe_button(id, buttons[j], component_name));
00108                                 }
00109                                 else 
00110                                 {
00111                                         std::string fail = buttons[j][1];
00112                                         ROS_DEBUG_ONCE("function %s not known to rviz_movement_buttons panel", fail.c_str());
00113                                 }               
00114                                                 
00115                                 id++;                                                                                            
00116                         }       
00117                         
00118                         
00119                         
00120                         //add nav buttons (optional)            
00121                         if("base" == TostlString(component_name))
00122                         {
00123                                 param_prefix = "/nav_buttons";
00124                                 
00125                                 if(false != (ros::param::has(param_prefix)))
00126                                 {
00127                                         XmlRpc::XmlRpcValue nav_buttons_param;
00128                                         XmlRpc::XmlRpcValue nav_buttons;
00129                                         
00130                                         ros::param::get(param_prefix, nav_buttons_param);
00131                                         
00132                                         nav_buttons = nav_buttons_param["buttons"];
00133                                         
00134                                         for(int k=0; k < nav_buttons.size(); k++)
00135                                         {
00136                                                 current_buttons.push_back(Descripe_button(id, nav_buttons[k], component_name)); 
00137                                                 id++;
00138                                         }
00139                                 } 
00140                                 else
00141                                 {
00142                                         ROS_DEBUG_ONCE("parameter %s does not exist on ROS parameter server, no nav buttons will be available!\n", param_prefix.c_str());               
00143                                 }
00144                         }
00145                         
00146                         groups_.push_back(std::pair<std::string, Buttonlist>(TostlString(group_name),current_buttons));
00147                 }                               
00148                 
00149                 //uniquify lists
00150                 stop_buttons_.unique();
00151                 init_buttons_.unique();
00152                 recover_buttons_.unique();
00153                 
00154                 return true;
00155         }       
00156         
00157         //creates the graphical user interface
00158         void CommandGuiRvizPanel::Creategui()
00159         {       
00160                 //main sizer
00161                 wxSizer *mainsizer = new wxBoxSizer(wxHORIZONTAL);
00162                 
00163                 //create general box
00164                 sizers_.push_back(CreatesbGeneral());
00165                 
00166                 //create boxes and buttons inside them
00167                 for(Grouplist::const_iterator group_ci = groups_.begin(); group_ci != groups_.end(); group_ci++)
00168                 {
00169                         wxSizer *vsizer = new wxStaticBoxSizer(wxVERTICAL, this, TowxString(group_ci->first));
00170                         
00171                         for(Buttonlist::const_iterator button_ci = (group_ci->second).begin(); button_ci != (group_ci->second).end(); button_ci++)
00172                         {                               
00173                                 vsizer->Add(AddButton(button_ci->id, TowxString(button_ci->button_name)), 0, wxEXPAND);         
00174                         }
00175                         
00176                         sizers_.push_back(vsizer);
00177                 }
00178                 
00179                 //add each groupsizer to the mainsizer
00180                 for(unsigned int i = 0; i < sizers_.size(); i++)
00181                 {
00182                         mainsizer->Add(sizers_[i], 1, wxEXPAND);
00183                 }       
00184                 
00185                 mainsizer->SetSizeHints(this);
00186                 this->SetSizerAndFit(mainsizer);
00187         }
00188         
00189         //creates the 'general' box with predefined widgets
00190         wxSizer* CommandGuiRvizPanel::CreatesbGeneral()
00191         {                       
00192                 //widget ids
00193                 const int genids[5] = {001, 002, 003, 004, 005};                
00194                 
00195                 wxSizer *vsizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("general"));
00196                 
00197                 statuslabel_    = new wxStaticText(this, wxID_ANY, wxT("\n Status: OK"));
00198                 cbPlanning_             = new wxCheckBox(this, genids[0], wxT("planning"));
00199                 cbBaseDiff_             = new wxCheckBox(this, genids[1], wxT("base diff"));
00200                 
00201                 wxButton *btnstopall    = new wxButton(this, genids[2], wxT("stop all"), wxDefaultPosition, /*wxDefaultSize*/wxSize(30,29), wxBU_EXACTFIT);
00202                 wxButton *btninitall    = new wxButton(this, genids[3], wxT("init all"), wxDefaultPosition, /*wxDefaultSize*/wxSize(30,29), wxBU_EXACTFIT);
00203                 wxButton *btnrecoverall = new wxButton(this, genids[4], wxT("recover all"), wxDefaultPosition, /*wxDefaultSize*/wxSize(30,29), wxBU_EXACTFIT);          
00204                 
00205                 btnstopall->Enable(true);
00206                 btninitall->Enable(true);       
00207                 btnrecoverall->Enable(true);
00208                 
00209                 //connect checkboxes to event handler
00210                 Connect(genids[0], wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::planned_toggle));
00211                 Connect(genids[1], wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::base_mode_toggle));
00212                 
00213                 //connect buttons to event handler
00214                 Connect(genids[2], wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::OnStopAll));
00215                 Connect(genids[3], wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::OnInitAll));
00216                 Connect(genids[4], wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::OnRecoverAll));
00217 
00218 
00219                 vsizer->Add(statuslabel_, 0, wxEXPAND);
00220                 vsizer->Add(btnstopall, 0, wxEXPAND);
00221                 vsizer->Add(btninitall, 0, wxEXPAND);
00222                 vsizer->Add(btnrecoverall, 0, wxEXPAND);
00223                 
00224                 vsizer->Add(cbPlanning_, 0, wxEXPAND);
00225                 vsizer->Add(cbBaseDiff_, 0, wxEXPAND);  
00226                 
00227                 return vsizer;
00228         }
00229  
00230         //creates a 'Button_Description'
00231         Button_Description CommandGuiRvizPanel::Descripe_button(const int &id, XmlRpc::XmlRpcValue data, const std::string &component_name) const
00232         {
00233                 Button_Description btn;
00234                 
00235                 btn.id = id;
00236                 btn.button_name   = TostlString(data[0]);
00237                 btn.function_name = TostlString(data[1]);
00238                 btn.args.first    = component_name;
00239                 btn.args.second   = TostlString(data[2]);
00240                 
00241         return btn;
00242         }
00243         
00244         //creates a wxButton and connects it to a event-handler
00245         wxButton* CommandGuiRvizPanel::AddButton(const int &id, const wxString &name)
00246         {
00247                 wxButton *but = new wxButton(this, id, name, wxDefaultPosition, wxSize(30,29)/*wxDefaultSize*/, wxBU_EXACTFIT, wxDefaultValidator, name);
00248                 
00249                 but->Enable(true);
00250                 
00251                 Connect(id, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CommandGuiRvizPanel::OnClick));
00252                  
00253                 return but;
00254         }
00255 
00256         //event handler for buttons from the config file on ROS parameter server
00257         void CommandGuiRvizPanel::OnClick(wxCommandEvent& event)
00258         {                               
00259                 Button_Description pressed_button;
00260                 std::string group_name;
00261                 
00262                 pressed_button.id = event.GetId();
00263                 
00264                 //use the button_id to get more information about the pressed button            
00265                 for(Grouplist::const_iterator group_ci = groups_.begin(); group_ci != groups_.end(); group_ci++)
00266                 {
00267                         for(Buttonlist::const_iterator button_ci = group_ci->second.begin(); button_ci != group_ci->second.end(); button_ci++)
00268                         {
00269                                 if((button_ci->id == pressed_button.id))
00270                                 {
00271                                         pressed_button.button_name = button_ci->button_name;
00272                                         pressed_button.function_name = button_ci->function_name;
00273                                         pressed_button.args = button_ci->args;
00274                                         group_name = group_ci->first;
00275                                 }
00276                         }
00277                 }
00278                                 
00279                 ROS_INFO("'%s-%s' clicked", group_name.c_str(), pressed_button.button_name.c_str());
00280                 
00281                 cob_script_server::ScriptGoal goal;
00282                 goal.function_name  = pressed_button.function_name;
00283                 goal.component_name = pressed_button.args.first;
00284                 goal.parameter_name = pressed_button.args.second;
00285                 
00286                 if("arm" == goal.component_name)
00287                 {
00288                         if(false != planning_enabled)
00289                         {
00290                                 goal.mode = "planned";
00291                         }
00292                 }
00293                 
00294                 if("base" == goal.component_name)
00295                 {
00296                         if(false != base_diff_enabled)
00297                         {
00298                                 goal.mode = "diff";
00299                         }       
00300                 }
00301                 
00302                 //fill in goal here
00303                 action_client_->sendGoal(goal);
00304                 action_client_->waitForResult(ros::Duration(1.0));
00305                 if(action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00306                 {
00307                         //set status to 'ok'
00308                         statuslabel_->SetLabel(wxT("\n Status: OK"));
00309                         
00310                         this->GetSizer()->Layout();
00311                 }
00312                 else
00313                 {
00314                         //set status to 'no connection'
00315                         statuslabel_->SetLabel(wxT("\nstatus: \nno connect. to action server!\n\n"));
00316                         
00317                         this->GetSizer()->Layout();
00318                         
00319                         ROS_DEBUG_ONCE("Error! - no connection to action server!\n");
00320                 }
00321                 
00322                 ROS_INFO("current state: %s\n", action_client_->getState().toString().c_str());
00323         }
00324         
00325         //event handler for the 'stop all' button
00326         void CommandGuiRvizPanel::OnStopAll(wxCommandEvent &event)
00327         {
00328                 cob_script_server::ScriptGoal goal;
00329                 bool success = true; 
00330                 
00331                 goal.function_name  = "stop";
00332                 
00333                 ROS_INFO("'stop all' clicked");
00334                 
00335                 for(Stringlist::const_iterator ci = stop_buttons_.begin(); ci != stop_buttons_.end(); ci++)
00336                 {
00337                         goal.component_name = *ci;
00338                         
00339                         action_client_->sendGoal(goal);
00340                         action_client_->waitForResult(ros::Duration(1.0));
00341                     
00342                         if("SUCCEEDED" != action_client_->getState().toString())
00343                         {
00344                                 success = false;
00345                                 ROS_INFO("warning: component %s not properly stopped\n", goal.component_name.c_str());
00346                         }
00347                         
00348                         ROS_INFO("current state: %s\n", action_client_->getState().toString().c_str());
00349                 }
00350                 
00351                 if(false != success)
00352                 { 
00353                         ROS_INFO("all components stopped\n");
00354                         
00355                         statuslabel_->SetLabel(wxT("\n Status: OK"));
00356                         this->GetSizer()->Layout();
00357                 }
00358                 else
00359                 {
00360                         //set status to 'no connection'
00361                         statuslabel_->SetLabel(wxT("\nstatus: \nno connect. to action server!\n\n"));
00362                         
00363                         this->GetSizer()->Layout();
00364                         
00365                         ROS_DEBUG_ONCE("Error! - no connection to action server!\n");
00366                 }
00367         }
00368         
00369         //event handler for the 'init all' button
00370         void CommandGuiRvizPanel::OnInitAll(wxCommandEvent &event)
00371         {
00372                 cob_script_server::ScriptGoal goal;
00373                 bool success = true; 
00374                 
00375                 goal.function_name = "init";
00376                 
00377                 ROS_INFO("'init all' clicked");
00378                 
00379                 for(Stringlist::const_iterator ci = init_buttons_.begin(); ci != init_buttons_.end(); ci++)
00380                 {
00381                         goal.component_name = *ci;
00382                         
00383                         action_client_->sendGoal(goal);
00384                         action_client_->waitForResult(ros::Duration(1.0));
00385                     
00386                         if("SUCCEEDED" != action_client_->getState().toString())
00387                         {
00388                                 success = false;
00389                                 ROS_INFO("warning: component %s not properly initialized\n", goal.component_name.c_str());
00390                         }
00391                         
00392                         ROS_INFO("current state: %s\n", action_client_->getState().toString().c_str());
00393                 }
00394                 
00395                 if(false != success)
00396                 { 
00397                         statuslabel_->SetLabel(wxT("\n Status: OK"));
00398                         this->GetSizer()->Layout();
00399                         
00400                         ROS_INFO("all components initialized\n");
00401                 }
00402                 else
00403                 {
00404                         //set status to 'no connection'
00405                         statuslabel_->SetLabel(wxT("\nstatus: \nno connect. to action server!\n\n"));
00406                         
00407                         this->GetSizer()->Layout();
00408                         
00409                         ROS_DEBUG_ONCE("Error! - no connection to action server!\n");
00410                 }
00411         }
00412         
00413         //event handler for the 'recover all' button
00414         void CommandGuiRvizPanel::OnRecoverAll(wxCommandEvent &event)
00415         {
00416                 cob_script_server::ScriptGoal goal;
00417                 bool success = true; 
00418                 
00419                 goal.function_name = "recover";
00420                 
00421                 ROS_INFO("'recover all' clicked");
00422                 
00423                 for(Stringlist::const_iterator ci = recover_buttons_.begin(); ci != recover_buttons_.end(); ci++)
00424                 {
00425                         goal.component_name = *ci;
00426                         
00427                         action_client_->sendGoal(goal);
00428                         action_client_->waitForResult(ros::Duration(1.0));
00429                         
00430                         if("SUCCEEDED" != action_client_->getState().toString())
00431                         {
00432                                 success = false;
00433                                 ROS_INFO("warning: component %s not properly recovered\n", goal.component_name.c_str());
00434                         }
00435                         
00436                         ROS_INFO("current state: %s\n", action_client_->getState().toString().c_str());
00437                 }
00438                 
00439                 if(false != success)
00440                 { 
00441                         statuslabel_->SetLabel(wxT("\n Status: OK"));
00442                         this->GetSizer()->Layout();
00443                         
00444                         ROS_INFO("all components recovered\n");
00445                 }
00446                 else
00447                 {
00448                         //set status to 'no connection'
00449                         statuslabel_->SetLabel(wxT("\nstatus: \nno connect. to action server!\n\n"));
00450                         
00451                         this->GetSizer()->Layout();
00452                         
00453                         ROS_DEBUG_ONCE("Error! - no connection to action server!\n");
00454                 }
00455         }
00456         
00457         //event handler for the 'planning' checkbox
00458         inline void CommandGuiRvizPanel::planned_toggle(wxCommandEvent &event)
00459         {
00460                 planning_enabled = !planning_enabled;
00461         }
00462         
00463         //event handler for the 'base diff' checkbox
00464         inline void CommandGuiRvizPanel::base_mode_toggle(wxCommandEvent &event)
00465         {
00466                 base_diff_enabled = !base_diff_enabled;
00467         }
00468 
00469         //type casts a std::string into a wxString
00470         inline wxString CommandGuiRvizPanel::TowxString(const std::string &temp) const
00471         {
00472                 return wxString(temp.c_str(), wxConvUTF8);
00473         }
00474         
00475         //type casts a XmlRpcValue of 'typestring' or a wxString into std::string
00476         inline std::string CommandGuiRvizPanel::TostlString(XmlRpc::XmlRpcValue temp) const
00477         {
00478                 return static_cast<std::string>(temp);
00479         }
00480         
00481         //type casts a wxString into std::string
00482         inline std::string CommandGuiRvizPanel::TostlString(wxString temp) const
00483         {
00484                 return std::string(temp.mb_str());
00485         }
00486 
00487 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


cob_command_gui_rviz
Author(s): Jonathan Schwarz
autogenerated on Sun Jan 20 2013 12:37:04