基于PTP实现主机与相机系统时钟同步功能

基于PTP实现主机与相机系统时钟同步功能

一、PTP简介

PTP概览: PTP是一种网络时间同步协议,设计用于实现局域网络中设备间的高精度时间同步,通常能达到亚微秒乃至纳秒级的同步精度。它主要服务于对时间同步有严格要求的应用场景,如金融交易、电信网络、科学研究、工业自动化等。

核心特点:

  • 硬件级实现:PTP利用网络接口卡(NIC)的硬件时间戳功能直接在数据链路层(MAC层)进行时间戳标记,减少了操作系统和协议栈带来的延迟,提升了同步精度。
  • 主从架构:网络中存在一个或多个主时钟(通常通过Best Master Clock算法选举),其他设备作为从时钟,根据主时钟的信号调整自己的时间。
  • 时间延迟补偿:PTP协议通过测量和补偿消息的传播延迟,包括往返时间(Round Trip Time, RTT)的计算,来精确调整从时钟的时间。
  • PTPv2(IEEE 1588-2008):相较于最初的PTPv1,PTPv2增加了对多种时钟类型的支持、改善了时钟模型、增强了时间戳机制,并引入透明时钟(Transparent Clocks)概念,进一步提高了同步精度。

PTP作为一种高精度时间同步技术,能够实现亚微秒乃至约30纳秒的精准同步,但这需要网络中的交换机等节点具备PTP支持,以确保纳秒级的同步精度。尽管传统的NTP能满足多数应用场景,提供大约5毫秒内的时钟同步,非极高端需求外,PTP并非标配之选,因其对硬件和网络配置有着更高要求。

PTP协议在IEEE 1588标准中定义,主要通过两种方式在网络中传输数据包:

  • 基于以太网的数据链路层(MAC层)直接封装:这是PTPv2推荐的方式之一,允许时间同步消息直接在数据链路层传输,绕过了网络层(IP)和传输层(TCP/UDP),从而减少延迟和抖动。这种方式下,PTP报文类型和时间戳在MAC层处理,减少了操作系统和协议栈引入的不确定性。
  • 基于UDP/IP的承载:当直接MAC层传输不可行或不适用时,PTP可以利用UDP/IP协议作为传输载体。PTP事件消息(如Sync和Follow_Up)通常使用UDP端口319,而PTP通用(或普通)消息(如Delay_Req和Delay_Resp)使用UDP端口320。这种方式虽然方便与现有网络基础设施集成,但由于经过了完整的网络协议栈,可能引入更多的时延和不确定性,降低了同步精度。

而想要在UDP上承载PTP,需要确保网络设备(如交换机和终端设备)能够支持PTP,并正确配置网络接口以使用UDP端口转发PTP消息。在软件层面,可以利用编程语言(如C、C++、Python或Go)中的网络编程库来发送和接收这些UDP数据包,并根据PTP协议规范处理时间戳和同步算法。

二、工业相机PTP功能支持

海康工业网口相机支持PTP时钟同步功能,可以通过PTP协议,实现多场景的高精度时间戳同步,例如:多个工业相机之间、工业相机与主机时间、工业相机与硬件授时模块(北斗/GPS授时服务器)等.

海康相机可以通过简单的参数配置,在参数配置Transport layer下启用IEEE 1588 V2(即PTP v2)功能,通过设置相机为主时钟(Master)或从时钟(Slave),并利用交换机等网络设备实现纳秒级的同步拍照。因此,在适当的网络配置下,海康工业相机能够利用PTP功能满足对时间同步有严格要求的应用场景。

海康工业相机支持的PTP状态模式如下:

  • Master(主钟态): 成为Master的PTP设备承担起为网络中的其他设备提供时间基准的责任。它会定期广播时间同步消息(Sync)和对准消息(Follow_Up),帮助网络中的Slave设备与其时间保持一致。Master通常由网络中的设备基于Best Master Clock (BMC)算法选举产生,考虑到了时钟的精度、稳定性等多种因素。
  • Slave(从钟态): 当一个PTP设备确定自身应遵循网络中的另一台设备(即Master)作为时间参考时,它会转变为Slave状态。在此状态下,设备会积极接收来自Master的同步和跟随(Delay_Resp)消息,通过这些信息调整自己的时间,以尽量减小与Master之间的时间偏差,实现精确的时间同步。
  • Uncalibrated(未校准态): 当一个PTP时钟刚开始运行或刚被重置时,它通常处于未校准态。在这个状态下,时钟尚未完成与网络中其他时钟的对齐过程,因此其时间和频率的准确性无法保证。设备在这一阶段主要是在收集网络信息、识别其他PTP设备,并准备进入更高级的状态进行时间同步。
  • Passive(被动态): 被动态是指PTP时钟虽然监听网络上的同步和对准消息,但并不参与主时钟的选择过程,也不进行任何时间调整。它是一个观察者角色,可能用于监控网络状况或准备进入Slave或Master状态而不立即参与同步过程。
    需要注意的是,这些状态之间的转换是动态的,依据设备的性能、网络条件以及PTP协议的内部机制来决定。PTP协议的设计旨在通过这些状态的有序变迁,确保网络中的所有时钟能够高效、准确地达到时间同步

三、工业相机时间戳介绍

工业相机中的时间戳是一种记录图像获取精确时刻的功能,它是工业视觉系统和高精度测量应用中的核心要素。以下是对工业相机时间戳的详细介绍:

3.1基本概念

时间戳指的是附着在每一帧图像数据上的时间信息,通常表示相对于相机内部时钟的相对时间(非UTC时间)。这个时间戳使得用户可以准确知道每幅图像的捕获时间,对于需要精确同步多相机系统、分析动态过程或与外部事件关联的应用至关重要。

a) 实现机制

  • 硬件时间戳:工业相机通常内置高精度振荡器(如温补晶振、铷钟或铯钟)来生成时间基准,确保即使在没有外部时间源的情况下也能维持较高的时间精度。图像传感器在捕获图像的同时,硬件直接在图像数据包中嵌入时间戳,这种机制减少了软件处理的延迟,提高了时间记录的即时性和准确性。
  • 软件时间戳:在一些应用场景中,时间戳也可以通过软件方式在图像数据处理链路的后期添加。虽然这种方法简便,但由于涉及到软件处理流程,相较于硬件时间戳可能会引入额外的延迟。
    b) 精度与同步
    工业相机的时间戳精度可达到微秒甚至纳秒级,这对于需要极高时间分辨率的应用(如高速运动分析、机器视觉引导的机器人操作)至关重要。
    为了在多相机系统中实现精确同步,可以使用诸如 Precision Time Protocol (PTP) 或 GenICam的Time Stamp over Ethernet (ToE) 功能,通过网络基础设施(交换机网络)来同步所有相机的时间基准。
    c) 应用场景
    • 生产制造:在自动化装配线中,时间戳帮助追踪每个部件通过各个检查点的确切时间,用于质量控制和过程优化。
    • 运动捕捉:在体育分析、生物力学研究中,高精度时间戳确保了动作的精确计时和分析。
    • 科学研究:如天文观测、粒子物理实验中,时间戳对于精确记录和分析瞬时事件至关重要。
    • 安全监控:在安全和监控应用中,时间戳是事件重建和证据记录的关键。

3.2海康工业相机时间戳介绍

海康工业相机支持多种途径获取相机内部时间戳,主要分类如下:

  • 相机参数时间戳:用户主动读取相机参数TimestampValue,获取访问当前参数时刻的相机内部时间戳
  • 图像嵌入式时间戳:产生图像前,相机内部自动记录时间,通过嵌入到图像帧信息内部,方便用户获取
  • Event事件时间戳:记录相机内部各种事件时刻的时间戳

三种类型的时间戳,都是基于相机内部时钟产生相对时间,由硬件晶振生成时间基准,开始时间一般为相机上电时刻

3.2.1相机参数时间戳

相机参数 说明
GevTimestampTickFrequency 相机时间戳晶振频率,其倒数即为时间戳的单位,如时钟频率为 100MHz 时相机时间戳单位为 10ns,不同相机该频率可能不同,需要结合该参数具体值来确认
GevTimestampControlLatch 获取当前的时间戳值,时间戳值并不会自动更新,使用时需要执行该命令进 行获取
GevTimestampValue 时间戳值,需搭配GevTimestampControlLatch获取,本身不会主动更新

3.2.2图像嵌入式时间戳

图像嵌入式时间戳,用于记录相机的拍照时刻。

通常需要结合sdk接口,在_MV_FRAME_OUT_INFO_EX_帧信息结构体获取得到;

也可以通过Wireshark抓包,获取相机的图像数据流GVSP包,在leader头包中获取;

3.2.3相机event事件时间戳

海康工业相机支持多种事件,每一种事件产生,都会有时间戳记录

事件类型 简介
Acquisition Start 采集开始
Acquisition End 采集结束
Frame Start 帧开始
Frame End 帧结束
Frame Burst Start 帧触发开始
Frame Burst End 帧触发结束
Exposure Start 曝光开始
Exposure End 曝光结束
Line0 Rising Edge Line 0 上升沿
Line0 Falling Edge Line 0 下降沿
Frame Start Over Trigger 帧开始过触发
Over Run 过载
Stream Transfer Overflow 相机缓存内图像被覆盖
Frame Trigger Wait 帧触发等待,相机可被触发时输出event
Software Active 软触发有效
Image Error 图像错误

在MVS中,设置操作方法:

  1. 在相机参数中,开启所要选择的事件,以Exposure Start事件为例
  2. 开始相机取流曝光,在事件监视器中,获取事件信息

3.2.4各种时间戳的时序关系

以相机常用的时间戳为例,梳理了下工业相机比较场景的时间戳关系,以相机相对时间为基准,具体如下图:

  1. Line0RisingEdge:触发信号通过line0给到相机

  2. FrameStart:图像输出开始

  3. nDevTimeStamp:时间戳打包到leader包时刻

  4. ExposureStart:sensor开始曝光时刻

  5. ExposureEnd:sensor结束曝光时刻

  6. nHoststamp: 图像头包到达主机时间,主机时间,非相机时间戳

  7. FrameEnd:相机端图像输出结束

3.2.5通过工业相机SDK获取相机时间戳

  1. 事件时间戳
c 复制代码
// ch:开启相机Event功能 | en:Set Event  On
char const *nEvent_ID[]={"Line0RisingEdge","FrameStart","FrameEnd", "ExposureStart","ExposureEnd"};
for(int i=0;i<sizeof(nEvent_ID)/sizeof(nEvent_ID[0]);i++)
{
	nRet = MV_CC_SetEnumValueByString(handle, "EventSelector",nEvent_ID[i]);
	if (MV_OK != nRet)
	{
		printf("Set Event Selector fail! nRet [0x%x],nEvent_ID:%d\n", nRet,i);
	}
	nRet = MV_CC_SetEnumValueByString(handle, "EventNotification", "On");
	if (MV_OK != nRet)
	{
		printf("Set Event Notification fail! nRet [0x%x]\n", nRet);
	}
	// ch:注册event事件回调函数
	nRet = MV_CC_RegisterEventCallBackEx(handle, nEvent_ID[i],EventCallBack, handle);
	if (MV_OK != nRet)
	{
		printf("Register Event CallBack fail! nRet [0x%x]\n", nRet);
	}	
}		

相机事件配置与事件回调函数注册

c 复制代码
void __stdcall EventCallBack(MV_EVENT_OUT_INFO * pEventInfo, void* pUser)
{
    if (pEventInfo)
    {
        int64_t nBlockId = pEventInfo->nBlockIdHigh;
        nBlockId = (nBlockId << 32) + pEventInfo->nBlockIdLow;
        int64_t nTimestamp = pEventInfo->nTimestampHigh;
        nTimestamp = (nTimestamp << 32) + pEventInfo->nTimestampLow;
		printf("EventName[%s],Timestamp[" "%" PRIu64 "]\n",pEventInfo->EventName,nTimestamp);
    }
}

事件回调函数内部处理

  1. 图像时间戳
c 复制代码
void __stdcall ImageCallBackEx(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser)
{
	uint64_t m_DevTimeStamp=0;//设备产生图像的时间
	int64_t  m_HostTimeStamp =0;//图像头包到达主机时间
    if (pFrameInfo)
    {
		m_DevTimeStamp = pFrameInfo->nDevTimeStampHigh;
		m_DevTimeStamp = (m_DevTimeStamp << 32)+pFrameInfo->nDevTimeStampLow;
		m_HostTimeStamp=pFrameInfo->nHostTimeStamp;
		printf("GetOneFrame, Width[%d], Height[%d], nFrameNum[%d],nDevTimeStamp[" "%" PRIu64 "],nHostTimeStamp[" "%" PRIu64 "]\n",
		pFrameInfo->nWidth, pFrameInfo->nHeight, pFrameInfo->nFrameNum,m_DevTimeStamp,m_HostTimeStamp);
    }
}

通过回调函数取流并通过帧信息结构体中获取nDevTimeStamp、nHoststamp

  1. 相机参数时间戳获取
c 复制代码
//获取相机当前时间戳
//仅网口相机支持
MVCC_INTVALUE_EX nGevTimestampValue;
nRet = MV_CC_SetCommandValue(handle, "GevTimestampControlLatch");
if (MV_OK != nRet)
{
	printf("Gev TimestampControlLatch fail! nRet [%x]\n", nRet);
	//break; 
}else
{
	nRet = MV_CC_GetIntValueEx(handle,"GevTimestampValue",&nGevTimestampValue);
	if (MV_OK == nRet)
	{
		printf("Get GevTimestampValue =  [%lld] Success!\n",(long long)nGevTimestampValue.nCurValue);
	}
}

四、通过PTPD实现主机与相机系统时钟同步

4.1 ptpd服务部署

参考文章:ptpd安装部署
ptpd开源链接:github

ptpd通常指的是实现Precision Time Protocol (PTP) 协议的守护进程,用于在计算机网络中提供高精度的时间同步服务;

  1. 查看网卡与ip
bash 复制代码
1|sudo apt-get install net-tools
2|ifconfig

2、查看网卡支持项

bash 复制代码
1|sudo apt-get install ethtool
2|sudo ethtool -T ens33

软件时间戳需要包括参数

bash 复制代码
SOF_TIMESTAMPING_SOFTWARE
SOF_TIMESTAMPING_TX_SOFTWARE
SOF_TIMESTAMPING_RX_SOFTWARE

硬件时间戳需要包括参数

bash 复制代码
SOF_TIMESTAMPING_RAW_HARDWARE
SOF_TIMESTAMPING_TX_HARDWARE
SOF_TIMESTAMPING_RX_HARDWARE
  1. 查看NTP(网络时间同步)状态,并关闭
bash 复制代码
timedatectl  status
sudo timedatectl set-ntp false
  1. ptpd安装部署
bash 复制代码
sudo apt-get install ptpd
  1. 选定主机网卡ens33,开启ptpd作为主时钟master
bash 复制代码
sudo ptpd -M -i ens33

开启ptpd后,可在进程中发现ptpd相关进程

  1. 主机作为从时钟(相机或其他设备作为主设备)
bash 复制代码
sudo ptpd -g -i ens33
注:步骤4和5加入-C参数的话,会在前台运行,并打印输出,如在主时钟端:

例:sudo ptpd -M -C -i ens33

  1. 关闭进程

测试结束时,可直接使用kill命令,结束进程中的ptpd,恢复NTP服务

bash 复制代码
sudo pkill ptpd
sudo timedatectl set-ntp true

4.2 PTP时钟同步测试

PTP时钟同步,可以搭配不同的硬件有多种Master、Slave组合,如下表所示

Master Slave
电脑主机 工业相机、硬件同步设备、电脑主机
工业相机 电脑主机、工业相机、硬件同步设备
硬件同步设备(GPS等) 工业相机、电脑主机、硬件同步设备

本文主要基于PTPD介绍表格中第一种情况,即Ubuntu主机,作为Master、工业相机作为Slave模式

测试方法:

  1. Ubuntu开启Master模式
bash 复制代码
sudo ptpd -M -i ens33
  1. 工业相机开启1588模式
  2. 使用工业相机时间戳,测试同步效果如下

    按照时间维度,对时间戳进行排序与计算
时间戳类型 时间戳ID 时间戳 时间差us(100MHz) ns 说明
Event Line0RisingEdge 1716878696804977842 / / /
Event FrameStart 1716878696804990022 12.18 12180 FrameStart- Line0RisingEdge
Image nDevTimeStamp 1716878696804990082 0.06 60 nDevTimeStamp- FrameStart
Event ExposureStart 1716878696804991182 1.1 1100 ExposureStart- nDevTimeStamp
Event ExposureEnd 1716878696810658622 5667.44 5667440 ExposureEnd- ExposureStart
Host nHostTimeStamp 1716878696811 341.378 341378 nHostTimeStamp- ExposureEnd
Event FrameEnd 1716878696836186552 25186.552 25186552 FrameEnd- nHostTimeStamp

HostTimeStamp与相机的各种时间戳时间单位基本一致

关闭ptpd进程服务,相机断电重新测试

bash 复制代码
sudo pkill ptpd
时间戳类型 时间戳ID 时间戳 时间差us(100MHz) ns 说明
Event Line0RisingEdge 32279293504138 / / /
Event FrameStart 32279293509238 5.1 5100 FrameStart- Line0RisingEdge
Image nDevTimeStamp 32279293509298 0.06 60 nDevTimeStamp- FrameStart
Event ExposureStart 32279293510398 1.1 1100 ExposureStart- nDevTimeStamp
Event ExposureEnd 32279299177970 5667.572 5667572 ExposureEnd- ExposureStart
Host nHostTimeStamp 1716872579325 / / /
Event FrameEnd 32279324706381 25528.41 25528411 FrameEnd- ExposureEnd

关闭ptpd服务后,主机时间nHostTimeStamp不与相机时间同步

其他:

  1. 如需实现工业相机与工业相机之间PTP同步,只需要选定一台相机做master,先开启1588参数使能接口,其他相机后开启,会自动协商成slave模式;如需实现1588触发同步功能,建议参考海康工业相机ActionCommand功能
  2. 如需在windows上实现ptpd等类似功能,需要找能够在windows上运行的ptp开源项目;或者使用硬件设备作为master,相机只需要作为slave在windows上面运行
    测试代码基于ubuntu 系统,海康工业相机示例程序Grab_ImageCallback修改,可自行下载测试
相关推荐
51camera1 个月前
Dragonfly S 5MP工业相机量产 机器视觉应用的新选择
视觉检测·机器视觉·工业相机
小俊俊的博客1 个月前
海康相机opencv,C++调用demo配置记录
c++·opencv·工业相机·海康
51camera1 个月前
简述灰点工业相机的相关知识
机器视觉·工业相机·灰点相机
资深流水灯工程师3 个月前
机器视觉:工业相机的主要参数
工业相机
LabVIEW开发3 个月前
LabVIEW图像采集处理项目中相机选择与应用
数码相机·计算机视觉·labview·工业相机
lylsalt5 个月前
相机知识的补充
人工智能·计算机视觉·工业相机
lylsalt5 个月前
关于海康相机和镜头参数的记录
工业相机
paw5zx5 个月前
开源相机管理库Aravis例程学习(五)——camera-api
c++·工业相机
paw5zx5 个月前
开源相机管理库Aravis例程学习(四)——multiple-acquisition-signal
工业相机