Skip to content

Commit 6577632

Browse files
committed
mix plugin solutions
1 parent fae00ec commit 6577632

2 files changed

Lines changed: 49 additions & 66 deletions

File tree

Industrial/gz_noisy_odometry/include/gz_noisy_odometry/NoisyOdometryPlugin.hpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#ifndef NOISY_ODOMETRY_PLUGIN_HPP_
22
#define NOISY_ODOMETRY_PLUGIN_HPP_
33

4-
#include <gz/sim/System.hh>
5-
#include <gz/sim/Model.hh>
6-
#include <gz/transport/Node.hh>
4+
#include <gz/sim/System.hpp>
5+
#include <gz/sim/Model.hpp>
6+
#include <gz/transport/Node.hpp>
77
#include <gz/msgs/twist.pb.h>
8-
#include <gz/math/Pose3.hh>
8+
#include <gz/math/Pose3.hpp>
9+
#include <gz/math/Rand.hpp>
910

1011
#include <rclcpp/rclcpp.hpp>
1112
#include <nav_msgs/msg/odometry.hpp>
1213

1314
#include <mutex>
14-
#include <random>
1515
#include <string>
1616
#include <memory>
1717

@@ -49,16 +49,14 @@ namespace custom_plugins
4949
std::string child_frame_id_;
5050

5151
bool initialized_{false};
52-
gz::math::Pose3d current_pose_;
52+
gz::math::Pose3d noisy_pose_internal_; // Nuestra "realidad" ruidosa acumulada
53+
std::chrono::steady_clock::duration last_update_time_{0};
5354

5455
double current_v_{0.0};
5556
double current_w_{0.0};
5657

5758
std::mutex mutex_;
58-
59-
std::default_random_engine generator_;
60-
std::normal_distribution<double> linear_noise_dist_;
61-
std::normal_distribution<double> angular_noise_dist_;
59+
double gaussian_noise_coeff_{0.0};
6260
};
6361
}
6462

Industrial/gz_noisy_odometry/src/gz_noisy_odometry/NoisyOdometryPlugin.cpp

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "gz_noisy_odometry/NoisyOdometryPlugin.hpp"
2-
#include <gz/sim/components/Pose.hh>
3-
#include <gz/plugin/Register.hh>
2+
#include <gz/sim/components/Pose.hpp>
3+
#include <gz/plugin/Register.hpp>
44
#include <tf2/LinearMath/Quaternion.h>
55

66
GZ_ADD_PLUGIN(
@@ -13,45 +13,30 @@ GZ_ADD_PLUGIN_ALIAS(custom_plugins::NoisyOdometryPlugin, "custom_plugins::NoisyO
1313

1414
namespace custom_plugins
1515
{
16-
NoisyOdometryPlugin::NoisyOdometryPlugin() : generator_(std::random_device{}())
17-
{
18-
}
16+
NoisyOdometryPlugin::NoisyOdometryPlugin() {}
1917

2018
void NoisyOdometryPlugin::Configure(const gz::sim::Entity &_entity,
2119
const std::shared_ptr<const sdf::Element> &_sdf,
2220
gz::sim::EntityComponentManager &_ecm,
2321
gz::sim::EventManager &)
2422
{
2523
model_ = gz::sim::Model(_entity);
24+
if (!model_.Valid(_ecm)) return;
2625

27-
if (!model_.Valid(_ecm))
28-
{
29-
return;
30-
}
31-
32-
double linear_std_dev = _sdf->Get<double>("linear_noise_std_dev", 0.05).first;
33-
double angular_std_dev = _sdf->Get<double>("angular_noise_std_dev", 0.05).first;
34-
35-
linear_noise_dist_ = std::normal_distribution<double>(0.0, linear_std_dev);
36-
angular_noise_dist_ = std::normal_distribution<double>(0.0, angular_std_dev);
37-
38-
ros_topic_ = _sdf->Get<std::string>("ros_topic", "/noisy_odom").first;
39-
gz_cmd_vel_topic_ = _sdf->Get<std::string>("gz_cmd_vel_topic", "/cmd_vel").first;
26+
// Parámetros del SDF
27+
gaussian_noise_coeff_ = _sdf->Get<double>("gaussian_noise", 0.05).first;
28+
ros_topic_ = _sdf->Get<std::string>("ros_topic", "/turtlebot3/odom_noisy").first;
29+
gz_cmd_vel_topic_ = _sdf->Get<std::string>("gz_cmd_vel_topic", "/turtlebot3/cmd_vel").first;
4030
frame_id_ = _sdf->Get<std::string>("frame_id", "odom").first;
41-
child_frame_id_ = _sdf->Get<std::string>("child_frame_id", "base_link").first;
31+
child_frame_id_ = _sdf->Get<std::string>("child_frame_id", "base_footprint").first;
4232

4333
gz_node_.Subscribe(gz_cmd_vel_topic_, &NoisyOdometryPlugin::OnCmdVel, this);
4434

45-
if (!rclcpp::ok())
46-
{
47-
rclcpp::init(0, nullptr);
48-
}
49-
50-
ros_node_ = rclcpp::Node::make_shared("noisy_odometry_node_" + model_.Name(_ecm));
35+
if (!rclcpp::ok()) rclcpp::init(0, nullptr);
36+
ros_node_ = rclcpp::Node::make_shared("noisy_odom_node_" + model_.Name(_ecm));
5137

52-
rclcpp::QoS qos(rclcpp::KeepLast(10));
38+
rclcpp::QoS qos(10);
5339
qos.transient_local();
54-
5540
ros_pub_ = ros_node_->create_publisher<nav_msgs::msg::Odometry>(ros_topic_, qos);
5641
}
5742

@@ -65,28 +50,22 @@ namespace custom_plugins
6550
void NoisyOdometryPlugin::PostUpdate(const gz::sim::UpdateInfo &_info,
6651
const gz::sim::EntityComponentManager &_ecm)
6752
{
68-
if (_info.paused)
69-
{
70-
return;
71-
}
53+
if (_info.paused) return;
7254

7355
if (!initialized_)
7456
{
7557
auto poseComp = _ecm.Component<gz::sim::components::Pose>(model_.Entity());
76-
if (poseComp)
77-
{
78-
current_pose_ = poseComp->Data();
58+
if (poseComp) {
59+
noisy_pose_internal_ = poseComp->Data();
60+
last_update_time_ = _info.simTime;
7961
initialized_ = true;
8062
}
8163
return;
8264
}
8365

84-
double dt = std::chrono::duration<double>(_info.dt).count();
85-
86-
if (dt <= 0.0)
87-
{
88-
return;
89-
}
66+
double dt = std::chrono::duration<double>(_info.simTime - last_update_time_).count();
67+
if (dt <= 0.0) return;
68+
last_update_time_ = _info.simTime;
9069

9170
double v_cmd, w_cmd;
9271
{
@@ -95,32 +74,38 @@ namespace custom_plugins
9574
w_cmd = current_w_;
9675
}
9776

98-
double v_noisy = v_cmd + linear_noise_dist_(generator_);
99-
double w_noisy = w_cmd + angular_noise_dist_(generator_);
77+
// MATEMÁTICA HÍBRIDA: Integración Estocástica Proporcional
78+
// El ruido es proporcional a la velocidad y escalado por sqrt(dt) para un Random Walk correcto
79+
double linear_noise = gaussian_noise_coeff_ * gz::math::Rand::DblNormal(0, 1) * std::sqrt(dt) * std::abs(v_cmd);
80+
double angular_noise = gaussian_noise_coeff_ * gz::math::Rand::DblNormal(0, 1) * std::sqrt(dt) * std::abs(w_cmd);
10081

101-
double yaw = current_pose_.Yaw();
102-
double dx = v_noisy * cos(yaw + (w_noisy * dt / 2.0)) * dt;
103-
double dy = v_noisy * sin(yaw + (w_noisy * dt / 2.0)) * dt;
104-
double dyaw = w_noisy * dt;
82+
double v_noisy = v_cmd + (linear_noise / dt);
83+
double w_noisy = w_cmd + (angular_noise / dt);
10584

106-
current_pose_.Pos().X() += dx;
107-
current_pose_.Pos().Y() += dy;
85+
// Actualización de orientación (Yaw)
86+
double yaw_prev = noisy_pose_internal_.Rot().Yaw();
87+
double yaw_new = yaw_prev + (w_noisy * dt);
88+
89+
// Actualización de posición (Cinemática Diferencial)
90+
double distance = v_noisy * dt;
91+
noisy_pose_internal_.Pos().X() += distance * std::cos(yaw_prev + (w_noisy * dt / 2.0));
92+
noisy_pose_internal_.Pos().Y() += distance * std::sin(yaw_prev + (w_noisy * dt / 2.0));
10893

109-
gz::math::Quaterniond new_rot;
110-
new_rot.SetFromEuler(0.0, 0.0, yaw + dyaw);
111-
current_pose_.Rot() = new_rot;
94+
gz::math::Quaterniond q_new;
95+
q_new.SetFromEuler(0, 0, yaw_new);
96+
noisy_pose_internal_.Rot() = q_new;
11297

98+
// Publicación en ROS 2
11399
nav_msgs::msg::Odometry odom_msg;
114100
odom_msg.header.stamp = ros_node_->now();
115101
odom_msg.header.frame_id = frame_id_;
116102
odom_msg.child_frame_id = child_frame_id_;
117103

118-
odom_msg.pose.pose.position.x = current_pose_.Pos().X();
119-
odom_msg.pose.pose.position.y = current_pose_.Pos().Y();
120-
odom_msg.pose.pose.position.z = current_pose_.Pos().Z();
121-
104+
odom_msg.pose.pose.position.x = noisy_pose_internal_.Pos().X();
105+
odom_msg.pose.pose.position.y = noisy_pose_internal_.Pos().Y();
106+
122107
tf2::Quaternion q;
123-
q.setRPY(0.0, 0.0, current_pose_.Yaw());
108+
q.setRPY(0, 0, yaw_new);
124109
odom_msg.pose.pose.orientation.x = q.x();
125110
odom_msg.pose.pose.orientation.y = q.y();
126111
odom_msg.pose.pose.orientation.z = q.z();

0 commit comments

Comments
 (0)