ridgeback_lighting.cpp
Go to the documentation of this file.
00001 
00026 #include "ridgeback_base/ridgeback_lighting.h"
00027 #include <boost/assign/list_of.hpp>
00028 
00029 namespace ridgeback_base
00030 {
00031 
00032 namespace States
00033 {
00034   enum State
00035   {
00036     Idle = 0,
00037     Driving,
00038     Charged,
00039     Charging,
00040     LowBattery,
00041     NeedsReset,
00042     Fault,
00043     Stopped,
00044     NumberOfStates
00045   };
00046 }  // namespace States
00047 typedef States::State State;
00048 
00049 namespace Colours
00050 {
00051   enum Colour
00052   {
00053     Off = 0x000000,
00054     Red_H = 0xFF0000,
00055     Red_M = 0xAA00000,
00056     Red_L = 0x550000,
00057     Green_H = 0x00FF00,
00058     Green_M = 0x00AA00,
00059     Green_L = 0x005500,
00060     Blue_H = 0x0000FF,
00061     Blue_M = 0x0000AA,
00062     Blue_L = 0x000055,
00063     Yellow_H = 0xFFFF00,
00064     Yellow_M = 0xAAAA00,
00065     Yellow_L = 0x555500,
00066     Orange_H = 0xFFAE00,
00067     Orange_M = 0xF0A80E,
00068     Orange_L = 0xD69F27,
00069     White_H = 0xFFFFFF,
00070     White_M = 0xAAAAAA,
00071     White_L = 0x555555
00072   };
00073 }  // namespace Colours
00074 typedef Colours::Colour Colour;
00075 
00076 
00077 RidgebackLighting::RidgebackLighting(ros::NodeHandle* nh) :
00078   nh_(nh),
00079   allow_user_(false),
00080   user_publishing_(false),
00081   state_(States::Idle),
00082   current_pattern_count_(0)
00083 {
00084   lights_pub_ = nh_->advertise<ridgeback_msgs::Lights>("mcu/cmd_lights", 1);
00085 
00086   user_cmds_sub_ = nh_->subscribe("cmd_lights", 1, &RidgebackLighting::userCmdCallback, this);
00087   mcu_status_sub_ = nh_->subscribe("mcu/status", 1, &RidgebackLighting::mcuStatusCallback, this);
00088   puma_status_sub_ = nh_->subscribe("status", 1, &RidgebackLighting::pumaStatusCallback, this);
00089   cmd_vel_sub_ = nh_->subscribe("cmd_vel", 1, &RidgebackLighting::cmdVelCallback, this);
00090 
00091   pub_timer_ = nh_->createTimer(ros::Duration(1.0/5), &RidgebackLighting::timerCb, this);
00092   user_timeout_ = nh_->createTimer(ros::Duration(1.0/1), &RidgebackLighting::userTimeoutCb, this);
00093 
00094   using namespace Colours;  // NOLINT(build/namespaces)
00095   patterns_.stopped.push_back(boost::assign::list_of(Red_H)(Red_H)(Red_H)(Red_H)(Red_H)(Red_H)(Red_H)(Red_H));
00096   patterns_.stopped.push_back(boost::assign::list_of(Off)(Off)(Off)(Off)(Off)(Off)(Off)(Off));
00097 
00098   patterns_.fault.push_back(
00099     boost::assign::list_of(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H));
00100   patterns_.fault.push_back(boost::assign::list_of(Off)(Off)(Off)(Off)(Off)(Off)(Off)(Off));
00101 
00102   patterns_.reset.push_back(boost::assign::list_of(Off)(Red_H)(Off)(Red_H)(Yellow_H)(Yellow_H)(Red_H)(Off));
00103   patterns_.reset.push_back(boost::assign::list_of(Red_H)(Off)(Red_H)(Off)(Red_H)(Red_H)(Off)(Red_H));
00104 
00105   patterns_.low_battery.push_back(
00106     boost::assign::list_of(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L));
00107   patterns_.low_battery.push_back(
00108     boost::assign::list_of(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M));
00109   patterns_.low_battery.push_back(
00110     boost::assign::list_of(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H)(Orange_H));
00111   patterns_.low_battery.push_back(
00112     boost::assign::list_of(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M)(Orange_M));
00113   patterns_.low_battery.push_back(
00114     boost::assign::list_of(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L)(Orange_L));
00115 
00116   patterns_.charged.push_back(
00117     boost::assign::list_of(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H));
00118 
00119   patterns_.charging.push_back(
00120     boost::assign::list_of(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L));
00121   patterns_.charging.push_back(
00122     boost::assign::list_of(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M));
00123   patterns_.charging.push_back(
00124     boost::assign::list_of(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H)(Green_H));
00125   patterns_.charging.push_back(
00126     boost::assign::list_of(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M)(Green_M));
00127   patterns_.charging.push_back(
00128     boost::assign::list_of(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L)(Green_L));
00129 
00130   patterns_.driving.push_back(
00131     boost::assign::list_of(White_M)(White_M)(White_M)(White_M)(Red_M)(Red_M)(Red_M)(Red_M));
00132 
00133   patterns_.idle.push_back(
00134     boost::assign::list_of(White_L)(White_L)(White_L)(White_L)(Red_L)(Red_L)(Red_L)(Red_L));
00135 }
00136 
00137 
00138 void RidgebackLighting::setRGB(ridgeback_msgs::RGB* rgb, uint32_t colour)
00139 {
00140   rgb->red = ((colour & 0xFF0000) >> 16) / 255.0;
00141   rgb->green = ((colour & 0x00FF00) >> 8) / 255.0;
00142   rgb->blue = ((colour & 0x0000FF)) / 255.0;
00143 }
00144 
00145 void RidgebackLighting::setLights(ridgeback_msgs::Lights* lights, uint32_t pattern[8])
00146 {
00147   for (int i = 0; i < 8; i++)
00148   {
00149     setRGB(&lights->lights[i], pattern[i]);
00150   }
00151 }
00152 
00153 void RidgebackLighting::userCmdCallback(const ridgeback_msgs::Lights::ConstPtr& lights_msg)
00154 {
00155   if (allow_user_)
00156   {
00157     lights_pub_.publish(lights_msg);
00158   }
00159   user_publishing_ = true;
00160 }
00161 
00162 void RidgebackLighting::mcuStatusCallback(const ridgeback_msgs::Status::ConstPtr& status_msg)
00163 {
00164   mcu_status_msg_ = *status_msg;
00165 }
00166 
00167 void RidgebackLighting::pumaStatusCallback(const puma_motor_msgs::MultiStatus::ConstPtr& status_msg)
00168 {
00169   pumas_status_msg_ = *status_msg;
00170 }
00171 
00172 void RidgebackLighting::cmdVelCallback(const geometry_msgs::Twist::ConstPtr& msg)
00173 {
00174   cmd_vel_msg_ = *msg;
00175 }
00176 
00177 void RidgebackLighting::timerCb(const ros::TimerEvent&)
00178 {
00179   updateState();
00180 
00181   if (state_ >= States::Charged)
00182   {
00183     allow_user_ = false;
00184   }
00185   else
00186   {
00187     allow_user_ = true;
00188   }
00189 
00190   if (!user_publishing_ || !allow_user_)
00191   {
00192     ridgeback_msgs::Lights lights_msg;
00193     updatePattern();
00194     setLights(&lights_msg, &current_pattern_[0]);
00195     lights_pub_.publish(lights_msg);
00196   }
00197 }
00198 
00199 void RidgebackLighting::userTimeoutCb(const ros::TimerEvent&)
00200 {
00201   user_publishing_ = false;
00202 }
00203 
00204 void RidgebackLighting::updateState()
00205 {
00206   if (mcu_status_msg_.stop_engaged == true)
00207   {
00208     state_ = States::Stopped;
00209   }
00210   else if (mcu_status_msg_.drivers_active == false)
00211   {
00212     state_ = States::NeedsReset;
00213   }
00214   else if (pumas_status_msg_.drivers.size() == 4 &&
00215           (pumas_status_msg_.drivers[0].fault != 0 ||
00216            pumas_status_msg_.drivers[1].fault != 0 ||
00217            pumas_status_msg_.drivers[2].fault != 0 ||
00218            pumas_status_msg_.drivers[3].fault != 0))
00219   {
00220     state_ = States::Fault;
00221   }
00222   else if (mcu_status_msg_.measured_battery <= 24.0)
00223   {
00224     state_ = States::LowBattery;
00225   }
00226   else if (mcu_status_msg_.charging_complete == true)
00227   {
00228     state_ = States::Charged;
00229   }
00230   else if (mcu_status_msg_.charger_connected == true)
00231   {
00232     state_ = States::Charging;
00233   }
00234   else if (cmd_vel_msg_.linear.x != 0.0 ||
00235            cmd_vel_msg_.linear.y != 0.0 ||
00236            cmd_vel_msg_.angular.z != 0.0)
00237   {
00238     state_ = States::Driving;
00239   }
00240   else
00241   {
00242     state_ = States::Idle;
00243   }
00244 }
00245 
00246 void RidgebackLighting::updatePattern()
00247 {
00248   if (old_state_ != state_)
00249   {
00250     current_pattern_count_ = 0;
00251   }
00252 
00253   switch (state_)
00254   {
00255     case States::Stopped:
00256       if (current_pattern_count_ >= patterns_.stopped.size())
00257       {
00258         current_pattern_count_ = 0;
00259       }
00260       memcpy(&current_pattern_, &patterns_.stopped[current_pattern_count_], sizeof(current_pattern_));
00261       break;
00262     case States::Fault:
00263       if (current_pattern_count_ >= patterns_.fault.size())
00264       {
00265         current_pattern_count_ = 0;
00266       }
00267       memcpy(&current_pattern_, &patterns_.fault[current_pattern_count_], sizeof(current_pattern_));
00268       break;
00269     case States::NeedsReset:
00270       if (current_pattern_count_ >= patterns_.reset.size())
00271       {
00272         current_pattern_count_ = 0;
00273       }
00274       memcpy(&current_pattern_, &patterns_.reset[current_pattern_count_], sizeof(current_pattern_));
00275       break;
00276     case States::LowBattery:
00277       if (current_pattern_count_ >= patterns_.low_battery.size())
00278       {
00279         current_pattern_count_ = 0;
00280       }
00281       memcpy(&current_pattern_, &patterns_.low_battery[current_pattern_count_], sizeof(current_pattern_));
00282       break;
00283     case States::Charged:
00284       if (current_pattern_count_ >= patterns_.charged.size())
00285       {
00286         current_pattern_count_ = 0;
00287       }
00288       memcpy(&current_pattern_, &patterns_.charged[current_pattern_count_], sizeof(current_pattern_));
00289       break;
00290     case States::Charging:
00291       if (current_pattern_count_ >= patterns_.charging.size())
00292       {
00293         current_pattern_count_ = 0;
00294       }
00295       memcpy(&current_pattern_, &patterns_.charging[current_pattern_count_], sizeof(current_pattern_));
00296       break;
00297     case States::Driving:
00298       if (current_pattern_count_ >= patterns_.driving.size())
00299       {
00300         current_pattern_count_ = 0;
00301       }
00302       memcpy(&current_pattern_, &patterns_.driving[current_pattern_count_], sizeof(current_pattern_));
00303       break;
00304     case States::Idle:
00305       if (current_pattern_count_ >= patterns_.idle.size())
00306       {
00307         current_pattern_count_ = 0;
00308       }
00309       memcpy(&current_pattern_, &patterns_.idle[current_pattern_count_], sizeof(current_pattern_));
00310       break;
00311   }
00312   old_state_ = state_;
00313   current_pattern_count_++;
00314 }
00315 
00316 }  // namespace ridgeback_base


ridgeback_base
Author(s): Mike Purvis , Tony Baltovski
autogenerated on Sun Mar 24 2019 03:01:13