4 #include <gazebo/sensors/Sensor.hh>
6 #include <boost/filesystem.hpp>
8 #include <gazebo/physics/PhysicsFactory.hh>
9 #include <gazebo/sensors/SensorManager.hh>
12 #include <ignition/common/StringUtils.hh>
14 namespace fs = boost::filesystem;
31 "gazebo_custom_sensor_preloader",
"gazebo::sensors::Sensor");
34 for (
const auto& name : names)
37 if (ignition::common::StartsWith(name,
"sensors/"))
39 const auto parts = ignition::common::Split(name,
'/');
40 if (parts.size() != 2 || parts[1].empty())
42 gzerr <<
"CustomSensorPreloader: Wrong 'name' attribute of custom "
43 <<
"sensor. It should have the form 'sensors/sensor_type', got "
51 if (name.find(
'/') != std::string::npos)
53 gzerr <<
"CustomSensorPreloader: Wrong 'name' attribute of custom "
54 <<
"sensor. It should have the form 'sensors/sensor_type', got "
60 gzwarn <<
"CustomSensorPreloader: Attribute 'name' of custom sensor '"
61 << name <<
"' is missing the 'sensors/' prefix. This may lead "
62 <<
"to name collisions. Consider adding the prefix."
69 const auto classParts = ignition::common::Split(classType,
':');
71 if (classParts.size() != 5)
73 gzerr <<
"CustomSensorPreloader: Attribute 'type' of custom sensor "
74 << name <<
" should have the form 'gazebo::sensors::ClassName', "
75 <<
"got '" << classType <<
"' instead." << std::endl;
79 const auto classname = classParts.back();
84 gzerr <<
"CustomSensorPreloader: Could not find path to the library of "
85 <<
"custom sensor '" << name <<
"'." << std::endl;
88 else if (!fs::exists(fullname))
90 gzerr <<
"CustomSensorPreloader: Library '" << fullname <<
"' of custom "
91 <<
"sensor '" << name <<
"' does not exists." << std::endl;
113 const size_t max_iterations = 2000000;
115 while (!gazebo::physics::PhysicsFactory::IsRegistered(
"ode") && it < max_iterations)
124 const auto registerFunc = std::get<0>(*tuple);
125 const auto type = std::get<1>(*tuple);
126 const auto classname = std::get<2>(*tuple);
127 const auto fullname = std::get<3>(*tuple);
132 std::vector<std::string> types;
133 sensors::SensorManager::Instance()->GetSensorTypes(types);
135 if (std::find(types.begin(), types.end(), type) == types.end())
137 gzwarn <<
"CustomSensorPreloader: Custom sensor " << classname
138 <<
" from library " << fullname
139 <<
" was preloaded, but it did not register a sensor of type "
140 << type << std::endl;
144 gzmsg <<
"CustomSensorPreloader: Preloaded custom sensor " << classname
145 <<
" from library " << fullname << std::endl;
149 this->sensorsToRegister.clear();
153 const std::string& _classname,
const std::string& _fullname)
156 const auto path = fs::path(_fullname);
157 auto filename = path.filename().string();
158 const auto libraryDir = path.parent_path();
165 size_t soSuffix = filename.rfind(
".so");
166 if (soSuffix != std::string::npos)
168 const std::string macSuffix(
".dylib");
169 filename.replace(soSuffix, macSuffix.length(), macSuffix);
175 size_t soSuffix = filename.rfind(
".so");
176 if (soSuffix != std::string::npos)
178 const std::string winSuffix(
".dll");
179 filename.replace(soSuffix, winSuffix.length(), winSuffix);
181 size_t libPrefix = filename.find(
"lib");
185 filename.erase(0, 3);
188 #endif // ifdef __APPLE__
190 const auto fullname = (libraryDir / fs::path(filename)).
string();
192 void *dlHandle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
195 gzerr <<
"CustomSensorPreloader: Failed to load custom sensor library "
196 << fullname <<
": " << dlerror() << std::endl;
201 const auto registerFuncName =
"Register" + _classname;
202 const auto registerFunc = (
registerFuncType) dlsym(dlHandle, registerFuncName.c_str());
206 gzerr <<
"CustomSensorPreloader: Failed to resolve registration function "
207 << registerFuncName <<
": " << dlerror() << std::endl
208 <<
"Did you call GZ_REGISTER_STATIC_SENSOR(\"" << _type <<
"\", "
209 << _classname <<
") inside your sensor source file?" << std::endl;
215 std::make_tuple(registerFunc, _type, _classname, fullname)));