$search
00001 /**************************************************************** 00002 * 00003 * Copyright (c) 2010 00004 * 00005 * Fraunhofer Institute for Manufacturing Engineering 00006 * and Automation (IPA) 00007 * 00008 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00009 * 00010 * Project name: care-o-bot 00011 * ROS stack name: cob_driver 00012 * ROS package name: cob_light 00013 * Description: Switch robots led color by sending data to 00014 * the led-µC over serial connection. 00015 * 00016 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00017 * 00018 * Author: Benjamin Maidel, email:benjamin.maidel@ipa.fraunhofer.de 00019 * Supervised by: Benjamin Maidel, email:benjamin.maidel@ipa.fraunhofer.de 00020 * 00021 * Date of creation: August 2012 00022 * ToDo: 00023 * 00024 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00025 * 00026 * Redistribution and use in source and binary forms, with or without 00027 * modification, are permitted provided that the following conditions are met: 00028 * 00029 * * Redistributions of source code must retain the above copyright 00030 * notice, this list of conditions and the following disclaimer. 00031 * * Redistributions in binary form must reproduce the above copyright 00032 * notice, this list of conditions and the following disclaimer in the 00033 * documentation and/or other materials provided with the distribution. 00034 * * Neither the name of the Fraunhofer Institute for Manufacturing 00035 * Engineering and Automation (IPA) nor the names of its 00036 * contributors may be used to endorse or promote products derived from 00037 * this software without specific prior written permission. 00038 * 00039 * This program is free software: you can redistribute it and/or modify 00040 * it under the terms of the GNU Lesser General Public License LGPL as 00041 * published by the Free Software Foundation, either version 3 of the 00042 * License, or (at your option) any later version. 00043 * 00044 * This program is distributed in the hope that it will be useful, 00045 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00046 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00047 * GNU Lesser General Public License LGPL for more details. 00048 * 00049 * You should have received a copy of the GNU Lesser General Public 00050 * License LGPL along with this program. 00051 * If not, see <http://www.gnu.org/licenses/>. 00052 * 00053 ****************************************************************/ 00054 00055 // standard includes 00056 #include <stdio.h> 00057 #include <string.h> 00058 #include <sstream> 00059 #include <math.h> 00060 00061 // ros includes 00062 #include <ros/ros.h> 00063 00064 // ros message includes 00065 #include <std_msgs/ColorRGBA.h> 00066 #include <cob_lightmode/LightMode.h> 00067 #include <visualization_msgs/Marker.h> 00068 00069 #include <spektrumviz.h> 00070 00071 #define DEFAULT_RECORD_SIZE 1024 00072 #define DEFAULT_APPBUFFER_SIZE DEFAULT_RECORD_SIZE/2 00073 #define DEFAULT_SAMPLING_RATE 44100 00074 #define DEFAULT_SUBBAND_SIZE 64 00075 #define DEFAULT_CHANNELS 2 00076 00077 //#define ENABLE_GUI 00078 00079 class LightMode 00080 { 00081 public: 00082 LightMode() : 00083 _timer_inc(0.0) 00084 { 00085 _nh = ros::NodeHandle("~"); 00086 _srvServer = 00087 _nh.advertiseService("mode", &LightMode::modeCallback, this); 00088 00089 _pub = _nh.advertise<std_msgs::ColorRGBA>("/light_controller/command",2); 00090 00091 _beatController = new mybeat::BeatController(DEFAULT_RECORD_SIZE,DEFAULT_SAMPLING_RATE,DEFAULT_SUBBAND_SIZE, DEFAULT_CHANNELS); 00092 _beatController->signalProcessingDone()->connect(boost::bind(&LightMode::beatProcessDoneCallback,this)); 00093 //_beatController->signalBeatSnare()->connect(boost::bind(&LightMode::beatSnareCallback,this)); 00094 //_beatController->signalBeatDrum()->connect(boost::bind(&LightMode::beatDrumCallback,this)); 00095 _beatController->start(); 00096 } 00097 00098 ~LightMode() 00099 { 00100 _beatController->stop(); 00101 delete _beatController; 00102 } 00103 00104 mybeat::BeatController* getBeatController(){return _beatController;} 00105 00106 enum LedMode{ STATIC = 0, BREATH = 1, BREATH_COLOR = 2, FLASH = 3, SOUND = 4 }; 00107 00108 void beatProcessDoneCallback() 00109 { 00110 _sound_magnitude = (_beatController->getBuffers().at(0)->pwr() / _beatController->getBuffers().at(0)->max_pwr()); 00111 00112 } 00113 00114 void beatSnareCallback() 00115 { 00116 ROS_INFO_NAMED("LightMode","beat Snare"); 00117 } 00118 00119 void beatDrumCallback() 00120 { 00121 ROS_INFO_NAMED("LightMode","beat Drum"); 00122 } 00123 00124 private: 00125 ros::NodeHandle _nh; 00126 ros::ServiceServer _srvServer; 00127 ros::Publisher _pub; 00128 00129 ros::Timer _timerMode; 00130 float _timer_inc; 00131 00132 std_msgs::ColorRGBA _color; 00133 00134 mybeat::BeatController *_beatController; 00135 float _sound_magnitude; 00136 00137 00138 bool modeCallback(cob_lightmode::LightMode::Request &req, cob_lightmode::LightMode::Response &res) 00139 { 00140 if(_timerMode.isValid()) 00141 ROS_INFO("Stopping timer"); 00142 _timerMode.stop(); 00143 00144 if(_beatController->getEnabled()) 00145 { 00146 _beatController->stop(); 00147 ROS_INFO("Stopping _beatController"); 00148 } 00149 00150 switch(req.mode) 00151 { 00152 case STATIC: 00153 ROS_INFO("Set Mode to Static"); 00154 _color = req.color; 00155 _pub.publish(_color); 00156 break; 00157 00158 case BREATH: 00159 ROS_INFO("Set Mode to Breath"); 00160 _color = req.color; 00161 _timerMode = _nh.createTimer(ros::Duration(0.04), 00162 &LightMode::breathCallback, this); 00163 break; 00164 00165 case BREATH_COLOR: 00166 ROS_INFO("Set Mode to BreathColor"); 00167 _color = req.color; 00168 _timerMode = _nh.createTimer(ros::Duration(0.04), 00169 &LightMode::breathCallback, this); 00170 break; 00171 00172 case FLASH: 00173 ROS_INFO("Set Mode to Flash"); 00174 _color = req.color; 00175 break; 00176 00177 case SOUND: 00178 ROS_INFO("Set Mode to Sound"); 00179 _color = req.color; 00180 _beatController->start(); 00181 ROS_INFO("beatController started"); 00182 _timerMode = _nh.createTimer(ros::Duration(0.05), 00183 &LightMode::soundCallback, this); 00184 break; 00185 00186 default: 00187 ROS_WARN_NAMED("LightMode","Unsupported Mode: %d", req.mode); 00188 } 00189 res.error_type = 0; 00190 res.error_msg = ""; 00191 return true; 00192 } 00193 00194 // cyclic called callback if mode is breath 00195 // fades leds brightness 00196 void breathCallback(const ros::TimerEvent &event) 00197 { 00198 //double fV = (exp(sin(_timer_inc))-1.0/M_E)*(1.000/(M_E-1.0/M_E)); 00199 double fV = (exp(sin(_timer_inc))-0.36787944)*0.42545906411; 00200 00201 _timer_inc += 0.025; 00202 if(_timer_inc >= M_PI*2) 00203 _timer_inc = 0.0; 00204 00205 std_msgs::ColorRGBA col; 00206 col.r = _color.r; 00207 col.g = _color.g; 00208 col.b = _color.b; 00209 col.a = fV; 00210 00211 _pub.publish(col); 00212 } 00213 00214 void flashCallback(const ros::TimerEvent &event) 00215 { 00216 // todo: add functionality 00217 } 00218 00219 void soundCallback(const ros::TimerEvent &event) 00220 { 00221 std_msgs::ColorRGBA col; 00222 col.r = _color.r; 00223 col.g = _color.g; 00224 col.b = _color.b; 00225 if(_sound_magnitude > 1.0) 00226 _sound_magnitude = 1.0; 00227 col.a = _sound_magnitude; 00228 00229 _pub.publish(col); 00230 } 00231 }; 00232 00233 int main(int argc, char** argv) 00234 { 00235 #ifdef ENABLE_GUI 00236 if(!Glib::thread_supported()) 00237 Glib::thread_init(); 00238 #endif 00239 // init node 00240 ros::init(argc, argv, "led_mode"); 00241 // create LightMode instance 00242 LightMode LightMode; 00243 00244 #ifdef ENABLE_GUI 00245 Gtk::Main kit(argc, argv); 00246 00247 Gtk::Window win; 00248 win.set_title("SpektrumViz"); 00249 00250 SpektrumViz viz(LightMode.getBeatController()); 00251 00252 win.add(viz); 00253 viz.show(); 00254 win.show_all(); 00255 win.set_size_request(860,140); 00256 #endif 00257 00258 ros::Rate r(30); //Cycle-Rate: Frequency of publishing EMStopStates 00259 while(ros::ok()) 00260 { 00261 #ifdef ENABLE_GUI 00262 while( Gtk::Main::events_pending() ) 00263 Gtk::Main::iteration(); 00264 #endif 00265 ros::spinOnce(); 00266 r.sleep(); 00267 } 00268 //ros::spin(); 00269 00270 return 0; 00271 }