26#include <ignition/math/Color.hh>
28#include <gazebo/common/Plugin.hh>
29#include <gazebo/msgs/msgs.hh>
30#include <gazebo/physics/physics.hh>
31#include <gazebo/transport/transport.hh>
33#include <boost/algorithm/string.hpp>
37 using namespace gazebo;
49 public: ignition::math::Color
color;
69 const gazebo::physics::ModelPtr &_model,
70 const std::string &_lightName,
const std::string &_linkName)
72 auto childLink = _model->GetChildLink(_linkName);
73 if (childLink && childLink->GetSDF()->HasElement(
"light"))
75 auto sdfLight = childLink->GetSDF()->GetElement(
"light");
78 if (sdfLight->Get<std::string>(
"name") == _lightName)
82 sdfLight = sdfLight->GetNextElement(
"light");
85 for (
auto model: _model->NestedModels())
101 public: gazebo::physics::LinkPtr
link;
125 public: std::vector< std::shared_ptr<Block> >
blocks;
140 public: std::shared_ptr<FlashLightSetting>
142 const std::string &_lightName,
const std::string &_linkName)
const
146 if (setting->Name() == _lightName)
148 if (_linkName.length() == 0
149 || setting->Link()->GetName() == _linkName)
160 public: gazebo::physics::ModelPtr
model;
163 public: gazebo::physics::WorldPtr
world;
166 public: gazebo::transport::NodePtr
node;
179using namespace gazebo;
185 const sdf::ElementPtr &_sdf,
186 const gazebo::physics::ModelPtr &_model,
187 const gazebo::common::Time &_currentTime,
188 gazebo_ros::Node::SharedPtr rosnode)
193 if (_sdf->HasElement(
"id"))
195 lightId = _sdf->Get<std::string>(
"id");
199 gzerr <<
"Parameter <id> is missing." << std::endl;
201 int posDelim = lightId.rfind(
"/");
202 this->
dataPtr->name = lightId.substr(posDelim+1, lightId.length());
207 lightId.substr(0, posDelim));
209 if (_sdf->HasElement(
"block"))
211 sdf::ElementPtr sdfBlock = _sdf->GetElement(
"block");
214 auto block = std::make_shared<Block>();
216 if (sdfBlock->HasElement(
"duration"))
218 block->duration = sdfBlock->Get<
double>(
"duration");
223 block->duration = std::numeric_limits<double>::max();
227 if (sdfBlock->HasElement(
"interval"))
229 block->interval = sdfBlock->Get<
double>(
"interval");
234 block->interval = std::numeric_limits<double>::max();
238 if (sdfBlock->HasElement(
"color"))
240 block->color = sdfBlock->Get<ignition::math::Color>(
"color");
244 block->color.Reset();
247 this->
dataPtr->blocks.push_back(block);
248 sdfBlock = sdfBlock->GetNextElement(
"block");
253 auto block = std::make_shared<Block>();
255 if (_sdf->HasElement(
"duration"))
257 block->duration = _sdf->Get<
double>(
"duration");
262 block->duration = std::numeric_limits<double>::max();
266 if (_sdf->HasElement(
"interval"))
268 block->interval = _sdf->Get<
double>(
"interval");
273 block->interval = std::numeric_limits<double>::max();
277 if (_sdf->HasElement(
"color"))
279 block->color = _sdf->Get<ignition::math::Color>(
"color");
283 block->color.Reset();
286 this->
dataPtr->blocks.push_back(block);
290 this->
dataPtr->startTime = _currentTime;
315 if (this->
dataPtr->link->GetSDF()->HasElement(
"light"))
317 auto sdfLight = this->
dataPtr->link->GetSDF()->GetElement(
"light");
320 if (sdfLight->Get<std::string>(
"name") == this->
dataPtr->name)
323 = sdfLight->GetElement(
"attenuation")->Get<
double>(
"range");
326 sdfLight = sdfLight->GetNextElement(
"light");
328 this->
dataPtr->lightExists =
true;
340 const gazebo::transport::PublisherPtr &_pubLight)
343 this->
dataPtr->pubLight = _pubLight;
345 if (this->
dataPtr->lightExists)
349 this->
dataPtr->link->GetScopedName() +
"::" + this->dataPtr->name);
435 this->
dataPtr->switchOn =
true;
441 gzmsg <<
"switch off" << std::endl;
443 this->
dataPtr->switchOn =
false;
449 if (0 <= _index && _index <
static_cast<int>(this->
dataPtr->blocks.size()))
451 this->
dataPtr->blocks[_index]->duration = _duration;
455 gzerr <<
"The given index for block is out of range." << std::endl;
462 for (
auto block: this->
dataPtr->blocks)
464 block->duration = _duration;
471 if (0 <= _index && _index <
static_cast<int>(this->
dataPtr->blocks.size()))
473 this->
dataPtr->blocks[_index]->interval = _interval;
477 gzerr <<
"The given index for block is out of range." << std::endl;
484 for (
auto block: this->
dataPtr->blocks)
486 block->interval = _interval;
492 const ignition::math::Color &_color,
const int _index)
494 if (0 <= _index && _index <
static_cast<int>(this->
dataPtr->blocks.size()))
496 this->
dataPtr->blocks[_index]->color = _color;
500 gzerr <<
"The given index for block is out of range." << std::endl;
507 for (
auto block: this->
dataPtr->blocks)
509 block->color = _color;
516 return this->
dataPtr->blocks.size();
522 if (_index < 0 ||
static_cast<int>(this->
dataPtr->blocks.size()) <= _index)
527 this->
dataPtr->blocks.erase(this->
dataPtr->blocks.begin() + _index);
534 const double _duration,
const double _interval,
535 const ignition::math::Color &_color,
const int _index)
537 auto block = std::make_shared<Block>();
539 block->duration = _duration;
540 block->interval = _interval;
541 block->color = _color;
543 if (_index < 0 ||
static_cast<int>(this->
dataPtr->blocks.size()) <= _index)
545 this->
dataPtr->blocks.push_back(block);
549 this->
dataPtr->blocks.insert(this->
dataPtr->blocks.begin() + _index, block);
559 if (this->
dataPtr->blocks[this->dataPtr->currentBlockIndex]->color
560 != ignition::math::Color::Black)
562 msgs::Set(this->
dataPtr->msg.mutable_diffuse(),
563 this->dataPtr->blocks[this->dataPtr->currentBlockIndex]->color);
564 msgs::Set(this->
dataPtr->msg.mutable_specular(),
565 this->dataPtr->blocks[this->dataPtr->currentBlockIndex]->color);
568 if (this->
dataPtr->lightExists)
573 this->
dataPtr->flashing =
true;
580 this->
dataPtr->msg.set_range(0.0);
582 if (this->
dataPtr->lightExists)
587 this->
dataPtr->flashing =
false;
593 return this->
dataPtr->blocks[this->
dataPtr->currentBlockIndex]->color;
601 this->
dataPtr->node = gazebo::transport::NodePtr(
new gazebo::transport::Node());
620 this->
dataPtr->model = _parent;
621 this->
dataPtr->world = _parent->GetWorld();
623 auto node = gazebo_ros::Node::Get(_sdf);
625 gazebo::common::Time currentTime = this->
dataPtr->world->SimTime();
628 if (_sdf->HasElement(
"light"))
630 sdf::ElementPtr sdfFlashLight = _sdf->GetElement(
"light");
631 while (sdfFlashLight)
634 if (sdfFlashLight->HasElement(
"id"))
637 std::shared_ptr<FlashLightSetting> setting
639 sdfFlashLight, this->
dataPtr->model, currentTime, node);
645 this->
dataPtr->listFlashLight.push_back(setting);
650 gzerr <<
"id does not exist in <light>" << std::endl;
653 sdfFlashLight = sdfFlashLight->GetNextElement(
"light");
657 if (_sdf->HasElement(
"enable"))
659 if (_sdf->Get<
bool>(
"enable"))
669 if (_sdf->HasElement(
"light"))
671 sdf::ElementPtr sdfFlashLight = _sdf->GetElement(
"light");
672 while (sdfFlashLight)
674 if (sdfFlashLight->HasElement(
"enable"))
676 std::string lightId = sdfFlashLight->Get<std::string>(
"id");
677 int posDelim = lightId.rfind(
"/");
678 std::string lightName = lightId.substr(posDelim+1, lightId.length());
679 std::string linkName = lightId.substr(0, posDelim);
680 if (sdfFlashLight->Get<
bool>(
"enable"))
682 this->
TurnOn(lightName, linkName);
686 this->
TurnOff(lightName, linkName);
690 sdfFlashLight = sdfFlashLight->GetNextElement(
"light");
695 if (!this->
dataPtr->listFlashLight.empty())
697 this->
dataPtr->updateConnection = event::Events::ConnectWorldUpdateBegin(
701 rclcpp::SensorDataQoS qos;
703 auto topicname =
"/"+ this->
dataPtr->model->GetName()+
"/cmdled";
705 boost::replace_all(topicname,
"::",
"/");
707 gzmsg <<
"topicname: " << topicname <<
"\n";
710 node->create_subscription<std_msgs::msg::Int8>(topicname, qos,
712 (
const std_msgs::msg::Int8::SharedPtr msg)
714 RCLCPP_INFO(node->get_logger(),
"msg received");
727 gazebo::common::Time currentTime = this->
dataPtr->world->SimTime();
729 for (
auto &setting: this->
dataPtr->listFlashLight)
732 setting->UpdateLightInEnv(currentTime);
739 return this->
TurnOn(_lightName,
"");
744 const std::string &_lightName,
const std::string &_linkName)
746 std::shared_ptr<FlashLightSetting> setting
747 = this->
dataPtr->SettingByLightNameAndLinkName(_lightName, _linkName);
755 gzerr <<
"light: [" + _linkName +
"/" + _lightName +
"] does not exist."
763 if (this->
dataPtr->listFlashLight.empty())
765 gzerr <<
"no flash lights exist to turn on." << std::endl;
769 for (
auto &setting: this->
dataPtr->listFlashLight)
780 return this->
TurnOff(_lightName,
"");
785 const std::string &_linkName)
787 std::shared_ptr<FlashLightSetting> setting
788 = this->
dataPtr->SettingByLightNameAndLinkName(_lightName, _linkName);
792 setting->SwitchOff();
796 gzerr <<
"light: [" + _linkName +
"/" + _lightName +
"] does not exist."
804 gzmsg <<
"msg TurnOffAll" << std::endl;
805 if (this->
dataPtr->listFlashLight.empty())
807 gzerr <<
"no flash lights exist to turn off." << std::endl;
811 gzmsg <<
"switch off" << std::endl;
813 for (
auto &setting: this->
dataPtr->listFlashLight)
815 setting->SwitchOff();
823 const std::string &_lightName,
const std::string &_linkName,
824 const double _duration,
const int _index
827 std::shared_ptr<FlashLightSetting> setting
828 = this->
dataPtr->SettingByLightNameAndLinkName(_lightName, _linkName);
834 setting->SetDuration(_duration, _index);
838 setting->SetDuration(_duration);
843 gzerr <<
"light <" + _lightName +
"> does not exist." << std::endl;
849 const std::string &_lightName,
const std::string &_linkName,
850 const double _duration
853 return this->
ChangeDuration(_lightName, _linkName, _duration, -1);
858 const std::string &_lightName,
const std::string &_linkName,
859 const double _interval,
const int _index
862 std::shared_ptr<FlashLightSetting> setting
863 = this->
dataPtr->SettingByLightNameAndLinkName(_lightName, _linkName);
869 setting->SetInterval(_interval, _index);
873 setting->SetInterval(_interval);
878 gzerr <<
"light <" + _lightName +
"> does not exist." << std::endl;
884 const std::string &_lightName,
const std::string &_linkName,
885 const double _interval
888 return this->
ChangeInterval(_lightName, _linkName, _interval, -1);
893 const std::string &_lightName,
const std::string &_linkName,
894 const ignition::math::Color &_color,
const int _index
897 std::shared_ptr<FlashLightSetting> setting
898 = this->
dataPtr->SettingByLightNameAndLinkName(_lightName, _linkName);
904 setting->SetColor(_color, _index);
908 setting->SetColor(_color);
913 gzerr <<
"light <" + _lightName +
"> does not exist." << std::endl;
919 const std::string &_lightName,
const std::string &_linkName,
920 const ignition::math::Color &_color
923 return this->
ChangeColor(_lightName, _linkName, _color, -1);
927std::shared_ptr<FlashLightSetting>
929 const sdf::ElementPtr &_sdf,
930 const gazebo::physics::ModelPtr &_model,
931 const gazebo::common::Time &_currentTime,
932 gazebo_ros::Node::SharedPtr node)
934 return std::make_shared<FlashLightSetting>(_sdf, _model, _currentTime, node);
939 std::shared_ptr<FlashLightSetting> &_setting)
941 _setting->InitPubLight(this->
dataPtr->pubLight);
gazebo::physics::ModelPtr model
pointer to the model.
std::shared_ptr< FlashLightSetting > SettingByLightNameAndLinkName(const std::string &_lightName, const std::string &_linkName) const
Find a setting by names. This is internally used to access an individual setting. If the link name is...
gazebo::physics::WorldPtr world
pointer to the world.
gazebo::transport::NodePtr node
The pointer to node for communication.
gazebo::transport::PublisherPtr pubLight
The pointer to publisher to send a command to the light.
event::ConnectionPtr updateConnection
pointer to the update even connection.
std::vector< std::shared_ptr< FlashLightSetting > > listFlashLight
The list of flashlight settings to control.
virtual bool TurnOffAll() final
Turn off all flash lights.
virtual ~FlashLightPlugin()
Destructor.
rclcpp::Subscription< std_msgs::msg::Int8 >::SharedPtr cmdledsubscription
virtual bool TurnOnAll() final
Turn on all flash lights.
void Load(gazebo::physics::ModelPtr _parent, sdf::ElementPtr _sdf) override
virtual void OnUpdate()
Called by the world update start event.
virtual bool ChangeColor(const std::string &_lightName, const std::string &_linkName, const ignition::math::Color &_color, const int _index) final
Change the color of a specific block of the flashlight. If the index is a negative number,...
virtual bool TurnOn(const std::string &_lightName) final
Turn on a flash light specified by the light name If more than one link have lights with the identica...
virtual bool TurnOff(const std::string &_lightName) final
Turn off a flash light specified by the name If more than one link have lights with the identical nam...
FlashLightPlugin()
Constructor.
std::unique_ptr< FlashLightPluginPrivate > dataPtr
Pointer to private data.
virtual void InitSettingBySpecificData(std::shared_ptr< FlashLightSetting > &_setting)
Initialize the additional part of an object of setting.
virtual std::shared_ptr< FlashLightSetting > CreateSetting(const sdf::ElementPtr &_sdf, const gazebo::physics::ModelPtr &_model, const gazebo::common::Time &_currentTime, gazebo_ros::Node::SharedPtr node)
Create an object of setting.
virtual bool ChangeInterval(const std::string &_lightName, const std::string &_linkName, const double _interval, const int _index) final
Change the interval of a specific block of the flashlight. If the index is a negative number,...
virtual bool ChangeDuration(const std::string &_lightName, const std::string &_linkName, const double _duration, const int _index) final
Change the duration of a specific block of the flashlight. If the index is a negative number,...
gazebo::common::Time startTime
The time at which the current phase started.
bool lightExists
True if <light> element exists.
gazebo::transport::PublisherPtr pubLight
The pointer to publisher to send a command to a light.
std::string name
The name of flash light.
gazebo::physics::LinkPtr link
Link which holds this flash light.
bool switchOn
The current switch state (the light itself is active or not).
FlashLightSettingPrivate()
Constructor.
gazebo::physics::LinkPtr FindLinkForLight(const gazebo::physics::ModelPtr &_model, const std::string &_lightName, const std::string &_linkName)
Find the link holding the light to control. If multiple models are nested, this function is recursive...
double range
The length of the ray (in meters).
msgs::Light msg
A message holding a flashlight command.
int currentBlockIndex
the index of the current block.
bool flashing
The current flasshing state (flash or dim).
std::vector< std::shared_ptr< Block > > blocks
The list of blocks of light.
virtual void SetDuration(const double _duration, const int _index) final
Set the duration time for the specified block.
virtual void InitPubLight(const gazebo::transport::PublisherPtr &_pubLight) final
Set the publisher and send an initial light command.
virtual unsigned int BlockCount() final
Get the number of blocks.
virtual void UpdateLightInEnv(const gazebo::common::Time &_currentTime) final
Update the light based on the given time.
std::unique_ptr< FlashLightSettingPrivate > dataPtr
Pointer to private data.
virtual void InsertBlock(const double _duration, const double _interval, const ignition::math::Color &_color, const int _index) final
Insert a block. Create a block with specified parameters. If the index is out of range,...
virtual const std::string Name() const final
Getter of name.
virtual void SwitchOn() final
Switch on (enable the flashlight).
virtual void Dim()
Dim the light This function is internally used to update the light in the environment.
virtual const gazebo::physics::LinkPtr Link() const final
Getter of link.
virtual ignition::math::Color CurrentColor() final
Get the current color of the light. This is to be used by an inheriting class of FlashLightSetting cl...
virtual void SetInterval(const double _interval, const int _index) final
Set the interval time for the specified block.
virtual void Flash()
Flash the light This function is internally used to update the light in the environment.
virtual void SwitchOff() final
Switch off (disable the flashlight).
virtual ~FlashLightSetting()
Destructor.
virtual void SetColor(const ignition::math::Color &_color, const int _index) final
Set the color for the specified block.
FlashLightSetting(const sdf::ElementPtr &_sdf, const gazebo::physics::ModelPtr &_model, const gazebo::common::Time &_currentTime, gazebo_ros::Node::SharedPtr node)
Constructor. Initialize the setting by the data given to the base plugin.
virtual bool RemoveBlock(const int _index) final
Remove a specified block.
double duration
The duration time to flash (in seconds).
double interval
The interval time between flashing (in seconds). When it is zero, the light is constant.
ignition::math::Color color
The color of light.