cob_teleop.cpp
Go to the documentation of this file.
00001 
00064 #include <cstdlib>
00065 #include <cstdio>
00066 #include <unistd.h>
00067 #include <XmlRpcValue.h>
00068 #include <ros/ros.h>
00069 #include <sensor_msgs/Joy.h>
00070 #include <sensor_msgs/JointState.h>
00071 #include <trajectory_msgs/JointTrajectory.h>
00072 #include <geometry_msgs/Twist.h>
00073 
00074 #include <cob_srvs/Trigger.h>
00075 #include <brics_actuator/JointPositions.h>
00076 #include <brics_actuator/JointVelocities.h>
00077 
00078 const int PUBLISH_FREQ = 100.0;
00079 
00085 class TeleopCOB
00086 {
00087 public:
00088         struct joint_module{
00089                 std::string key;
00090                 std::vector<std::string> joint_names;
00091                 std::vector<double> req_joint_pos_;
00092                 std::vector<double> req_joint_vel_;
00093                 std::vector<double> steps;
00094                 ros::Publisher module_publisher_;
00095                 ros::Publisher module_publisher_brics_;
00096         };
00097 
00098         std::map<std::string,joint_module> joint_modules_; //std::vector<std::string> module_names;
00099 
00100         struct base_module_struct{
00101                 std::vector<double> req_vel_;
00102                 std::vector<double> vel_old_; //,vy_old_,vth_old_;
00103                 std::vector<double> max_vel_; //max_vx_,max_vy_,max_vth_;
00104                 std::vector<double> max_acc_; //max_ax_,max_ay_,max_ath_;
00105                 ros::Publisher base_publisher_;
00106                 ros::Publisher base_safety_publisher_;
00107         } base_module_;
00108 
00109         bool has_base_module_;
00110 
00111         int lower_neck_button_,upper_neck_button_; //buttons
00112         int tray_button_;
00113         int axis_vx_,axis_vy_,axis_vth_;
00114         int arm_joint12_button_;
00115         int arm_joint34_button_;
00116         int arm_joint56_button_;
00117         int arm_joint7_button_;
00118         //signs
00119         int up_down_, left_right_;   //sign for movements of upper_neck and tray
00120 
00121         //common
00122         int deadman_button_, run_button_, base_safety_button_, stop_base_button_, recover_base_button_;
00123         bool joy_active_, stopped_, base_safety_;
00124         double run_factor_, run_factor_param_;
00125 
00126 
00127         ros::NodeHandle n_;
00128         ros::Subscriber joy_sub_;  //subscribe topic joy
00129         ros::Subscriber joint_states_sub_;  //subscribe topic joint_states
00130 
00131         bool got_init_values_;
00132         double time_for_init_;
00133 
00134         struct combined_joints_struct{
00135                 std::vector<std::string> joint_names_;
00136                 std::vector<double> joint_init_values_;
00137                 std::vector<joint_module*> module_ref_;
00138         }combined_joints_;
00139         std::vector<std::string> joint_names_;
00140         std::vector<double> joint_init_values_;
00141 
00142         TeleopCOB();
00143         void getConfigurationFromParameters();
00144         void init();
00145         void joy_cb(const sensor_msgs::Joy::ConstPtr &joy_msg);
00146         void joint_states_cb(const sensor_msgs::JointState::ConstPtr &joint_states_msg);
00147         void update();
00148         void update_joint_modules();
00149         void update_base();
00150         void setInitValues();
00151         ~TeleopCOB();
00152 
00153 private:
00154         bool assign_joint_module(std::string,XmlRpc::XmlRpcValue);
00155         bool assign_base_module(XmlRpc::XmlRpcValue);
00156 };
00157 
00158 void TeleopCOB::getConfigurationFromParameters()
00159 {
00160         //std::map<std::string,joint_module> joint_modules; //std::vector<std::string> module_names;
00161         if(n_.hasParam("modules"))
00162         {
00163                 XmlRpc::XmlRpcValue modules;
00164                 ROS_DEBUG("modules found ");
00165                 n_.getParam("modules", modules);
00166                 if(modules.getType() == XmlRpc::XmlRpcValue::TypeStruct)
00167                 {
00168                         ROS_DEBUG("modules are of type struct with size %d",(int)modules.size());
00169 
00170                         for(std::map<std::string,XmlRpc::XmlRpcValue>::iterator p=modules.begin();p!=modules.end();++p)
00171                         {
00172                                 std::string mod_name = p->first;
00173                                 ROS_DEBUG("module name: %s",mod_name.c_str());
00174                                 XmlRpc::XmlRpcValue mod_struct = p->second;
00175                                 if(mod_struct.getType() != XmlRpc::XmlRpcValue::TypeStruct)
00176                                         ROS_WARN("invalid module, name: %s",mod_name.c_str());
00177                                 // search for joint_name parameter in current module struct to determine which type of module
00178                                 // only joint mods or wheel mods supported
00179                                 // which mens that is no joint names are found, then the module is a wheel module
00180                                 // TODO replace with build in find, but could not get it to work
00181                                 if(!assign_joint_module(mod_name, mod_struct))
00182                                 {
00183                                         // add wheel module struct
00184                                         ROS_DEBUG("wheel module found");
00185                                         assign_base_module(mod_struct);
00186                                 }
00187                         }
00188                 }
00189         }
00190 }
00191 
00203 bool TeleopCOB::assign_joint_module(std::string mod_name, XmlRpc::XmlRpcValue mod_struct)
00204 {
00205         // search for joint_name parameter in current module struct to determine which type of module
00206         // only joint mods or wheel mods supported
00207         // which mens that is no joint names are found, then the module is a wheel module
00208         // TODO replace with build in find, but could not get it to work
00209         bool is_joint_module = false;
00210         joint_module tempModule;
00211         for(std::map<std::string,XmlRpc::XmlRpcValue>::iterator ps=mod_struct.begin();ps!=mod_struct.end();++ps)
00212         {
00213                 std::string par_name = ps->first;
00214                 ROS_DEBUG("par name: %s",par_name.c_str());
00215 
00216                 if(par_name.compare("joint_names")==0)
00217                 {
00218                         ROS_DEBUG("joint names found");
00219                         XmlRpc::XmlRpcValue joint_names = ps->second;
00220 
00221                         ROS_ASSERT(joint_names.getType() == XmlRpc::XmlRpcValue::TypeArray);
00222                         ROS_DEBUG("joint_names.size: %d \n", joint_names.size());
00223                         for(int i=0;i<joint_names.size();i++)
00224                         {
00225                                 ROS_ASSERT(joint_names[i].getType() == XmlRpc::XmlRpcValue::TypeString);
00226                                 std::string s((std::string)joint_names[i]);
00227                                 ROS_DEBUG("joint_name found = %s",s.c_str());
00228                                 tempModule.joint_names.push_back(s);
00229                         }
00230                         // set size of other vectors according to the joint name vector
00231                         tempModule.req_joint_pos_.resize(joint_names.size());
00232                         tempModule.req_joint_vel_.resize(joint_names.size());
00233 
00234                         is_joint_module = true;
00235                         //break; // no need to continue searching if joint names are found
00236                 }else if(par_name.compare("joint_step")==0){
00237                         ROS_DEBUG("joint steps found");
00238                         XmlRpc::XmlRpcValue joint_steps = ps->second;
00239 
00240                         ROS_ASSERT(joint_steps.getType() == XmlRpc::XmlRpcValue::TypeArray);
00241                         ROS_DEBUG("joint_steps.size: %d \n", joint_steps.size());
00242                         for(int i=0;i<joint_steps.size();i++)
00243                         {
00244                                 ROS_ASSERT(joint_steps[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00245                                 double step((double)joint_steps[i]);
00246                                 ROS_DEBUG("joint_step found = %f",step);
00247                                 tempModule.steps.push_back(step);
00248                         }
00249                 }
00250         }
00251         if(is_joint_module)
00252         {
00253                 // assign publisher
00254                 tempModule.module_publisher_ = n_.advertise<trajectory_msgs::JointTrajectory>(("/"+mod_name+"_controller/command"),1);
00255                 tempModule.module_publisher_brics_ = n_.advertise<brics_actuator::JointVelocities>(("/"+mod_name+"_controller/command_vel"),1);
00256                 // store joint module in collection
00257                 ROS_DEBUG("head module stored");
00258                 joint_modules_.insert(std::pair<std::string,joint_module>(mod_name,tempModule));
00259         }
00260         return is_joint_module;
00261 }
00273 bool TeleopCOB::assign_base_module(XmlRpc::XmlRpcValue mod_struct)
00274 {
00275         for(std::map<std::string,XmlRpc::XmlRpcValue>::iterator ps=mod_struct.begin();ps!=mod_struct.end();++ps)
00276         {
00277                 std::string par_name = ps->first;
00278                 ROS_DEBUG("par name: %s",par_name.c_str());
00279 
00280                 if(par_name.compare("max_velocity")==0)
00281                 {
00282                         ROS_DEBUG("max vel found");
00283                         XmlRpc::XmlRpcValue max_vel = ps->second;
00284 
00285                         ROS_ASSERT(max_vel.getType() == XmlRpc::XmlRpcValue::TypeArray);
00286                         if(max_vel.size()!=3){ROS_WARN("invalid base parameter size");}
00287                         ROS_DEBUG("max_vel.size: %d \n", max_vel.size());
00288                         for(int i=0;i<max_vel.size();i++)
00289                         {
00290                                 ROS_ASSERT(max_vel[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00291                                 double val = (double)max_vel[i];
00292                                 ROS_DEBUG("max vel value = %f",val);
00293                                 base_module_.max_vel_.push_back(val);
00294                         }
00295                 }
00296                 else if(par_name.compare("max_acceleration")==0)
00297                 {
00298                         ROS_DEBUG("max acc found");
00299                         XmlRpc::XmlRpcValue max_acc = ps->second;
00300 
00301                         ROS_ASSERT(max_acc.getType() == XmlRpc::XmlRpcValue::TypeArray);
00302                         if(max_acc.size()!=3){ROS_DEBUG("invalid base parameter size");}
00303                         ROS_DEBUG("max_acc.size: %d \n", max_acc.size());
00304                         for(int i=0;i<max_acc.size();i++)
00305                         {
00306                                 ROS_ASSERT(max_acc[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00307                                 double val = (double)max_acc[i];
00308                                 ROS_DEBUG("max acc value = %f", val);
00309                                 base_module_.max_acc_.push_back(val);
00310                         }
00311                 }
00312                 else
00313                 {
00314                         ROS_WARN("unsupported base module parameter read");
00315                 }
00316         }
00317         // make all the vectors the same length
00318         // the vector size is not completely safe since only warning is
00319         // issued if max value arrays has the wrong length
00320         base_module_.req_vel_.resize(base_module_.max_acc_.size());
00321         base_module_.vel_old_.resize(base_module_.max_acc_.size());
00322         base_module_.base_publisher_ = n_.advertise<geometry_msgs::Twist>("/cmd_vel",1);
00323         base_module_.base_safety_publisher_ = n_.advertise<geometry_msgs::Twist>("/cmd_vel_safety",1);
00324         ROS_DEBUG("base module stored");
00325         has_base_module_ = true;
00326         return true;
00327 }
00328 
00332 TeleopCOB::TeleopCOB()
00333 {
00334         getConfigurationFromParameters(); // assign configuration and subscribe to topics
00335         got_init_values_ = false;
00336         time_for_init_ = 0.0;
00337         joy_active_ = false;
00338         run_factor_ = 1.0;
00339 
00340         // add all found joint names to joint_names_vector, which is used to pass values to the state aggregator
00341         for(std::map<std::string,joint_module>::iterator module_it=joint_modules_.begin();module_it!=joint_modules_.end();++module_it){
00342                 std::vector<std::string> names = (module_it->second).joint_names;
00343                 for(unsigned int i=0; i<names.size();i++){
00344                         joint_names_.push_back(names[i]);
00345                         combined_joints_.joint_names_.push_back(names[i]); // puch joit name to combined collection
00346                         combined_joints_.joint_init_values_.push_back(0.0); // be sure that a init value is related to the joint name
00347                         combined_joints_.module_ref_.push_back((joint_module*)(&(module_it->second))); // store a reference to the module containing the joint
00348                 }
00349         }
00350         joint_init_values_.resize(joint_names_.size());
00351 }
00352 
00356 TeleopCOB::~TeleopCOB()
00357 {
00358 }
00359 
00363 void TeleopCOB::init()
00364 {
00365         // common
00366         n_.param("run_factor",run_factor_param_,1.5);
00367 
00368         // assign buttons
00369         n_.param("lower_neck_button",lower_neck_button_,6);
00370         n_.param("upper_neck_button",upper_neck_button_,4);
00371         n_.param("tray_button",tray_button_,3);
00372         n_.param("arm_joint12_button",arm_joint12_button_,0);
00373         n_.param("arm_joint34_button",arm_joint34_button_,1);
00374         n_.param("arm_joint56_button",arm_joint56_button_,2);
00375         n_.param("arm_joint7_button",arm_joint7_button_,3);
00376         n_.param("deadman_button",deadman_button_,5);
00377         n_.param("run_button",run_button_,7);
00378         n_.param("base_safety_button",base_safety_button_,4);
00379         n_.param("stop_base_button",stop_base_button_,8);
00380         n_.param("recover_base_button",recover_base_button_,9);
00381 
00382         // assign axis
00383         n_.param("axis_vx",axis_vx_,1);
00384         n_.param("axis_vy",axis_vy_,0);
00385         n_.param("axis_vth",axis_vth_,2);
00386         n_.param("up_down",up_down_,5); //axis[5] tray--up/down; tilt--front/back, here we just name up_down
00387         n_.param("left_right",left_right_,4);  //axis[4] pan--left/right
00388 
00389         // output for debugging
00390         ROS_DEBUG("init::lower_neck_button: %d",lower_neck_button_);
00391         ROS_DEBUG("init::upper_neck_button: %d",upper_neck_button_);
00392         ROS_DEBUG("init::tray_button: %d",tray_button_);
00393         ROS_DEBUG("init::arm_joint12_button: %d",arm_joint12_button_);
00394         ROS_DEBUG("init::arm_joint34_button: %d",arm_joint34_button_);
00395         ROS_DEBUG("init::arm_joint56_button: %d",arm_joint56_button_);
00396         ROS_DEBUG("init::arm_joint7_button: %d",arm_joint7_button_);
00397         ROS_DEBUG("init::deadman_button: %d",deadman_button_);
00398         ROS_DEBUG("init::run_button: %d",run_button_);
00399         ROS_DEBUG("init::stop_base_button: %d",stop_base_button_);
00400         ROS_DEBUG("init::recover_base_button: %d",recover_base_button_);
00401 
00402         ROS_DEBUG("init::axis_vx: %d",axis_vx_);
00403         ROS_DEBUG("init::axis_vy: %d",axis_vy_);
00404         ROS_DEBUG("init::axis_vth: %d",axis_vth_);
00405         ROS_DEBUG("init::up_down: %d",up_down_);
00406         ROS_DEBUG("init::left_right: %d",left_right_);
00407 
00408         // TODO general!!!
00409         joy_sub_ = n_.subscribe("/joy",1,&TeleopCOB::joy_cb,this);
00410         joint_states_sub_ = n_.subscribe("/joint_states",1,&TeleopCOB::joint_states_cb,this);
00411 }
00412 
00416 void TeleopCOB::setInitValues()
00417 {
00418 
00419         // loop trough all the joints in the combined collection
00420         for(unsigned int i=0; i<combined_joints_.joint_init_values_.size();i++){
00421                 //loop trough all the joints in module containing joint settings,
00422                 //and try to find the one with a name matching the currently browsed joint
00423                 //in the combined collection
00424                 for(unsigned int j=0; j<combined_joints_.module_ref_[i]->joint_names.size();j++){
00425                         // if the matching joint is found, assign value to pos command and stop looking for this name
00426                         if(combined_joints_.module_ref_[i]->joint_names[j].compare(combined_joints_.joint_names_[i])==0){
00427                                 combined_joints_.module_ref_[i]->req_joint_pos_[j] = combined_joints_.joint_init_values_[i];
00428                                 combined_joints_.module_ref_[i]->req_joint_vel_[j] = 0.0; // initalize velocity cmd to 0
00429                                 break; // node found, break the search
00430                         }
00431                 }
00432         }
00433 
00434         // base init values (velocities) are already set to 0 by default
00435 
00436         got_init_values_ = true;
00437 }
00438 
00446 void TeleopCOB::joint_states_cb(const sensor_msgs::JointState::ConstPtr &joint_states_msg)
00447 {
00448         if (!got_init_values_ && stopped_ && joy_active_)
00449         {
00450                 ROS_DEBUG("joint_states_cb: getting init values");
00451                 for (unsigned int j = 0; j<joint_names_.size(); j++ )
00452                 {
00453                         for (unsigned int i = 0; i<joint_states_msg->name.size(); i++ )
00454                         {
00455                                 ROS_DEBUG("joint names in init: %s should match %s",joint_names_[j].c_str(),joint_states_msg->name[i].c_str());
00456                                 if (joint_states_msg->name[i] == joint_names_[j])
00457                                 {
00458                                         joint_init_values_[j] = joint_states_msg->position[i];
00459                                         if(joint_names_[j]!=combined_joints_.joint_names_[j])
00460                                                 ROS_ERROR("error in new joint name collection, name miss match.");
00461                                         combined_joints_.joint_init_values_[j] = joint_states_msg->position[i]; //new
00462                                         ROS_DEBUG("joint %s found. init value = %f",joint_names_[j].c_str(),joint_init_values_[j]);
00463                                         break;
00464                                 }
00465                         }
00466                 }
00467                 setInitValues();
00468         }
00469 }
00470 
00478 void TeleopCOB::joy_cb(const sensor_msgs::Joy::ConstPtr &joy_msg)
00479 {
00480         // deadman button to activate joystick
00481         if(deadman_button_>=0 && deadman_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[deadman_button_]==1)
00482         {
00483                 if (!joy_active_)
00484                 {
00485                         ROS_INFO("joystick is active");
00486                         joy_active_ = true;
00487                         got_init_values_ = false;
00488                 }
00489         }
00490         else
00491         {
00492                 ROS_DEBUG("joystick is not active");
00493                 joy_active_ = false;
00494                 return;
00495         }
00496 
00497         // run button
00498         if(run_button_>=0 && run_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[run_button_]==1)
00499         {
00500                 run_factor_ = run_factor_param_;
00501         }
00502         else //button release
00503         {
00504                 run_factor_ = 1.0;
00505         }
00506         
00507         // base safety button
00508         if(base_safety_button_>=0 && base_safety_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[base_safety_button_]==1)
00509         {
00510                 base_safety_ = false;
00511         }
00512         else //button release
00513         {
00514                 base_safety_ = true;
00515         }
00516         
00517         // recover base button
00518         if(recover_base_button_>=0 && recover_base_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[recover_base_button_]==1)
00519         {
00520                 ros::ServiceClient client_init_base = n_.serviceClient<cob_srvs::Trigger>("/base_controller/init");
00521         
00522                 ROS_INFO("Init base");
00523                 cob_srvs::Trigger srv = cob_srvs::Trigger();
00524                 if (client_init_base.call(srv))
00525                 {
00526                         ROS_INFO("Base init successfully");
00527                 }
00528                 else
00529                 {
00530                         ROS_ERROR("Failed to call service /base_controller/init");
00531                 }
00532                 
00533                 ros::ServiceClient client_recover_base = n_.serviceClient<cob_srvs::Trigger>("/base_controller/recover");
00534         
00535                 ROS_INFO("Recover base");
00536                 if (client_recover_base.call(srv))
00537                 {
00538                         ROS_INFO("Base recovered successfully");
00539                 }
00540                 else
00541                 {
00542                         ROS_ERROR("Failed to call service /base_controller/recover");
00543                 }
00544         }
00545         
00546         // stop base button
00547         if(stop_base_button_>=0 && stop_base_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[stop_base_button_]==1)
00548         {
00549                 ros::ServiceClient client_stop_base = n_.serviceClient<cob_srvs::Trigger>("/base_controller/stop");
00550         
00551                 ROS_INFO("Stop base");
00552                 cob_srvs::Trigger srv = cob_srvs::Trigger();
00553                 if (client_stop_base.call(srv))
00554                 {
00555                         ROS_INFO("Base stop successfully");
00556                 }
00557                 else
00558                 {
00559                         ROS_ERROR("Failed to call service /base_controller/stop");
00560                 }
00561         }
00562 
00563         // TODO add map for buttons
00564 
00565         // head
00566         if(joint_modules_.find("head")!=joint_modules_.end())
00567         {
00568                 if(upper_neck_button_>=0 &&
00569                                 upper_neck_button_<(int)joy_msg->buttons.size() &&
00570                                 joy_msg->buttons[upper_neck_button_]==1)
00571                 {
00572                         //pan (turn)
00573                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00574                                 joint_modules_["head"].req_joint_vel_[0] = (int)joy_msg->buttons[upper_neck_button_]*joint_modules_["head"].steps[0]*run_factor_;//upper_pan_step_*run_factor_;
00575                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00576                                 joint_modules_["head"].req_joint_vel_[0] = -1*(int)joy_msg->buttons[upper_neck_button_]*joint_modules_["head"].steps[0]*run_factor_;//upper_pan_step_*run_factor_;
00577                         else
00578                                 joint_modules_["head"].req_joint_vel_[0]= 0.0;
00579                         ROS_DEBUG("cb::upper neck pan velocity: %f",joint_modules_["head"].req_joint_vel_[0]);
00580 
00581                         //tilt (nod)
00582                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00583                                 joint_modules_["head"].req_joint_vel_[1] = -1*(int)joy_msg->buttons[upper_neck_button_]*joint_modules_["head"].steps[1]*run_factor_;//upper_tilt_step_*run_factor_;
00584                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00585                                 joint_modules_["head"].req_joint_vel_[1] = (int)joy_msg->buttons[upper_neck_button_]*joint_modules_["head"].steps[1]*run_factor_;//upper_tilt_step_*run_factor_;
00586                         else
00587                                 joint_modules_["head"].req_joint_vel_[1] = 0.0;
00588                         ROS_DEBUG("cb::upper neck tilt velocity: %f",joint_modules_["head"].req_joint_vel_[1]);
00589 
00590                 }
00591                 else
00592                 {
00593                         joint_modules_["head"].req_joint_vel_[0] = 0.0;
00594                         joint_modules_["head"].req_joint_vel_[1] = 0.0;
00595                 }
00596         }
00597         if(joint_modules_.find("torso")!=joint_modules_.end())
00598         {
00599                 // torso TODO update with general as well
00600                 //lower neck
00601                 if(lower_neck_button_>=0 &&
00602                                 lower_neck_button_<(int)joy_msg->buttons.size() &&
00603                                 joy_msg->buttons[lower_neck_button_]==1)
00604                 {
00605                         //pan
00606                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00607                                 joint_modules_["torso"].req_joint_vel_[0] = (int)joy_msg->buttons[lower_neck_button_]*joint_modules_["torso"].steps[0]*run_factor_; //req_lower_pan_vel_
00608                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00609                                 joint_modules_["torso"].req_joint_vel_[0] = -1*(int)joy_msg->buttons[lower_neck_button_]*joint_modules_["torso"].steps[0]*run_factor_; //req_lower_pan_vel_
00610                         else
00611                                 joint_modules_["torso"].req_joint_vel_[0] = 0.0;
00612                         ROS_DEBUG("cb::lower neck pan velocity: %f",joint_modules_["torso"].req_joint_vel_[0]);
00613 
00614                         //tilt
00615                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00616                                 joint_modules_["torso"].req_joint_vel_[1] = (int)joy_msg->buttons[lower_neck_button_]*joint_modules_["torso"].steps[1]*run_factor_; //req_lower_tilt_vel_
00617                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00618                                 joint_modules_["torso"].req_joint_vel_[1] = -1*(int)joy_msg->buttons[lower_neck_button_]*joint_modules_["torso"].steps[1]*run_factor_;
00619                         else
00620                                 joint_modules_["torso"].req_joint_vel_[1] = 0.0;
00621                         ROS_DEBUG("cb::lower neck tilt velocity: %f",joint_modules_["torso"].req_joint_vel_[1]);
00622                 }
00623                 else //button release
00624                 {
00625                         joint_modules_["torso"].req_joint_vel_[0] = 0.0;
00626                         joint_modules_["torso"].req_joint_vel_[1] = 0.0;
00627                 }
00628 
00629                 //upper neck
00630                 if(upper_neck_button_>=0 &&
00631                                 upper_neck_button_<(int)joy_msg->buttons.size() &&
00632                                 joy_msg->buttons[upper_neck_button_]==1)
00633                 {
00634                         //pan
00635                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00636                                 joint_modules_["torso"].req_joint_vel_[2] = (int)joy_msg->buttons[upper_neck_button_]*joint_modules_["torso"].steps[2]*run_factor_;
00637                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00638                                 joint_modules_["torso"].req_joint_vel_[2] = -1*(int)joy_msg->buttons[upper_neck_button_]*joint_modules_["torso"].steps[2]*run_factor_;
00639                         else
00640                                 joint_modules_["torso"].req_joint_vel_[2] = 0.0;
00641                         ROS_DEBUG("cb::upper neck pan velocity: %f",joint_modules_["torso"].req_joint_vel_[2]);
00642 
00643                         //tilt
00644                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00645                                 joint_modules_["torso"].req_joint_vel_[3] = (int)joy_msg->buttons[upper_neck_button_]*joint_modules_["torso"].steps[3]*run_factor_;
00646                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00647                                 joint_modules_["torso"].req_joint_vel_[3] = -1*(int)joy_msg->buttons[upper_neck_button_]*joint_modules_["torso"].steps[3]*run_factor_;
00648                         else
00649                                 joint_modules_["torso"].req_joint_vel_[3] = 0.0;
00650                         ROS_DEBUG("cb::upper neck tilt velocity: %f",joint_modules_["torso"].req_joint_vel_[3]);
00651                 }
00652                 else //button release
00653                 {
00654                         joint_modules_["torso"].req_joint_vel_[2] = 0.0;
00655                         joint_modules_["torso"].req_joint_vel_[3] = 0.0;
00656                 }
00657         }
00658 
00659         if(joint_modules_.find("tray")!=joint_modules_.end())
00660         {
00661                 //tray
00662                 if(tray_button_>=0 && tray_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[tray_button_]==1)
00663                 {
00664                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00665                                 joint_modules_["tray"].req_joint_vel_[0] = (int)joy_msg->buttons[tray_button_]*joint_modules_["tray"].steps[0]*run_factor_;
00666                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00667                                 joint_modules_["tray"].req_joint_vel_[0] = -1*(int)joy_msg->buttons[tray_button_]*joint_modules_["tray"].steps[0]*run_factor_;
00668                         else
00669                                 joint_modules_["tray"].req_joint_vel_[0] = 0.0;
00670                         ROS_DEBUG("cb::tray velocity: %f",joint_modules_["tray"].req_joint_vel_[0]);
00671                 }
00672                 else //button release
00673                 {
00674                         joint_modules_["tray"].req_joint_vel_[0] = 0.0;
00675                 }
00676         }
00677         if(joint_modules_.find("arm")!=joint_modules_.end())
00678         {
00679                 //arm
00680                 //publish_arm_ = false;
00681 
00682                 //joint12
00683                 if(joint_modules_["arm"].req_joint_vel_.size()>1 && arm_joint12_button_>=0 && arm_joint12_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[arm_joint12_button_]==1)
00684                 {
00685                         //joint 1 left or right
00686                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00687                                 joint_modules_["arm"].req_joint_vel_[0] = -1*(int)joy_msg->buttons[arm_joint12_button_]*joint_modules_["arm"].steps[0]*run_factor_;
00688                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00689                                 joint_modules_["arm"].req_joint_vel_[0] = (int)joy_msg->buttons[arm_joint12_button_]*joint_modules_["arm"].steps[0]*run_factor_;
00690                         else
00691                                 joint_modules_["arm"].req_joint_vel_[0] = 0.0;
00692                         ROS_DEBUG("cb::arm joint1 velocity: %f",joint_modules_["arm"].req_joint_vel_[0]);
00693 
00694                         //joint 2 up or down
00695                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00696                                 joint_modules_["arm"].req_joint_vel_[1] = (int)joy_msg->buttons[arm_joint12_button_]*joint_modules_["arm"].steps[1]*run_factor_;
00697                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00698                                 joint_modules_["arm"].req_joint_vel_[1] = -1*(int)joy_msg->buttons[arm_joint12_button_]*joint_modules_["arm"].steps[1]*run_factor_;
00699                         else
00700                                 joint_modules_["arm"].req_joint_vel_[1] = 0.0;
00701                         ROS_DEBUG("cb::arm joint2 velocity: %f",joint_modules_["arm"].req_joint_vel_[1]);
00702                         //publish_arm_ = true;
00703                 }
00704                 else //button release
00705                 {
00706                         joint_modules_["arm"].req_joint_vel_[0] = 0.0;
00707                         joint_modules_["arm"].req_joint_vel_[1] = 0.0;
00708                 } //arm_joint12
00709 
00710                 //joint34
00711                 if(joint_modules_["arm"].req_joint_vel_.size()>3 && arm_joint34_button_>=0 && arm_joint34_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[arm_joint34_button_]==1)
00712                 {
00713                         //joint 3 left or right
00714                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00715                                 joint_modules_["arm"].req_joint_vel_[2] = -1*(int)joy_msg->buttons[arm_joint34_button_]*joint_modules_["arm"].steps[2]*run_factor_;
00716                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00717                                 joint_modules_["arm"].req_joint_vel_[2] = (int)joy_msg->buttons[arm_joint34_button_]*joint_modules_["arm"].steps[2]*run_factor_;
00718                         else
00719                                 joint_modules_["arm"].req_joint_vel_[2] = 0.0;
00720                         ROS_DEBUG("cb::arm joint3 velocity: %f",joint_modules_["arm"].req_joint_vel_[2]);
00721 
00722                         //joint 4 up or down
00723                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00724                                 joint_modules_["arm"].req_joint_vel_[3] = (int)joy_msg->buttons[arm_joint34_button_]*joint_modules_["arm"].steps[3]*run_factor_;
00725                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00726                                 joint_modules_["arm"].req_joint_vel_[3] = -1*(int)joy_msg->buttons[arm_joint34_button_]*joint_modules_["arm"].steps[3]*run_factor_;
00727                         else
00728                                 joint_modules_["arm"].req_joint_vel_[3] = 0.0;
00729                         ROS_DEBUG("cb::arm joint4 velocity: %f",joint_modules_["arm"].req_joint_vel_[3]);
00730                         //publish_arm_ = true;
00731                 }
00732                 else //button release
00733                 {
00734                         joint_modules_["arm"].req_joint_vel_[2] = 0.0;
00735                         joint_modules_["arm"].req_joint_vel_[3] = 0.0;
00736                 } //arm_joint34
00737 
00738                 //joint56
00739                 if(joint_modules_["arm"].req_joint_vel_.size()>4 && arm_joint56_button_>=0 && arm_joint56_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[arm_joint56_button_]==1)
00740                 {
00741                         //joint 5 left or right
00742                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00743                                 joint_modules_["arm"].req_joint_vel_[4] = -1*(int)joy_msg->buttons[arm_joint56_button_]*joint_modules_["arm"].steps[4]*run_factor_;
00744                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00745                                 joint_modules_["arm"].req_joint_vel_[4] = (int)joy_msg->buttons[arm_joint56_button_]*joint_modules_["arm"].steps[4]*run_factor_;
00746                         else
00747                                 joint_modules_["arm"].req_joint_vel_[4] = 0.0;
00748                         ROS_DEBUG("cb::arm joint5 velocity: %f",joint_modules_["arm"].req_joint_vel_[4]);
00749 
00750                         //joint 6 up or down
00751                         if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]>0.0)
00752                                 joint_modules_["arm"].req_joint_vel_[5] = (int)joy_msg->buttons[arm_joint56_button_]*joint_modules_["arm"].steps[5]*run_factor_;
00753                         else if(up_down_>=0 && up_down_<(int)joy_msg->axes.size() && joy_msg->axes[up_down_]<0.0)
00754                                 joint_modules_["arm"].req_joint_vel_[5] = -1*(int)joy_msg->buttons[arm_joint56_button_]*joint_modules_["arm"].steps[5]*run_factor_;
00755                         else
00756                                 joint_modules_["arm"].req_joint_vel_[5] = 0.0;
00757                         ROS_DEBUG("cb::arm joint6 velocity: %f",joint_modules_["arm"].req_joint_vel_[5]);
00758                         //publish_arm_ = true;
00759                 }
00760                 else //button release
00761                 {
00762                         joint_modules_["arm"].req_joint_vel_[4] = 0.0;
00763                         joint_modules_["arm"].req_joint_vel_[5] = 0.0;
00764                 } //arm_joint56
00765 
00766                 //joint7
00767                 if(joint_modules_["arm"].req_joint_vel_.size()>5 && arm_joint7_button_>=0 && arm_joint7_button_<(int)joy_msg->buttons.size() && joy_msg->buttons[arm_joint7_button_]==1)
00768                 {
00769                         //joint 7 left or right
00770                         if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]<0.0)
00771                         {
00772                                 joint_modules_["arm"].req_joint_vel_[6] = -1*(int)joy_msg->buttons[arm_joint7_button_]*joint_modules_["arm"].steps[6]*run_factor_;
00773                                 //publish_arm_ = true;
00774                         }
00775                         else if(left_right_>=0 && left_right_<(int)joy_msg->axes.size() && joy_msg->axes[left_right_]>0.0)
00776                         {
00777                                 joint_modules_["arm"].req_joint_vel_[6] = (int)joy_msg->buttons[arm_joint7_button_]*joint_modules_["arm"].steps[6]*run_factor_;
00778                                 //publish_arm_ = true;
00779                         }
00780                         else
00781                                 joint_modules_["arm"].req_joint_vel_[6] = 0.0;
00782                         ROS_DEBUG("cb::arm joint7 velocity: %f",joint_modules_["arm"].req_joint_vel_[6]);
00783                 }
00784                 else //button release
00785                 {
00786                         joint_modules_["arm"].req_joint_vel_[6] = 0.0;
00787                 } //arm_joint7
00788         }
00789         //================base================
00790         if(has_base_module_ && base_module_.req_vel_.size()==3)
00791         {
00792                 if(axis_vx_>=0 && axis_vx_<(int)joy_msg->axes.size())
00793                         base_module_.req_vel_[0] = joy_msg->axes[axis_vx_]*base_module_.max_vel_[0]*run_factor_;
00794                 else
00795                         base_module_.req_vel_[0] = 0.0;
00796 
00797                 if(axis_vy_>=0 && axis_vy_<(int)joy_msg->axes.size())
00798                         base_module_.req_vel_[1] = joy_msg->axes[axis_vy_]*base_module_.max_vel_[1]*run_factor_;//req_vy_ = joy_msg->axes[axis_vy_]*max_vy_*run_factor_;
00799                 else
00800                         base_module_.req_vel_[1] = 0.0; //req_vy_ = 0.0;
00801 
00802                 if(axis_vth_>=0 && axis_vth_<(int)joy_msg->axes.size())
00803                         base_module_.req_vel_[2] = joy_msg->axes[axis_vth_]*base_module_.max_vel_[2]*run_factor_;//req_vth_ = joy_msg->axes[axis_vth_]*max_vth_*run_factor_;
00804                 else
00805                         base_module_.req_vel_[2] = 0.0; //req_vth_ = 0.0;
00806         }
00807 
00808 }//joy_cb
00809 
00813 void TeleopCOB::update()
00814 {
00815         if (!joy_active_)
00816         {
00817                 if (!stopped_)
00818                 {
00819                         // stop components: send zero for one time
00820                         for(std::map<std::string,joint_module>::iterator module_it=joint_modules_.begin();module_it!=joint_modules_.end();++module_it)
00821                         {
00822                                 for(unsigned int i=0; i<module_it->second.req_joint_vel_.size();i++)
00823                                 {
00824                                         module_it->second.req_joint_vel_[i] = 0.0;
00825                                 }
00826                         }
00827 
00828                         if(has_base_module_)
00829                         {
00830                                 for(unsigned int i=0; i<3; i++){
00831                                         base_module_.req_vel_[i]=0;
00832                                         base_module_.vel_old_[i]=0;
00833                                 }
00834                         }
00835 
00836                         update_joint_modules();
00837                         update_base();
00838                         stopped_ = true;
00839                         ROS_INFO("stopped all components");
00840                 }
00841                 return;
00842         }
00843 
00844         // set initial values
00845         if(!got_init_values_)
00846         {
00847                 if (time_for_init_ < 1.0) // wait for 1 sec, then set init values to 0.0
00848                 {
00849                         ROS_DEBUG("still waiting for initial values, time_for_init_ = %f",time_for_init_);
00850                         time_for_init_ = time_for_init_ + 1.0/PUBLISH_FREQ;
00851                         return;
00852                 }
00853                 else
00854                 {
00855                         ROS_WARN("Timeout waiting for /joint_states message. Setting all init values to 0.0");
00856                         setInitValues();
00857                 }
00858         }
00859 
00860         update_joint_modules();
00861         update_base();
00862         stopped_ = false;
00863 }
00864 
00865 void TeleopCOB::update_joint_modules()
00866 {
00867         double dt = 1.0/double(PUBLISH_FREQ);
00868         double horizon = 3.0*dt;
00869 
00870         joint_module* jointModule;
00871         for(std::map<std::string,joint_module>::iterator it = joint_modules_.begin();it!=joint_modules_.end();++it)
00872         {
00873                 jointModule = (joint_module*)(&(it->second));
00874 
00875                 trajectory_msgs::JointTrajectory traj;
00876                 traj.header.stamp = ros::Time::now()+ros::Duration(0.01);
00877                 traj.points.resize(1);
00878                 brics_actuator::JointVelocities cmd_vel;
00879                 brics_actuator::JointValue joint_vel;
00880                 joint_vel.timeStamp = traj.header.stamp;
00881                 joint_vel.unit = "rad";
00882                 for(unsigned int i = 0; i<jointModule->joint_names.size();i++)
00883                 {
00884                         // as trajectory message
00885                         traj.joint_names.push_back(jointModule->joint_names[i]);
00886                         traj.points[0].positions.push_back(jointModule->req_joint_pos_[i] + jointModule->req_joint_vel_[i]*horizon);
00887                         traj.points[0].velocities.push_back(jointModule->req_joint_vel_[i]);  //lower_neck_pan
00888                         // as brics message
00889                         joint_vel.value = jointModule->req_joint_vel_[i];
00890                         joint_vel.joint_uri = jointModule->joint_names[i];
00891                         cmd_vel.velocities.push_back(joint_vel);
00892                         // update current positions
00893                         jointModule->req_joint_pos_[i] += jointModule->req_joint_vel_[i]*horizon;
00894                 }
00895 
00896                 traj.points[0].time_from_start = ros::Duration(horizon);
00897 
00898                 jointModule->module_publisher_.publish(traj); // TODO, change
00899                 jointModule->module_publisher_brics_.publish(cmd_vel);
00900         }
00901 }
00902 
00906 void TeleopCOB::update_base()
00907 {
00908         if(!has_base_module_)
00909                 return;
00910         double dt = 1.0/double(PUBLISH_FREQ);
00911         double v[] = {0.0,0.0,0.0};
00912 
00913         for( int i =0; i<3; i++)
00914         {
00915                 // filter v with ramp
00916                 if ((base_module_.req_vel_[i]-base_module_.vel_old_[i])/dt > base_module_.max_acc_[i])
00917                 {
00918                         v[i] = base_module_.vel_old_[i] + base_module_.max_acc_[i]*dt;
00919                 }
00920                 else if((base_module_.req_vel_[i]-base_module_.vel_old_[i])/dt < -base_module_.max_acc_[i])
00921                 {
00922                         v[i] = base_module_.vel_old_[i] - base_module_.max_acc_[i]*dt;
00923                 }
00924                 else
00925                 {
00926                         v[i] = base_module_.req_vel_[i];
00927                 }
00928                 base_module_.vel_old_[i] = v[i];
00929         }
00930 
00931         geometry_msgs::Twist cmd;
00932         cmd.linear.x = v[0]; //vx;
00933         cmd.linear.y = v[1]; //vy;
00934         cmd.angular.z = v[2]; //vth;
00935 
00936         if (base_safety_)
00937         {
00938                 base_module_.base_safety_publisher_.publish(cmd);
00939         }
00940         else
00941         {
00942                 base_module_.base_publisher_.publish(cmd);
00943         }
00944 }
00945 
00951 int main(int argc,char **argv)
00952 {
00953         ros::init(argc,argv,"teleop_cob");
00954         TeleopCOB teleop_cob;
00955         teleop_cob.init();
00956 
00957         ros::Rate loop_rate(PUBLISH_FREQ); //Hz
00958         while(teleop_cob.n_.ok())
00959         {
00960                 ros::spinOnce();
00961                 teleop_cob.update();
00962                 loop_rate.sleep();
00963         }
00964 
00965         exit(0);
00966         return(0);
00967 }
00968 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


cob_teleop
Author(s): Florian Weisshardt
autogenerated on Fri Mar 1 2013 17:47:32