GMSL--Gigabit Multimedia Serial Link (中文译为:吉比特多媒体串行链路), 整个传输线路包含串行器和解串器(SerDes),GMSL全面支持汽车信息娱乐系统、高级驾驶辅助系统(ADAS)甚至未来无人驾驶 要求的宽带、复杂互连和数据完整性。
从摄像头的超低功耗要求、到传感器数据汇聚的宽带要求,GMSL SerDes能够满足未来系统的所有需求。先进的链路完整性和诊断功能提供可靠的链路性能监测——这对汽车安全系统的设计至关重要。GMSL串行器和解串器支持长达15m的屏蔽双绞线(STP)或同轴电缆传输,满足汽车行业最苛刻的电磁兼容(EMC)要求。
串行器和解串器IC均内置扩频功能,以改善链路的电磁兼容(EMI)性,无需外部扩频时钟。串行器和解串器系列产品的互操作性允许链路两侧使用不同接口。除驱动高分辨率中央/后排显示屏和仪表盘外,GMSL SerDes也能出胜任百万像素级摄像机系统设计。
在现代新型汽车视频互连众多性能的基础上,GMSL技术提供宽带、功能丰富、设计灵活性等优势,支持无人驾驶系统等未来汽车的设计需求。
GMSL 技术芯片厂商:MAXIM美信
二、GMSL可以做是什么?
近来,汽车ADAS高级驾驶辅助系统装车率快速增长,纵览各大厂商,这些技术基本上集中在L2-L3级自动驾驶,而为了实现这些功能,单车感知系统中,摄像头的使用量基本上都在5个以上。比如说特斯拉8个、小鹏P7为14个、威马W6是7个、而背靠阿里与上汽的智己汽车将之增加到15个。
这些摄像头根据不同位置分布实现其不同功能,GMSL摄像头典型应用场景:
三、如何利用GMSL 来做这些事 ?
举例NVIDIA Jetson Xavier AGX 平台+GMSL信号采集板+8路GMSL相机的应用案例:
硬件:
Jetson Xavier AGX Devkit 开发套件
GMSL2 信号采集板 --- 4xMAX9296/4x4Lane CSI
GMSL2 相机 --- AR0231RGB + MAX9295A (后置ISP)
软件:
Jetson Xavier AGX JetPack4.4 SDK(可兼容其他版本)
Ubuntu 18.04 --- Linux-4.9.140
应用:
Gstreamer 命令查看RAW相机
#查看相机/dev/video0 带帧率显示
gst-launch-1.0 --gst-debug=4 nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvvidconv ! fpsdisplaysink video-sink=xvimagesink sync=false
#查看多路相机/dev/video0|1 带帧率显示
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvvidconv ! fpsdisplaysink video-sink=xvimagesink sync=false \
& gst-launch-1.0 nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvvidconv ! fpsdisplaysink video-sink=xvimagesink sync=false
JetPack SDK -->nvidia-l4t-jetson-multimedia-api 打开RAW 相机参考
/usr/src/jetson_multimedia_api/samples/13_multi_camera/
OpenCV 预览多路相机代码参考:
/*
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
#include
#include
#include
#include
static void help()
{
std::cout << "\nThis is a sample OpenCV application to demonstrate "
"CSI-camera capture1 pipeline for NVIDIA accelerated GStreamer.\n\n"
"./opencv_nvgstcam [--Options]\n\n"
"OPTIONS:\n"
"\t-h,--help Prints this message\n"
"\t--width capture1 width [Default = 1280]\n"
"\t--height capture1 height [Default = 720]\n"
"\t--fps Frames per second [Default = 30]\n"
"\tq Runtime command to stop capture1\n\n"
<< std::endl;
}
static std::string create_capture (int index, int width, int height, int fps)
{
std::stringstream pipeline_str;
pipeline_str << "nvarguscamerasrc sensor-id=" <("fps");
width = cmd_parser.get("width");
height = cmd_parser.get("height");
if (!cmd_parser.check())
{
cmd_parser.printErrors();
help();
return_val = -1;
goto cleanup;
}
capture1.open(create_capture(0, width, height, fps), cv::CAP_GSTREAMER);//Open
capture2.open(create_capture(1, width, height, fps), cv::CAP_GSTREAMER);
capture3.open(create_capture(2, width, height, fps), cv::CAP_GSTREAMER);
capture4.open(create_capture(3, width, height, fps), cv::CAP_GSTREAMER);
//
if (!capture1.isOpened())
{
std::cerr << "Failed to open VideoCapture" << std::endl;
return_val = -4;
goto cleanup;
}
//Display window setting
cv::namedWindow("FPDLINKIII_4xCamera_Demo");
cv::moveWindow("FPDLINKIII_4xCamera_Demo", 0, 0);
while (true)
{
ticks.start();
capture1 >> frame1;
capture2 >> frame2;
capture3 >> frame3;
capture4 >> frame4;
cv::resize(frame1, frame1_dst, cv::Size(640,360));
cv::resize(frame2, frame2_dst, cv::Size(640,360));
cv::resize(frame3, frame3_dst, cv::Size(640,360));
cv::resize(frame4, frame4_dst, cv::Size(640,360));
#if 1
cv::hconcat(frame1_dst, frame2_dst, disp_mat1);
cv::hconcat(frame3_dst, frame4_dst, disp_mat2);
cv::vconcat(disp_mat1, disp_mat2, disp_vmat);
cv::imshow("FPDLINKIII_4xCamera_Demo", disp_vmat);
#else
cv::imshow("FPDLINKIII_4xCamera_Demo", frame1);
#endif
int key = cv::waitKey(1);
// 'q' for termination
if (key == 'q' )
{
break;
}
ticks.stop();
}
if (ticks.getCounter() == 0)
{
std::cerr << "No frames processed" << std::endl;
return_val = -10;
goto cleanup;
}
fps_calculated = ticks.getCounter() / ticks.getTimeSec();
std::cout << "Fps observed " << fps_calculated << std::endl;
cleanup:
capture1.release();
capture2.release();
capture3.release();
capture4.release();
return return_val;
}