在ros中调用GMSL2摄像头,刚开始是通过修改官方驱动包ros-meloidc-usb-cam,可能是修改的地方不对,一直报错,调用失败,要是有大佬修改成功,希望能交流一下。
后来借鉴了一下别人关于这方面的博客,成功拿到了图像数据。理论上jetson orin/nanotx2等也可以用。
这是我的包,可根据自己情况修改jetsongmls2相机驱动-编解码文档类资源-CSDN下载
1、设备 Nvidia Jetson Agx Xavier
2、jetpack 4.6.1
3、opencv 4.1.1
4、ros-melodic
5、python3.6.9
6、GMSL2相机+相机采集板
参考我的上篇博客,此步不可省略,因为opencv4.1.1是python3版本的,所以就得使用python3版本的cv_bridge,而官方默认版本为python2版,如不自己构建cv_bridge,必须安装python2版本的opencv版本,使用默认cv_bridge。
在ROS-meloidc中使用python3 cv_bridge_Ponnyao的博客-CSDN博客
mkdir -p ~/ros_camera_ws/src
cd ~/ros_camera_ws/
catkin_make
source devel/setup.bash
cd ~/ros_camera_ws/src
catkin_create_pkg learning_image_transport roscpp std_msgs cv_bridge image_transport sensor_msgs
在功能包learning_image_transport下的src目录中建立两个cpp文件。
cd ~/ros_camera_ws/src/learning_image_transport/src/
gedit my_publisher.cpp
写入以下代码:
#include
#include
#include
#include
#include // for converting the command line parameter to integer
int main(int argc, char** argv)
{
// Check if video source has been passed as a parameter
if(argv[1] == NULL)
{
ROS_INFO("argv[1]=NULL\n");
return 1;
}
ros::init(argc, argv, "image_publisher");
ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Publisher pub = it.advertise("camera/image", 1);
// Convert the passed as command line parameter index for the video device to an integer
std::istringstream video_sourceCmd(argv[1]);
int video_source;
// Check if it is indeed a number
if(!(video_sourceCmd >> video_source))
{
ROS_INFO("video_sourceCmd is %d\n",video_source);
return 1;
}
cv::VideoCapture cap(video_source);
// Check if video device can be opened with the given index
if(!cap.isOpened())
{
ROS_INFO("can not opencv video device\n");
return 1;
}
cv::Mat frame;
sensor_msgs::ImagePtr msg;
ros::Rate loop_rate(5);
while (nh.ok())
{
cap >> frame;
// Check if grabbed frame is actually full with some content
if(!frame.empty())
{
msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
pub.publish(msg);
//cv::Wait(1);
}
}
ros::spinOnce();
loop_rate.sleep();
}
gedit my_subscriber.cpp
写入以下代码:
#include
#include
#include
#include
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
try
{
cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
// cv::waitKey(30);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "image_listener");
ros::NodeHandle nh;
cv::namedWindow("view");
cv::startWindowThread();
image_transport::ImageTransport it(nh);
image_transport::Subscriber sub = it.subscribe("camera/image", 1,imageCallback);
ros::spin();
cv::destroyWindow("view");
}
cd ~/ros_camera_ws/src/learning_image_transport/
gedit CMakeLists.txt
填入以下内容:
find_package(OpenCV REQUIRED)
# add the publisher example
add_executable(my_publisher src/my_publisher.cpp)
target_link_libraries(my_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})
# add the subscriber example
add_executable(my_subscriber src/my_subscriber.cpp)
target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})
cd ~/ros_camera_ws/
catkin_make
roscore
cd ~/ros_camera_ws/
source devel/setup.bash
rosrun learning_image_transport my_publisher 0
0代表默认摄像头,如果有多个摄像头,则第二个是1,依次类推。
cd ~/ros_camera_ws/
source devel/setup.bash
rosrun learning_image_transport my_subscriber
在对应功能包scripts文件夹下新建image_view.py
#!/usr/bin/env python3
#coding:utf-8
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge,CvBridgeError
def callback(data):
cv_image=CvBridge().imgmsg_to_cv2(data,"bgr8")
cv2.imshow("view",cv_image)
cv2.waitKey(1)
if __name__ == '__main__':
rospy.init_node('image_acquistion')
rospy.Subscriber('camera/image', Image, callback)
rospy.spin()
cv2.destoryAllWindows()
rosrun 你的包名 image_view.py
参考博客
JETSON AGX XAVIER GMSL2接口相机驱动_努力划水的博客-CSDN博客_gmsl2接口