I would like to implement a plugin that switches back and forth between two albedo map files. In addition, I am closely following the command actor plugin tutorial from the repository (gz-sim/examples/plugin/command_actor/CommandActor.cc at gz-sim8 · gazebosim/gz-sim · GitHub)
// SatelliteGround.hh
namespace ros_gz_example_gazebo
{
class SatelliteGround:
public gz::sim::System,
public gz::sim::ISystemConfigure,
public gz::sim::ISystemPreUpdate
{
public:
void Configure(
const gz::sim::Entity &_entity,
const std::shared_ptr<const sdf::Element> &_sdf,
gz::sim::EntityComponentManager &_ecm,
gz::sim::EventManager &_eventManager
) override;
void PreUpdate(
const gz::sim::UpdateInfo &_info,
gz::sim::EntityComponentManager &_ecm
) override;
private:
gz::sim::Entity entity;
gz::sim::Entity visualEntity{gz::sim::kNullEntity};
gz::common::Timer timer;
bool toggle{false};
std::chrono::steady_clock::time_point lastUpdateTime;
const std::chrono::seconds updateInterval{2};
std::string texture1{"materials/textures/charuco_board_pattern.png"};
std::string texture2{"materials/textures/circles_pattern.png"};
};
}
// SatelliteGround.cc
#include <iostream>
#include <gz/plugin/Register.hh>
#include <gz/sim/components/Material.hh>
#include <gz/sim/components/Name.hh>
#include <gz/sim/EntityComponentManager.hh>
#include <gz/sim/EventManager.hh>
#include <gz/sim/System.hh>
#include <gz/rendering/RenderingIface.hh>
#include <gz/rendering/RenderEngine.hh>
#include <gz/sim/rendering/Events.hh>
#include <sdf/Pbr.hh>
#include <gz/rendering/Material.hh>
#include <gz/rendering/RenderTypes.hh>
#include "ros_gz_example_gazebo/SatelliteGround.hh"
using namespace ros_gz_example_gazebo;
void SatelliteGround::Configure(
const gz::sim::Entity &_entity,
const std::shared_ptr<const sdf::Element> &_sdf,
gz::sim::EntityComponentManager &_ecm,
gz::sim::EventManager &_eventManager
)
{
std::cout << "ros_gz_example_gazebo::SatelliteGround::Configure on entity: " << _entity << std::endl;
this->entity = _entity;
// Find the visual entity by its name
this->visualEntity = _ecm.EntityByComponents(
gz::sim::components::Name("ground_plane_visual"));
if (this->visualEntity == gz::sim::kNullEntity)
{
std::cerr << "Error: Visual entity not found." << std::endl;
return;
}
// Initialize the last update time
this->lastUpdateTime = std::chrono::steady_clock::now();
}
void SatelliteGround::PreUpdate(
const gz::sim::UpdateInfo &_info,
gz::sim::EntityComponentManager &_ecm)
{
auto currentTime = std::chrono::steady_clock::now();
if (currentTime - this->lastUpdateTime >= this->updateInterval)
{
// Retrieve the material component
auto materialComp = _ecm.Component<gz::sim::components::Material>(this->visualEntity);
if (!materialComp)
{
std::cerr << "Error: Material component not found." << std::endl;
return;
}
sdf::Material newMaterial;
sdf::Pbr pbr;
sdf::PbrWorkflow pbrWorkflow;
std::string texturePath;
if (this->toggle)
{
texturePath = this->texture1;
}
else
{
texturePath = this->texture2;
}
pbrWorkflow.SetAlbedoMap(texturePath);
pbrWorkflow.SetRoughness(0.6);
pbrWorkflow.SetMetalness(0.0);
pbr.SetWorkflow(sdf::PbrWorkflowType::METAL, pbrWorkflow);
newMaterial.SetAmbient(gz::math::Color(0.8, 0.8, 0.8, 1));
newMaterial.SetDiffuse(gz::math::Color(0.8, 0.8, 0.8, 1));
newMaterial.SetSpecular(gz::math::Color(0.8, 0.8, 0.8, 1));
newMaterial.SetPbrMaterial(pbr);
*materialComp = gz::sim::components::Material(newMaterial);
_ecm.SetChanged(
this->entity,
gz::sim::components::Material::typeId,
gz::sim::ComponentState::OneTimeChange
);
this->lastUpdateTime = currentTime;
}
}
GZ_ADD_PLUGIN(
ros_gz_example_gazebo::SatelliteGround,
gz::sim::System,
ros_gz_example_gazebo::SatelliteGround::ISystemConfigure,
ros_gz_example_gazebo::SatelliteGround::ISystemPreUpdate
)
It compiles and runs but the changes are not reflected visually on the simulation. What am I missing?