symbol_controller.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #include <algorithm>
19 #include <gazebo/physics/Model.hh>
20 #include <ignition/math/Rand.hh>
21 
23 
31 static std_msgs::ColorRGBA createColor(const double _r,
32  const double _g, const double _b, const double _a)
33 {
34  static std_msgs::ColorRGBA color;
35  color.r = _r;
36  color.g = _g;
37  color.b = _b;
38  color.a = _a;
39  return color;
40 }
41 
42 // Static initialization.
43 std::map<std::string, std_msgs::ColorRGBA> SymbolController::kColors =
44  {
45  {"red", createColor(1.0, 0.0, 0.0, 1.0)},
46  {"green", createColor(0.0, 1.0, 0.0, 1.0)},
47  {"blue", createColor(0.0, 0.0, 1.0, 1.0)},
48  };
49 std::vector<std::string> SymbolController::kShapes =
50  {"circle", "cross", "triangle"};
51 
53 void SymbolController::Load(gazebo::physics::ModelPtr _parent,
54  sdf::ElementPtr _sdf)
55 {
56  GZ_ASSERT(_parent != nullptr, "Received NULL model pointer");
57 
58  // Quit if ros plugin was not loaded
59  if (!ros::isInitialized())
60  {
61  ROS_ERROR("ROS was not initialized.");
62  return;
63  }
64 
65  // Load namespace from SDF if available. Otherwise, use the model name.
66  std::string modelName = _parent->GetName();
67  auto delim = modelName.find(":");
68  if (delim != std::string::npos)
69  modelName = modelName.substr(0, delim);
70 
71 
72  std::string ns = modelName;
73  if (_sdf->HasElement("robotNamespace"))
74  ns = _sdf->GetElement("robotNamespace")->Get<std::string>();
75  else
76  {
77  ROS_DEBUG_NAMED("symbolController",
78  "missing <robotNamespace>, defaulting to %s", ns.c_str());
79  }
80 
81  // Parse the shape. We initialize it with a random shape.
82  this->ShuffleShape();
83  if (_sdf->HasElement("shape"))
84  {
85  std::string aShape = _sdf->GetElement("shape")->Get<std::string>();
86  std::transform(aShape.begin(), aShape.end(), aShape.begin(), ::tolower);
87  // Sanity check: Make sure the shape is allowed.
88  if (std::find(this->kShapes.begin(), this->kShapes.end(), aShape) !=
89  this->kShapes.end())
90  {
91  this->shape = aShape;
92  }
93  else
94  {
95  ROS_INFO_NAMED("symbolController",
96  "incorrect [%s] <shape>, using random shape", aShape.c_str());
97  }
98  }
99 
100  // Parse the color. We initialize it with a random color.
101  this->ShuffleColor();
102  if (_sdf->HasElement("color"))
103  {
104  std::string aColor = _sdf->GetElement("color")->Get<std::string>();
105  std::transform(aColor.begin(), aColor.end(), aColor.begin(), ::tolower);
106  // Sanity check: Make sure the color is allowed.
107  if (this->kColors.find(aColor) != this->kColors.end())
108  {
109  this->color = aColor;
110  }
111  else
112  {
113  ROS_INFO_NAMED("symbolController",
114  "incorrect [%s] <color>, using random color", aColor.c_str());
115  }
116  }
117 
118  this->nh = ros::NodeHandle(ns);
119 
120  // Create publisher to set symbols
121  auto iterShapes = this->kShapes.begin();
122  for (auto i = 0; i < this->kShapes.size(); ++i)
123  {
124  std::string topic = *iterShapes;
125  std::advance(iterShapes, 1);
126  this->symbolPubs.push_back(
127  this->nh.advertise<std_msgs::ColorRGBA>(topic, 1u, true));
128  }
129 
130  // This timer is used to defer the symbol publication a few seconds to make
131  // sure that all subscribers receive the message.
132  this->timer = this->nh.createTimer(
133  ros::Duration(5.0), &SymbolController::Publish, this, true);
134 
135  // Advertise the service to shuffle shape and color.
136  this->changePatternServer = this->nh.advertiseService(
137  "shuffle", &SymbolController::Shuffle, this);
138 }
139 
141 bool SymbolController::Shuffle(std_srvs::Trigger::Request &/*_req*/,
142  std_srvs::Trigger::Response &_res)
143 {
144  this->Shuffle();
145  _res.success = true;
146  return _res.success;
147 }
148 
151 {
152  this->ShuffleShape();
153  this->ShuffleColor();
154  this->Publish();
155 }
156 
159 {
160  std::string newShape;
161  do
162  {
163  newShape =
164  this->kShapes[ignition::math::Rand::IntUniform(0,
165  this->kShapes.size() - 1)];
166  }
167  while (newShape == this->shape);
168  this->shape = newShape;
169 }
170 
173 {
174  std::string newColor;
175  do
176  {
177  auto iterColor = this->kColors.begin();
178  std::advance(iterColor,
179  ignition::math::Rand::IntUniform(0, this->kColors.size() - 1));
180  newColor = (*iterColor).first;
181  }
182  while (newColor == this->color);
183  this->color = newColor;
184 }
185 
188 {
189  this->Publish();
190 }
191 
194 {
195  for (auto i = 0; i < this->kShapes.size(); ++i)
196  {
197  std_msgs::ColorRGBA msg;
198  msg.a = 0.0;
199 
200  auto topic = this->symbolPubs[i].getTopic();
201  auto delim = topic.rfind("/");
202  auto aShape = topic.substr(delim + 1);
203  if (aShape == this->shape)
204  msg = this->kColors[this->color];
205 
206  this->symbolPubs[i].publish(msg);
207  }
208 }
209 
210 // Register plugin with gazebo
GZ_REGISTER_MODEL_PLUGIN(GazeboRosElevator)
msg
std::string color
The current color.
void Shuffle()
Create a new combination of shape/color.
static std_msgs::ColorRGBA createColor(const double _r, const double _g, const double _b, const double _a)
Creates a std_msgs::ColorRGBA message from 4 doubles.
#define ROS_INFO_NAMED(name,...)
ros::NodeHandle nh
Node handle.
ROSCPP_DECL bool isInitialized()
virtual void Load(gazebo::physics::ModelPtr _parent, sdf::ElementPtr _sdf)
std::vector< ros::Publisher > symbolPubs
Publisher to set the color to each of the 3 potential shapes.
static std::map< std::string, std_msgs::ColorRGBA > kColors
List of the color options (red, green, blue, and no color) with their string name for logging...
#define ROS_DEBUG_NAMED(name,...)
void ShuffleColor()
Choose a new random color.
Controls the shape and color of a symbol.
std::string shape
The current shape.
static std::vector< std::string > kShapes
List of the shape options (circle, cross, triangle) with their string name for logging.
ros::Timer timer
Timer triggered in simulated time to update the shape/color for.
ros::ServiceServer changePatternServer
Service to generate a new random shape/color.
#define ROS_ERROR(...)
void Publish()
Publish the current shape/color combination.
void ShuffleShape()
Choose a new random shape.


vmrc_gazebo
Author(s): Brian Bingham , Carlos Aguero
autogenerated on Sun Feb 17 2019 03:14:16