21 std::cerr <<
"ROS_ROOT not found" << std::endl;
22 std::string rosDistro;
25 rosDistro = ROS_DISTRO;
26 std::cerr <<
"ROS_DISTRO not found, setting " << rosDistro << std::endl;
28 const auto rosRoot =
"/opt/ros/" + rosDistro +
"/share/ros";
29 std::cerr <<
"Setting ROS_ROOT to " << rosRoot << std::endl;
30 ::setenv(
"ROS_ROOT", rosRoot.c_str(),
false);
38 #if PY_MAJOR_VERSION >= 3
39 return PyUnicode_FromStringAndSize(input.c_str(), input.size());
41 return PyString_FromStringAndSize(input.c_str(), input.size());
50 #if PY_MAJOR_VERSION >= 3
52 data = PyUnicode_AsUTF8AndSize(input, &size);
55 PyString_AsStringAndSize(input, &data, &size);
57 return {data,
static_cast<size_t>(size)};
62 PyObject *r = PyObject_GetAttrString(o, name.c_str());
73 PyObject*
getMsgField(
const std::string& messageType,
const std::string& field)
75 if (messageType.empty())
78 const auto slashPos = messageType.find(
'/');
79 if (slashPos == std::string::npos)
81 std::cerr <<
"Message type [" << messageType <<
"] does not contain a slash. It has to be of form "
82 <<
"package/MessageType." << std::endl;
86 const auto package = messageType.substr(0, slashPos);
87 const auto baseMessageType = messageType.substr(slashPos + 1);
91 std::cerr <<
"Package is empty for message type [" << messageType <<
"]" << std::endl;
95 if (baseMessageType.empty())
97 std::cerr <<
"Message type after package is empty for message type [" << messageType <<
"]" << std::endl;
103 std::cerr <<
"Could not find package [" <<
package << "] for message type [" << messageType << "]" << std::endl;
109 PyObject* def {
nullptr};
112 auto pModule = PyImport_Import(pName);
115 if (pModule !=
nullptr) {
117 if (pMessageClass !=
nullptr) {
119 if (pMsgDef !=
nullptr)
127 std::cerr <<
"Error reading message definition from " <<
package << ".msg." << baseMessageType << " !"
133 std::cerr <<
"Failed to load message class " <<
package << ".msg." << baseMessageType << " !" << std::endl;
139 std::cerr <<
"Failed to load module " <<
package << ".msg !" << std::endl;
148 auto pMsgDef =
getMsgField(messageType,
"_full_text");
156 auto pMD5Sum =
getMsgField(messageType,
"_md5sum");
164 auto pHasHeader =
getMsgField(messageType,
"_has_header");
165 if (pHasHeader ==
nullptr)
167 auto hasHeader = PyObject_IsTrue(pHasHeader);
168 Py_XDECREF(pHasHeader);
174 std::vector<std::string> fieldNames;
175 auto pFieldNames =
getMsgField(messageType,
"__slots__");
176 if (pFieldNames !=
nullptr && PyList_Check(pFieldNames))
178 for(Py_ssize_t i = 0; i < PyList_Size(pFieldNames); i++) {
179 const auto pFieldName = PyList_GetItem(pFieldNames, i);
180 if (pFieldName !=
nullptr)
184 Py_XDECREF(pFieldNames);
190 std::vector<std::string> fieldTypes;
191 auto pFieldTypes =
getMsgField(messageType,
"_slot_types");
192 if (pFieldTypes !=
nullptr && PyList_Check(pFieldTypes))
194 for(Py_ssize_t i = 0; i < PyList_Size(pFieldTypes); i++) {
195 const auto pFieldType = PyList_GetItem(pFieldTypes, i);
196 if (pFieldType !=
nullptr)
200 Py_XDECREF(pFieldTypes);
206 if (messageType.empty())
209 const auto slashPos = messageType.find(
'/');
210 if (slashPos == std::string::npos)
212 std::cerr <<
"Message type [" << messageType <<
"] does not contain a slash. It has to be of form "
213 <<
"package/MessageType." << std::endl;
217 const auto package = messageType.substr(0, slashPos);
218 const auto baseMessageType = messageType.substr(slashPos + 1);
222 std::cerr <<
"Package is empty for message type [" << messageType <<
"]" << std::endl;
226 if (baseMessageType.empty())
228 std::cerr <<
"Message type after package is empty for message type [" << messageType <<
"]" << std::endl;
233 if (packagePath.empty())
235 std::cerr <<
"Could not find package [" <<
package << "] for message type [" << messageType << "]" << std::endl;
246 auto path = packagePath + sep +
"msg" + sep + baseMessageType +
".msg";
250 if (stat(path.c_str(), &buffer) != 0)
258 if (messageType.empty())
264 std::cerr <<
"Could not find message proto file for message type [" << messageType <<
"]" << std::endl;
271 auto pModule = PyImport_Import(pName);
274 if (pModule !=
nullptr) {
275 auto pDict = PyModule_GetDict(pModule);
277 auto pFunc = PyDict_GetItem(pDict, pName);
279 if (pFunc !=
nullptr)
282 auto pGetDepsDict = PyObject_CallFunctionObjArgs(pFunc, pName,
nullptr);
285 if (pGetDepsDict !=
nullptr)
288 auto pSpec = PyDict_GetItem(pGetDepsDict, pName);
291 if (pSpec !=
nullptr)
294 auto pFunc2 = PyDict_GetItem(pDict, pName);
296 if (pFunc2 !=
nullptr)
298 auto pMD5Text = PyObject_CallFunctionObjArgs(pFunc2, pGetDepsDict, pSpec,
nullptr);
299 if (pMD5Text !=
nullptr)
303 Py_XDECREF(pMD5Text);
307 Py_XDECREF(pGetDepsDict);
313 std::cerr <<
"Failed to load module roslib.gentools !" << std::endl;