ROS
ROS 모터 센서 뷰어 통합
Jagbbum
2023. 10. 10. 12:17
앞서 공부한 odometry, lidar, imu를 활용하야 rviz 상에서 8자로 동작하는 모형을 구현한다.
rviz_all
│ ├── CMakeLists.txt
│ ├── include
│ │ └── rviz_all
│ ├── launch
│ │ └── rviz_all.launch
│ ├── package.xml
│ ├── rviz
│ │ └── rviz_all.rviz
│ ├── src
│ │ └── odom_imu.cpp
│ └── urdf
│ └── rviz_all.urdf
이외의 필요한 것은 전에 사용했던 파일을 사용한다.
#include "ros/init.h"
#include "ros/node_handle.h"
#include "ros/publisher.h"
#include "ros/subscriber.h"
#include "ros/time.h"
#include "tf/LinearMath/Quaternion.h"
#include <iterator>
#include <ros/ros.h>
#include <tf/tf.h>
#include <tf/transform_broadcaster.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/Quaternion.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Vector3.h>
#include <sensor_msgs/JointState.h>
#include <sensor_msgs/Imu.h>
#include <nav_msgs/Odometry.h>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
using namespace ros;
double angle;
vector<float> imu_data;
void callback(const sensor_msgs::JointState::ConstPtr& data){
auto ptr = find(data->name.begin(), data->name.end(), "front_left_hinge_joint");
int index = distance(data->name.begin(), ptr);
angle = data->position[index];
}
void callback_imu(const sensor_msgs::Imu::ConstPtr& data){
imu_data.push_back(data->orientation.x);
imu_data.push_back(data->orientation.y);
imu_data.push_back(data->orientation.z);
imu_data.push_back(data->orientation.w);
}
int main(int argc, char** argv){
ros::init(argc, argv, "odometry_publisher");
NodeHandle nh;
Subscriber sub = nh.subscribe("joint_states",1,callback);
Subscriber sub_imu = nh.subscribe("imu",1,callback_imu);
tf2::Quaternion quaternion;
quaternion.setRPY(0, 0, 0);
Publisher odom_pub = nh.advertise<nav_msgs::Odometry>("odom", 50);
tf::TransformBroadcaster odom_broad;
Time current_time = Time::now();
Time last_time = Time::now();
Rate r(30);
double current_speed = 0.4;
double wheel_base = 0.2;
double x_ =0;
double y_ =0;
double yaw_ =0;
double Angle_ =0;
while(ok()){
current_time = Time::now();
double dt = (current_time-last_time).toSec();
double current_steering_angle = angle;
double current_angular_velocity = current_speed * tan(current_steering_angle)/wheel_base;
double x_dot = current_speed *cos(yaw_) ;
double y_dot = current_speed *sin(yaw_);
x_ += x_dot *dt;
y_ += y_dot *dt;
yaw_ += current_angular_velocity *dt;
quaternion.setRPY(0, 0, yaw_);
tf::StampedTransform odom_trans;
odom_trans.stamp_ = current_time;
odom_trans.frame_id_ = "base_link";
odom_trans.child_frame_id_ = "odom";
odom_trans.setOrigin(tf::Vector3(x_, y_, 0));
odom_trans.setRotation(tf::Quaternion(quaternion.getX(),quaternion.getY(),quaternion.getZ(),quaternion.getW()));
odom_broad.sendTransform(odom_trans);
nav_msgs::Odometry odom;
odom.header.stamp = current_time;
odom.header.frame_id = "odom";
odom.pose.pose.position.x = x_;
odom.pose.pose.position.y = y_;
odom.pose.pose.position.z = 0.;
odom.pose.pose.orientation.x = quaternion.x();
odom.pose.pose.orientation.y = quaternion.y();
odom.pose.pose.orientation.z = quaternion.z();
odom.pose.pose.orientation.w = quaternion.w();
odom.child_frame_id = "base_link";
odom_pub.publish(odom);
last_time = current_time;
r.sleep();
}
}