使用ros發布UVC相機和串口IMU數據

1.目的:為了可以標定普通USB相機和固定在相機上的外置IMU的外參,我希望通過ROS獲取更高分辨率和更高頻率的圖像數據,并且可以將圖像和imu的topic發布出來,直接使用rosbag record錄制話題數據,寫入bag文件,這樣獲得的bag文件直接可以用于相機和IMU的外參標定, 標定工具是kalibr.

2. 為了達到上述目的,我首先是完成使用ros發布出來從串口獲取的imu數據,目前獲取的頻率是200hz,也是從網上找到的一個ros中串口通信的小demo,? ? ?參考? ?https://blog.csdn.net/tansir94/article/details/81357612? 和? ?https://blog.csdn.net/xinmei4275/article/details/85040164?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

3. 我安裝了minicom? 串口小工具

sudo apt-get install minicom
sudo minicom -D /dev/ttyUSB0 -b 230400 -H -w
-D 設置串口
-b 設置波特率
-H 設置十六進制顯示
-w 自動換行

我的代碼如下

#include <ros/ros.h>
#include <sensor_msgs/Imu.h>
#include <serial/serial.h> //ROS已經內置了的串口包
#include <std_msgs/Empty.h>
#include <std_msgs/String.h>
serial::Serial ser; //聲明串口對象sensor_msgs::Imu imu_data;
//回調函數
void write_callback(const std_msgs::String::ConstPtr &msg) {ROS_INFO_STREAM("Writing to serial port" << msg->data);ser.write(msg->data); //發送串口數據
}
int main(int argc, char **argv) {//初始化節點ros::init(argc, argv, "serial_example_node");//聲明節點句柄ros::NodeHandle nh;//訂閱主題,并配置回調函數ros::Subscriber write_sub = nh.subscribe("write", 1000, write_callback);//發布主題ros::Publisher read_pub = nh.advertise<std_msgs::String>("read", 1000);ros::Publisher IMU_read_pub =nh.advertise<sensor_msgs::Imu>("imu_data", 1000);// ros::Publisher Image_read_pub =
//       nh.advertise<sensor_msgs::>("imu_data", 1000);try {//設置串口屬性,并打開串口ser.setPort("/dev/ttyUSB0");ser.setBaudrate(230400);serial::Timeout to = serial::Timeout::simpleTimeout(1000);ser.setTimeout(to);ser.open();} catch (serial::IOException &e) {ROS_ERROR_STREAM("Unable to open port ");return -1;}//檢測串口是否已經打開,并給出提示信息if (ser.isOpen()) {ROS_INFO_STREAM("Serial Port initialized");} else {return -1;}//指定循環的頻率ros::Rate loop_rate(400);while (ros::ok()) {unsigned char data_size;/*! Return the number of characters in the buffer. */// available()
//     while((data_size = ser.available()) < 11){//     } if (data_size = ser.available()){unsigned char tmpdata[data_size];ser.read(tmpdata, data_size);// std::cout << "data_size: " << data_size << std::endl;for (int i = 0; i < data_size; i++) {if (tmpdata[i] == 0x55) {switch (tmpdata[i + 1]) {case 0x51:imu_data.header.stamp = ros::Time::now();imu_data.header.frame_id = "base_link";imu_data.linear_acceleration.x =((short)(tmpdata[3 + i] << 8 | tmpdata[2 + i])) / 32768.0 * 4 * 9.7803;imu_data.linear_acceleration.y =((short)(tmpdata[5 + i] << 8 | tmpdata[4 + i])) / 32768.0 * 4 * 9.7803;imu_data.linear_acceleration.z =((short)(tmpdata[7 + i] << 8 | tmpdata[6 + i])) / 32768.0 * 4 * 9.7803;std::cout<<"acc: "<<std::setprecision(16)<<imu_data.header.stamp<<" " <<imu_data.linear_acceleration.x<<" "<<imu_data.linear_acceleration.y<<" "<<imu_data.linear_acceleration.z<<std::endl<<std::endl;break;case 0x52:imu_data.angular_velocity.x =((short)(tmpdata[3 + i] << 8 | tmpdata[2 + i])) / 32768.0 * 500;imu_data.angular_velocity.y =((short)(tmpdata[5 + i] << 8 | tmpdata[4 + i])) / 32768.0 * 500;imu_data.angular_velocity.z =((short)(tmpdata[7 + i] << 8 | tmpdata[6 + i])) / 32768.0 * 500;//ROS_INFO_STREAM("imu_data: " << imu_data);IMU_read_pub.publish(imu_data);std::cout<<"gyr: "<<std::setprecision(16)<<imu_data.header.stamp<<" "<<imu_data.angular_velocity.x <<" "<<imu_data.angular_velocity.y <<" "<<imu_data.angular_velocity.z <<std::endl;break; }}}}//     if (ser.available()) {//       // ROS_INFO_STREAM("Reading from serial port\n");//       //讀到的是string類型的,//       std_msgs::String result;//       result.data = ser.read(ser.available());//       ROS_INFO_STREAM("Read: " << result.data);//       std::cout << "result.data: " << result.data << std::endl <<//       std::endl;//       // read_pub.publish(result);//     }//處理ROS的信息,比如訂閱消息,并調用回調函數ros::spinOnce();loop_rate.sleep();}
}

CMakeLists.txt的內容

cmake_minimum_required(VERSION 2.8.3)
project(serialPort)find_package(catkin REQUIRED COMPONENTSroscppserialstd_msgs
)catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES serialPortCATKIN_DEPENDS roscpp serial std_msgs
#  DEPENDS system_lib
)###########
## Build ##
############# Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
#include${catkin_INCLUDE_DIRS}
)add_executable(serialPort src/serialPort.cpp)add_dependencies(serialPort ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})target_link_libraries(serialPort${catkin_LIBRARIES}
)

4. 獲取uvc相機的圖像

#include <cv_bridge/cv_bridge.h>
#include <image_transport/image_transport.h>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <stdio.h>
using namespace cv;int main(int argc, char **argv) {ros::init(argc, argv, "image_publisher");ros::NodeHandle nh;image_transport::ImageTransport it(nh);image_transport::Publisher pub0 = it.advertise("camera/left", 0);image_transport::Publisher pub1 = it.advertise("camera/right", 1);//測試出來我的小覓相機是單ID相機cv::VideoCapture cap(0);cap.set(CV_CAP_PROP_FRAME_WIDTH, 2560);cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);cap.set(CV_CAP_PROP_FPS, 60);// cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);// cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);// cap.set(CV_CAP_PROP_FPS, 60);if (!cap.isOpened()) {ROS_INFO("cannot open video device0\n");return -1;}cv::Mat frame, frame_G, frame_L, frame_R;sensor_msgs::ImagePtr msg0;sensor_msgs::ImagePtr msg1;sensor_msgs::ImagePtr msg;ros::Rate loop_rate(30);while (nh.ok()) {cap >> frame;ros::Time time_now = ros::Time::now();cv::cvtColor(frame, frame_G, cv::COLOR_BGR2GRAY);frame_L = frame_G(cv::Rect(0, 0, 1280, 720));frame_R = frame_G(cv::Rect(1280, 0, 1280, 720));// frame_L = frame_G(cv::Rect(0, 0, 640, 480));// frame_R = frame_G(cv::Rect(640, 0, 640, 480));// cv::imshow("frame_L", frame_L);// cv::waitKey(2);// cv::imshow("frame_R", frame_R);// cv::waitKey(2);// cv::imshow("frame", frame);// cv::waitKey(2);// cv::imshow("frame_G", frame_G);// cv::waitKey(2);if (!frame_L.empty()) {msg0 =cv_bridge::CvImage(std_msgs::Header(), "mono8", frame_L).toImageMsg();msg0->header.stamp = time_now;pub0.publish(msg0);}if (!frame_R.empty()) {msg1 =cv_bridge::CvImage(std_msgs::Header(), "mono8", frame_R).toImageMsg();msg1->header.stamp = time_now;pub1.publish(msg1);}ROS_INFO("Publishing camera/left camera/right ROS topic MSG!! ");ros::spinOnce();loop_rate.sleep();}
}

CMakeLists.txt文件內容如下

cmake_minimum_required(VERSION 2.8.3)
project(imgReader)find_package(catkin REQUIRED COMPONENTSsensor_msgscv_bridgeroscppstd_msgsimage_transport
)
find_package(OpenCV REQUIRED)#
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES imgReaderCATKIN_DEPENDS sensor_msgs cv_bridge roscpp std_msgs image_transport
#  DEPENDS system_lib
)###########
## Build ##
############# Specify additional locations of header files
## Your package locations should be listed before other locationsinclude_directories(
# include${catkin_INCLUDE_DIRS}${OpenCV_INCLUDE_DIRS}
)add_executable(imgReader src/imgReader.cpp)target_link_libraries(imgReader${catkin_LIBRARIES}${OpenCV_LIBRARIES}
)
add_dependencies(imgReader ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

5. 設置rviz顯示圖像和Imu數據

首先設置launch文件

<launch><node pkg="serialPort" type="serialPort" name="serialPort" required="true" output="screen"><param name="port" value="/dev/ttyUSB0"/></node><node pkg="imgReader" type="imgReader" name="imgReader" required="true" output="screen"><param name="port" value="/dev/video0"/></node><!-- 在rviz中顯示-->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find imgReader)/config/rviz/get_imu_image.rviz" required="true" /></launch>

如果不設置launch文件,也可以分別發布兩個節點的信息.

terminal 1
roscoreterminal 2
source ./devel/setup.bash
rosrun serialPort serialPortterminal 3
source ./devel/setup.bash
rosrun imgReader imgReader

參考這篇文章設置rviz的配置文件??https://blog.csdn.net/weixin_44684139/article/details/104416690?和?https://blog.csdn.net/xinmei4275/article/details/85040164?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

首先是運行你的node,使得圖像和imu數據的topics都發布出來,使用rostopic list查看當前正在發布的topic

然后打開rviz窗口界面

rosrun rviz rviz

然后添加Imu和image的topics

最后保存rviz配置到相應的路徑.然后在上面的launch文件最后加上rviz配置文件,這樣,當roslaunch launch文件時,就可以同時加載rviz視圖窗口了.

就像下圖這樣.

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252429.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252429.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252429.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

API自動化測試利器——Postman

自從開始做API開發之后&#xff0c;我就在尋找合適的API測試工具。一開始不是很想用Chrome擴展&#xff0c;用的WizTools的工具&#xff0c;后來試過一次Postman之后就停不下來了&#xff0c;還買了付費的Jetpacks。推出Team Sync Beta之后我又把這個工具推廣給團隊&#xff0c…

gcc,cc,g++,CC的區別

***gcc是C編譯器&#xff1b; ***g是C編譯器&#xff1b; ***linux下cc一般是一個符號連接&#xff0c;指向gcc ***gcc說明 1.gcc編譯常用格式&#xff1a; gcc C源文件 -o 目標文件 或 gcc -o 目標文件 C源文件 或 gcc C源文件 最后一種情況產生的目標文件默認為a.out 2.gcc…

云原生實踐之 RSocket 從入門到落地:Servlet vs RSocket

技術實踐的作用在于&#xff1a;除了用于構建業務&#xff0c;也是為了驗證某項技術或框架是否值得大規模推廣。 本期開始&#xff0c;我們推出《RSocket 從入門到落地》系列文章&#xff0c;通過實例和對比來介紹RSocket。主要圍繞RSocket如何實現Polyglot RPC、Service Regis…

制作.sens數據集跑通bundlefusion

1. 主要參考這篇博客實現 https://blog.csdn.net/Wuzebiao2016/article/details/94426905 2. 首先就是將自己采集的RGBD圖像的保存格式向Bundlefusion需要的格式對齊&#xff0c;如彩色圖的命名格式是frame-000000.color.png&#xff0c;深度圖的命名規則是frame-000000.depth…

用ul li實現邊框重合并附帶鼠標經過效果

邊框重合這個效果并不難&#xff0c;只是我們沒有真正的動手做過而已&#xff0c;下面讓我們來談談用ul li如何實現邊框重合&#xff0c;并附帶鼠標經過效果 1 <!DOCTYPE html>2 <html lang"zh-CN">3 4 <head>5 <title></title>6 …

hive 中窗口函數row_number,rank,dense_ran,ntile分析函數的用法

https://www.cnblogs.com/wujin/p/6051768.html轉載于:https://www.cnblogs.com/0xcafedaddy/p/8385476.html

python之moviepy庫的安裝與使用

目的&#xff1a;因為需要保存一個大大的.mp4視頻&#xff0c;以防過程中設備出現異常導致整個長長的視頻無法正常保存&#xff0c;所以采用分段保存視頻的方式&#xff0c;每500幀保存一段&#xff0c;然后再將視頻合到一起&#xff0e;最近剛開始學習python,發現python真的很…

oracle 之 安裝后pl/sql登錄報ora-12154

這個問題一開始困擾了很久。 查的資料是復制一小段代碼到tnsnames.ora中 SID名 (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST localhost)(PORT 1522)) (CONNECT_DATA (SERVER DEDICATED) (SERVICE_NAME SID名) ) 注意SID名前面不能有任何其他字符&…

如何避免表單重復提交

客戶端方案 禁掉提交按鈕。 表單提交后使用Javascript使提交按鈕disable。這種方法防止心急的用戶多次點擊按鈕。但有個問題&#xff0c;如果客戶端把Javascript給禁止掉&#xff0c;這種方法就無效了。 使用Post/Redirect/Get模式 在提交后執行頁面重定向&#xff0c;這就是所…

十六進制轉八進制

【問題描述】 問題描述 給定n個十六進制正整數&#xff0c;輸出它們對應的八進制數。 輸入格式 輸入的第一行為一個正整數n &#xff08;1<n<10&#xff09;。 接下來n行&#xff0c;每行一個由0~9、大寫字母A~F組成的字符串&#xff0c;表示要轉換的十六進制正整數&…

使用iai_kinect2標定kinectV2相機

實驗背景&#xff1a;因為需要制作bundlefusion需要的數據集&#xff0c;所以需要使用kinectV2相機獲取rgbd圖像&#xff0c;年前的時候在我的筆記本上安裝了libfreenect2庫和iai_kinect2&#xff0c;標定過一次kinecv2相機&#xff0c;然后使用kinectv2相機實時獲取的圖像實現…

tar只解壓tar包中某個文件

如果tar包很大&#xff0c;而只想解壓出其中某個文件。方法如下&#xff1a; 只想解壓出Redis-1.972.tar 中的Changes文件&#xff0c;來查看有哪些更改。 [rootuplooking]# tar -tf Redis-1.972.tar Redis-1.972…

扎克伯格的中文夜:想要成功就不能放棄

10月23日消息。雖然并不太流暢。昨天馬克?扎克伯格依舊用中文與清華經管學院主持人完畢了一場對話&#xff1b;在對話中&#xff0c;這位Facebook創始人兼首席運行官闡述了自己學習中文的原因&#xff1a;想要和太太&#xff08;普里西拉?陳&#xff09;的家人交流&#xff1…

python將ros下bag文件的所有topic解析為csv格式

背景&#xff1a;最近在制作kimera的數據集&#xff0c;尤其是運行semantic模塊所需要的bag文件中有很多topic&#xff0c;但是很多不知道topic中裝的是什么數據&#xff0c;及其格式&#xff0c;所以我就想著怎么可以將bag中的topic都解析數來&#xff0c;這樣就能知道bag中都…

十九. Python基礎(19)--異常

十九. Python基礎(19)--異常 1 ● 捕獲異常 if VS異常處理: if是預防異常出現, 異常處理是處理異常出現 異常處理一般格式: try: <...............> #可能得到異常的語句 except <.......>: #捕獲是哪種異常 <...............> #出現異常的處理方…

洛谷1052——過河(DP+狀態壓縮)

題目描述 在河上有一座獨木橋&#xff0c;一只青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子&#xff0c;青蛙很討厭踩在這些石子上。由于橋的長度和青蛙一次跳過的距離都是正整數&#xff0c;我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點&#xff1a;0…

Tensorflow學習教程------tfrecords數據格式生成與讀取

首先是生成tfrecords格式的數據&#xff0c;具體代碼如下&#xff1a; #coding:utf-8import os import tensorflow as tf from PIL import Imagecwd os.getcwd() 此處我加載的數據目錄如下&#xff1a; bt -- 14018.jpg14019.jpg14020.jpgnbt -- 1_ddd.jpg1_dsdfs.jpg1_dfd.…

ROS獲取KinectV2相機的彩色圖和深度圖并制作bundlefusion需要的數據集

背景&#xff1a; 最近在研究BundleFusion&#xff0c;跑通官方數據集后&#xff0c;就想著制作自己的數據集來運行bundlefusion&#xff0e;KinectV2相機可直接獲取的圖像的分辨率分為三個HD 1920x1080, QHD: 960X540&#xff0c;SD: 512x424.我選擇是中間的分辨率qhd. 錄制…

Linux下配置tomcat+apr+native應對高并發

摘要&#xff1a;在慢速網絡上Tomcat線程數開到300以上的水平&#xff0c;不配APR&#xff0c;基本上300個線程狠快就會用滿&#xff0c;以后的請求就只好等待。但是配上APR之后&#xff0c;Tomcat將以JNI的形式調用Apache HTTP服務器的核心動態鏈接庫來處理文件讀取或網絡傳輸…

Firefox 66 將阻止自動播放音頻和視頻

百度智能云 云生態狂歡季 熱門云產品1折起>>> 當我們點擊一個鏈接&#xff0c;或者打開新的瀏覽器選項卡時&#xff0c;瀏覽器就開始自動播放視頻和聲音&#xff0c;這是一件十分煩人的事。Chrome 瀏覽器早已對這些行為下手了&#xff0c;現在 Firefox 也明確表示要…