Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <actionlib/server/simple_action_server.h>
00003 #include <diagnostic_msgs/DiagnosticArray.h>
00004 #include <std_msgs/String.h>
00005 #include <cob_srvs/Trigger.h>
00006 #include <cob_sound/SayAction.h>
00007 #include <cob_sound/SayText.h>
00008
00009 class SayAction
00010 {
00011 protected:
00012
00013 ros::NodeHandle nh_;
00014 actionlib::SimpleActionServer<cob_sound::SayAction> as_;
00015 ros::ServiceServer srvServer_;
00016 ros::ServiceServer srvServer_mute_;
00017 ros::ServiceServer srvServer_unmute_;
00018 ros::Subscriber sub_;
00019 std::string action_name_;
00020 bool mute_;
00021
00022 public:
00023 diagnostic_msgs::DiagnosticArray diagnostics_;
00024 ros::Publisher topicPub_Diagnostic_;
00025
00026 SayAction(std::string name) :
00027 as_(nh_, name, boost::bind(&SayAction::as_cb, this, _1), false),
00028 action_name_(name)
00029 {
00030 as_.start();
00031 srvServer_ = nh_.advertiseService("/say", &SayAction::service_cb, this);
00032 srvServer_mute_ = nh_.advertiseService("mute", &SayAction::service_cb_mute, this);
00033 srvServer_unmute_ = nh_.advertiseService("unmute", &SayAction::service_cb_unmute, this);
00034 sub_ = nh_.subscribe("/say", 1000, &SayAction::topic_cb, this);
00035 topicPub_Diagnostic_ = nh_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00036 mute_ = false;
00037 }
00038
00039 ~SayAction(void)
00040 {
00041 }
00042
00043 void as_cb(const cob_sound::SayGoalConstPtr &goal)
00044 {
00045 bool ret = say(goal->text.data);
00046 if (ret)
00047 {
00048 as_.setSucceeded();
00049 }
00050 else
00051 {
00052 as_.setAborted();
00053 }
00054 }
00055
00056 bool service_cb(cob_sound::SayText::Request &req,
00057 cob_sound::SayText::Response &res )
00058 {
00059 say(req.text);
00060 return true;
00061 }
00062
00063 void topic_cb(const std_msgs::String::ConstPtr& msg)
00064 {
00065 say(msg->data.c_str());
00066 }
00067
00068 bool service_cb_mute(cob_srvs::Trigger::Request &req,
00069 cob_srvs::Trigger::Response &res )
00070 {
00071 mute_ = true;
00072 res.success.data = true;
00073 return true;
00074 }
00075
00076 bool service_cb_unmute(cob_srvs::Trigger::Request &req,
00077 cob_srvs::Trigger::Response &res )
00078 {
00079 mute_ = false;
00080 res.success.data = true;
00081 return true;
00082 }
00083
00084 bool say(std::string text)
00085 {
00086 if (mute_)
00087 {
00088 ROS_WARN("Sound is set to mute. You will hear nothing.");
00089 return true;
00090 }
00091
00092 ROS_INFO("Saying: %s", text.c_str());
00093 std::string mode;
00094 std::string command;
00095 std::string cepstral_conf;
00096 nh_.param<std::string>("/sound_controller/mode",mode,"festival");
00097 nh_.param<std::string>("/sound_controller/cepstral_settings",cepstral_conf,"\"speech/rate=170\"");
00098 if (mode == "cepstral")
00099 {
00100 command = "swift -p " + cepstral_conf + " " + text;
00101 }
00102 else
00103 {
00104 command = "echo " + text + " | text2wave | aplay -q";
00105 }
00106 if (system(command.c_str()) != 0)
00107 {
00108 ROS_ERROR("Could not play sound");
00109
00110 diagnostic_msgs::DiagnosticStatus status;
00111 status.level = 2;
00112 status.name = "sound";
00113 status.message = "command say failed to play sound using mode " + mode;
00114 diagnostics_.status.push_back(status);
00115 diagnostics_.header.stamp = ros::Time::now();
00116 topicPub_Diagnostic_.publish(diagnostics_);
00117 diagnostics_.status.resize(0);
00118 return false;
00119 }
00120
00121 diagnostics_.header.stamp = ros::Time::now();
00122 return true;
00123 }
00124
00125
00126 };
00127
00128
00129 int main(int argc, char** argv)
00130 {
00131 ros::init(argc, argv, "cob_sound");
00132
00133 SayAction say("say");
00134
00135
00136 ros::Rate loop_rate(10);
00137 while (ros::Time::now().toSec() <= 1.0)
00138 {
00139 loop_rate.sleep();
00140 }
00141 say.diagnostics_.header.stamp = ros::Time::now();
00142
00143 ros::Rate r(10);
00144 while (ros::ok())
00145 {
00146 if (ros::Time::now() - say.diagnostics_.header.stamp >= ros::Duration(10))
00147 {
00148
00149 diagnostic_msgs::DiagnosticStatus status;
00150 status.level = 0;
00151 status.name = "sound";
00152 status.message = "sound controller running";
00153 say.diagnostics_.status.push_back(status);
00154 say.diagnostics_.header.stamp = ros::Time::now();
00155 say.topicPub_Diagnostic_.publish(say.diagnostics_);
00156 say.diagnostics_.status.resize(0);
00157 }
00158
00159 ros::spinOnce();
00160 r.sleep();
00161 }
00162 return 0;
00163 }
00164