218 zmq::message_t config_msg;
219 auto received = socket.recv(config_msg, zmq::recv_flags::dontwait);
223 auto currentTime = std::chrono::steady_clock::now();
224 std::chrono::duration<double> elapsed_seconds = currentTime - time_last_packet;
225 frequency_ms = elapsed_seconds.count() * 1000;
226 time_last_packet = currentTime;
229 std::string config_json_str(
static_cast<char*
>(config_msg.data()), config_msg.size());
230 nlohmann::json config_json = nlohmann::json::parse(config_json_str);
233 if (config_json.contains(
"timestamp") && config_json[
"timestamp"].is_number())
235 auto arrival_time = std::chrono::duration<double>(
236 std::chrono::system_clock::now().time_since_epoch())
238 double sender_time = config_json[
"timestamp"];
239 latency_ms = (arrival_time - sender_time) * 1000;
245 if (config_json.contains(
"publish_ip") && !publishSocketBound_.load())
248 config_json.erase(
"publish_ip");
254 receivedConfig.read(reader, config_json);
256 for (
auto& pair : this->
limb)
258 auto limbName = pair.first;
259 auto&
limb = pair.second;
261 auto limbConfig = prevCfg.limbs.at(limbName);
262 auto limbConfigNew = receivedConfig.limbs.at(limbName);
263 limbConfig.desiredPose = limbConfigNew.desiredPose;
264 limb->bufferConfigUserToNonRt.getWriteBuffer() =
266 limb->bufferConfigUserToNonRt.commitWrite();
272 this->
hands->updateConfig(receivedConfig.hands);
278 if (not rtTargetSafe)
293 datafields[
"frequency_ms"] =
new Variant(frequency_ms);
294 datafields[
"latency_ms"] =
new Variant(latency_ms);
298 for (
auto& pair : this->
limb)
300 if (not pair.second->rtReady.load())
308 if (!publishSocketBound_.load())
313 nlohmann::json stateJson;
314 stateJson[
"timestamp"] =
315 std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch())
318 auto mat4ToJson = [](
const Eigen::Matrix4f& m)
320 nlohmann::json j = nlohmann::json::array();
321 for (
int r = 0; r < 4; ++r)
322 for (
int c = 0;
c < 4; ++
c)
323 j.push_back(m(r,
c));
328 for (
auto& pair : this->limb)
330 if (not pair.second->rtReady.load())
332 auto rtData = pair.second->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
333 auto rtStatus = pair.second->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
334 const auto& nodeSetName = pair.second->kinematicChainName;
335 const auto& jointNames = pair.second->jointNames;
336 auto jointPosition = rtStatus.jointPosition;
337 auto jointVelocity = rtStatus.jointVelocity;
338 auto jointTorque = rtStatus.jointTorque;
339 auto desiredJointTorque = rtStatus.desiredJointTorque;
340 auto desiredJointVelocity = rtStatus.desiredJointVelocity;
341 auto desiredJointPosition = rtStatus.desiredJointPosition;
342 Eigen::Matrix4f currentPose = rtStatus.currentPose;
343 Eigen::Matrix4f desiredPose = rtStatus.desiredPose;
345 for (
size_t i = 0; i < jointNames.size(); ++i)
347 stateJson[nodeSetName][
"jointPosition"][jointNames[i]] = jointPosition(i);
348 stateJson[nodeSetName][
"jointVelocity"][jointNames[i]] = jointVelocity(i);
349 stateJson[nodeSetName][
"jointTorque"][jointNames[i]] = jointTorque(i);
350 stateJson[nodeSetName][
"desiredJointTorque"][jointNames[i]] = desiredJointTorque(i);
351 stateJson[nodeSetName][
"desiredJointVelocity"][jointNames[i]] = desiredJointVelocity(i);
352 stateJson[nodeSetName][
"desiredJointPosition"][jointNames[i]] = desiredJointPosition(i);
354 stateJson[nodeSetName][
"currentPose"] = mat4ToJson(currentPose);
355 stateJson[nodeSetName][
"desiredPose"] = mat4ToJson(desiredPose);
361 for (
auto& [handName, hand] : this->
hands->hands)
363 const auto& jointNames = hand->jointNames;
364 const auto desiredConfig =
365 hand->bufferConfigNonRTToOnPublish.getUpToDateReadBuffer();
366 const auto currentJointPositionMap = hand->ctrl->getJointValuesMap();
368 for (
size_t i = 0; i < jointNames.size(); ++i)
370 const auto it = currentJointPositionMap.find(jointNames[i]);
371 stateJson[handName][
"jointPosition"][jointNames[i]] =
372 (it != currentJointPositionMap.end()) ? it->second : 0.F;
373 if (desiredConfig.jointPosition.has_value())
375 stateJson[handName][
"desiredJointPosition"][jointNames[i]] =
376 desiredConfig.jointPosition.value()(i);
382 nlohmann::json metadata_json;
383 metadata_json[
"name"] =
"robot_state";
384 metadata_json[
"type"] =
"json";
385 metadata_json[
"timestamp_processed"] = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
386 std::string metadata_string = metadata_json.dump();
389 const std::string stateStr = stateJson.dump();
390 zmq::message_t msg(stateStr.size());
391 std::memcpy(msg.data(), stateStr.data(), stateStr.size());
392 zmq::message_t metadata_msg(metadata_string.size());
393 memcpy(metadata_msg.data(), metadata_string.data(), metadata_string.size());
396 std::unique_lock<std::mutex> lock(publishSocketMutex_);
397 publishSocket_.send(metadata_msg, zmq::send_flags::sndmore);
398 publishSocket_.send(msg, zmq::send_flags::dontwait);
400 catch (
const zmq::error_t& e)