216 zmq::message_t config_msg;
217 auto received = socket.recv(config_msg, zmq::recv_flags::dontwait);
221 auto currentTime = std::chrono::steady_clock::now();
222 std::chrono::duration<double> elapsed_seconds = currentTime - time_last_packet;
223 frequency_ms = elapsed_seconds.count() * 1000;
224 time_last_packet = currentTime;
227 std::string config_json_str(
static_cast<char*
>(config_msg.data()), config_msg.size());
228 nlohmann::json config_json = nlohmann::json::parse(config_json_str);
231 if (config_json.contains(
"timestamp") && config_json[
"timestamp"].is_number())
233 auto arrival_time = std::chrono::duration<double>(
234 std::chrono::system_clock::now().time_since_epoch())
236 double sender_time = config_json[
"timestamp"];
237 latency_ms = (arrival_time - sender_time) * 1000;
243 if (config_json.contains(
"publish_ip") && !publishSocketBound_.load())
246 config_json.erase(
"publish_ip");
252 receivedConfig.read(reader, config_json);
254 for (
auto& pair : this->
limb)
256 auto limbName = pair.first;
257 auto&
limb = pair.second;
259 auto limbConfig = prevCfg.limbs.at(limbName);
260 auto limbConfigNew = receivedConfig.limbs.at(limbName);
261 limbConfig.desiredPose = limbConfigNew.desiredPose;
262 limb->bufferConfigUserToNonRt.getWriteBuffer() =
264 limb->bufferConfigUserToNonRt.commitWrite();
270 this->
hands->updateConfig(receivedConfig.hands);
276 if (not rtTargetSafe)
291 datafields[
"frequency_ms"] =
new Variant(frequency_ms);
292 datafields[
"latency_ms"] =
new Variant(latency_ms);
296 for (
auto& pair : this->
limb)
298 if (not pair.second->rtReady.load())
306 if (!publishSocketBound_.load())
311 nlohmann::json stateJson;
312 stateJson[
"timestamp"] =
313 std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch())
316 auto mat4ToJson = [](
const Eigen::Matrix4f& m)
318 nlohmann::json j = nlohmann::json::array();
319 for (
int r = 0; r < 4; ++r)
320 for (
int c = 0;
c < 4; ++
c)
321 j.push_back(m(r,
c));
326 for (
auto& pair : this->limb)
328 if (not pair.second->rtReady.load())
330 auto rtData = pair.second->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
331 auto rtStatus = pair.second->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
332 const auto& nodeSetName = pair.second->kinematicChainName;
333 const auto& jointNames = pair.second->jointNames;
334 auto jointPosition = rtStatus.jointPosition;
335 auto jointVelocity = rtStatus.jointVelocity;
336 auto jointTorque = rtStatus.jointTorque;
337 auto desiredJointTorque = rtStatus.desiredJointTorque;
338 auto desiredJointVelocity = rtStatus.desiredJointVelocity;
339 auto desiredJointPosition = rtStatus.desiredJointPosition;
340 Eigen::Matrix4f currentPose = rtStatus.currentPose;
341 Eigen::Matrix4f desiredPose = rtStatus.desiredPose;
343 for (
size_t i = 0; i < jointNames.size(); ++i)
345 stateJson[nodeSetName][
"jointPosition"][jointNames[i]] = jointPosition(i);
346 stateJson[nodeSetName][
"jointVelocity"][jointNames[i]] = jointVelocity(i);
347 stateJson[nodeSetName][
"jointTorque"][jointNames[i]] = jointTorque(i);
348 stateJson[nodeSetName][
"desiredJointTorque"][jointNames[i]] = desiredJointTorque(i);
349 stateJson[nodeSetName][
"desiredJointVelocity"][jointNames[i]] = desiredJointVelocity(i);
350 stateJson[nodeSetName][
"desiredJointPosition"][jointNames[i]] = desiredJointPosition(i);
352 stateJson[nodeSetName][
"currentPose"] = mat4ToJson(currentPose);
353 stateJson[nodeSetName][
"desiredPose"] = mat4ToJson(desiredPose);
359 for (
auto& [handName, hand] : this->
hands->hands)
361 const auto& jointNames = hand->jointNames;
362 const auto desiredConfig =
363 hand->bufferConfigNonRTToOnPublish.getUpToDateReadBuffer();
364 const auto currentJointPositionMap = hand->ctrl->getJointValuesMap();
366 for (
size_t i = 0; i < jointNames.size(); ++i)
368 const auto it = currentJointPositionMap.find(jointNames[i]);
369 stateJson[handName][
"jointPosition"][jointNames[i]] =
370 (it != currentJointPositionMap.end()) ? it->second : 0.F;
371 if (desiredConfig.jointPosition.has_value())
373 stateJson[handName][
"desiredJointPosition"][jointNames[i]] =
374 desiredConfig.jointPosition.value()(i);
380 nlohmann::json metadata_json;
381 metadata_json[
"name"] =
"robot_state";
382 metadata_json[
"type"] =
"json";
383 metadata_json[
"timestamp_processed"] = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
384 std::string metadata_string = metadata_json.dump();
387 const std::string stateStr = stateJson.dump();
388 zmq::message_t msg(stateStr.size());
389 std::memcpy(msg.data(), stateStr.data(), stateStr.size());
390 zmq::message_t metadata_msg(metadata_string.size());
391 memcpy(metadata_msg.data(), metadata_string.data(), metadata_string.size());
394 std::unique_lock<std::mutex> lock(publishSocketMutex_);
395 publishSocket_.send(metadata_msg, zmq::send_flags::sndmore);
396 publishSocket_.send(msg, zmq::send_flags::dontwait);
398 catch (
const zmq::error_t& e)