如何使用SDK进行UTC时间同步 #123

Open
opened 2021-04-22 04:43:14 +02:00 by feiwei93 · 15 comments
feiwei93 commented 2021-04-22 04:43:14 +02:00 (Migrated from github.com)

如何utc同步来进行采样保存lvx文件呢?目前参考lidar_utc_sync与lidar_lvx_sample结合,控制逻辑是连接Lidar并配置同步,使用LidarStartSampling来进行采样,但收到的数据包时间戳并不是UTC时间。该如何在采样程序中嵌入同步UTC?能提供一下代码吗?

如何utc同步来进行采样保存lvx文件呢?目前参考lidar_utc_sync与lidar_lvx_sample结合,控制逻辑是连接Lidar并配置同步,使用LidarStartSampling来进行采样,但收到的数据包时间戳并不是UTC时间。该如何在采样程序中嵌入同步UTC?能提供一下代码吗?
Gitwlmai commented 2021-06-08 11:49:57 +02:00 (Migrated from github.com)

请问你解决了吗?我也遇到同样问题,打印点云的时间戳与UTC时间戳不一致

请问你解决了吗?我也遇到同样问题,打印点云的时间戳与UTC时间戳不一致
Gitwlmai commented 2021-06-10 04:54:52 +02:00 (Migrated from github.com)

兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里

兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里
feiwei93 commented 2021-06-11 03:12:34 +02:00 (Migrated from github.com)

不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗?

来自 Outlookhttp://aka.ms/weboutlook


发件人: Gitwlmai @.>
发送时间: 2021年6月10日 10:55
收件人: Livox-SDK/Livox-SDK @.
>
抄送: feiwei93 @.>; State change @.>
主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHubhttps://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-858240176, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA.

不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlook<http://aka.ms/weboutlook> ________________________________ 发件人: Gitwlmai ***@***.***> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK ***@***.***> 抄送: feiwei93 ***@***.***>; State change ***@***.***> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-858240176>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA>.
Gitwlmai commented 2021-06-11 03:31:01 +02:00 (Migrated from github.com)

我用的是GPS+PPS的同步方式,GPS发送UTC到我们的主机然后通过SDK发给雷达,PPS脉冲1HZ接雷达的同步接口,然后时间戳就如下所示
Rmc: $GNRMC,115611.00,A,2309.6336714,N,11322.8560422,E,0.013,319.4,090621,0.0,E,D*2A 第一步接收RMC时间
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419517
time: 21/6/9 11:3371000000 打印RMC时间21/6/9 11:3371000000
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419917 点云输出时间 21-6-9 11:3356419917 (两者相差了将近15s)
[2021-06-09 19:56:11.070] [console] [info] Send Command: Set 1 Id 10 Seq 208 [command_channel.cpp] [Send] [247]
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420316
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420715
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421114
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421515
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421913
lidar: data_type:6 ts_type:3 timeStamp: 21-6-9 11:3356421623
[2021-06-09 19:56:11.072] [console] [info] Recieve Ack: Set 1 Id 10 Seq 208 [command_handler.cpp] [OnCommand] [118]
OnLidarSetRmcSyncTimeCallback statue 0 handle 0 response 0.

没有同步到点云上,有偏差,我用的是2.3.0的SDK,应该是最新的

我用的是GPS+PPS的同步方式,GPS发送UTC到我们的主机然后通过SDK发给雷达,PPS脉冲1HZ接雷达的同步接口,然后时间戳就如下所示 Rmc: $GNRMC,115611.00,A,2309.6336714,N,11322.8560422,E,0.013,319.4,090621,0.0,E,D*2A 第一步接收RMC时间 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419517 time: 21/6/9 11:3371000000 打印RMC时间21/6/9 11:3371000000 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419917 点云输出时间 21-6-9 11:3356419917 (两者相差了将近15s) [2021-06-09 19:56:11.070] [console] [info] Send Command: Set 1 Id 10 Seq 208 [command_channel.cpp] [Send] [247] lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420316 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420715 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421114 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421515 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421913 lidar: data_type:6 ts_type:3 timeStamp: 21-6-9 11:3356421623 [2021-06-09 19:56:11.072] [console] [info] Recieve Ack: Set 1 Id 10 Seq 208 [command_handler.cpp] [OnCommand] [118] OnLidarSetRmcSyncTimeCallback statue 0 handle 0 response 0. 没有同步到点云上,有偏差,我用的是2.3.0的SDK,应该是最新的
feiwei93 commented 2021-06-11 03:33:39 +02:00 (Migrated from github.com)

我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。
来自 Outlookhttp://aka.ms/weboutlook


发件人: Fei Wei @.>
发送时间: 2021年6月11日 9:12
收件人: Livox-SDK/Livox-SDK @.
>
主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗?

来自 Outlookhttp://aka.ms/weboutlook


发件人: Gitwlmai @.>
发送时间: 2021年6月10日 10:55
收件人: Livox-SDK/Livox-SDK @.
>
抄送: feiwei93 @.>; State change @.>
主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHubhttps://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-858240176, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA.

我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlook<http://aka.ms/weboutlook> ________________________________ 发件人: Fei Wei ***@***.***> 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK ***@***.***> 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlook<http://aka.ms/weboutlook> ________________________________ 发件人: Gitwlmai ***@***.***> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK ***@***.***> 抄送: feiwei93 ***@***.***>; State change ***@***.***> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-858240176>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA>.
Gitwlmai commented 2021-06-11 03:43:52 +02:00 (Migrated from github.com)

不是直接解析GPS端发过来的时间直接通过SDK给到雷达吗?

不是直接解析GPS端发过来的时间直接通过SDK给到雷达吗?
feiwei93 commented 2021-06-11 03:47:13 +02:00 (Migrated from github.com)

你打印的rmc时间不是GNRMC的时间。你确定用GNRMC同步主机时间了吗?两者相差的时间可能是你代码运行的时间发自我的iPhone------------------ 原始邮件 ------------------发件人: Gitwlmai @.>发送时间: 2021年6月11日 09:31收件人: Livox-SDK/Livox-SDK @.>抄送: feiwei93 @.>, State change @.>主题: 回复:[Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)
我用的是GPS+PPS的同步方式,GPS发送UTC到我们的主机然后通过SDK发给雷达,PPS脉冲1HZ接雷达的同步接口,然后时间戳就如下所示
Rmc: $GNRMC,115611.00,A,2309.6336714,N,11322.8560422,E,0.013,319.4,090621,0.0,E,D*2A 第一步接收RMC时间
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419517
time: 21/6/9 11:3371000000 打印RMC时间21/6/9 11:3371000000
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419917 点云输出时间 21-6-9 11:3356419917 (两者相差了将近15s)
[2021-06-09 19:56:11.070] [console] [info] Send Command: Set 1 Id 10 Seq 208 [command_channel.cpp] [Send] [247]
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420316
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420715
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421114
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421515
lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421913
lidar: data_type:6 ts_type:3 timeStamp: 21-6-9 11:3356421623
[2021-06-09 19:56:11.072] [console] [info] Recieve Ack: Set 1 Id 10 Seq 208 [command_handler.cpp] [OnCommand] [118]
OnLidarSetRmcSyncTimeCallback statue 0 handle 0 response 0.
没有同步到点云上,有偏差,我用的是2.3.0的SDK,应该是最新的

—You are receiving this because you modified the open/close state.Reply to this email directly, view it on GitHub, or unsubscribe.
[
{
@.": "http://schema.org",
@.
": "EmailMessage",
"potentialAction": {
@.": "ViewAction",
"target": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859195069",
"url": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859195069",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
@.
": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]

你打印的rmc时间不是GNRMC的时间。你确定用GNRMC同步主机时间了吗?两者相差的时间可能是你代码运行的时间发自我的iPhone------------------ 原始邮件 ------------------发件人: Gitwlmai ***@***.***>发送时间: 2021年6月11日 09:31收件人: Livox-SDK/Livox-SDK ***@***.***>抄送: feiwei93 ***@***.***>, State change ***@***.***>主题: 回复:[Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我用的是GPS+PPS的同步方式,GPS发送UTC到我们的主机然后通过SDK发给雷达,PPS脉冲1HZ接雷达的同步接口,然后时间戳就如下所示 Rmc: $GNRMC,115611.00,A,2309.6336714,N,11322.8560422,E,0.013,319.4,090621,0.0,E,D*2A 第一步接收RMC时间 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419517 time: 21/6/9 11:3371000000 打印RMC时间21/6/9 11:3371000000 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356419917 点云输出时间 21-6-9 11:3356419917 (两者相差了将近15s) [2021-06-09 19:56:11.070] [console] [info] Send Command: Set 1 Id 10 Seq 208 [command_channel.cpp] [Send] [247] lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420316 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356420715 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421114 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421515 lidar: data_type:2 ts_type:3 timeStamp: 21-6-9 11:3356421913 lidar: data_type:6 ts_type:3 timeStamp: 21-6-9 11:3356421623 [2021-06-09 19:56:11.072] [console] [info] Recieve Ack: Set 1 Id 10 Seq 208 [command_handler.cpp] [OnCommand] [118] OnLidarSetRmcSyncTimeCallback statue 0 handle 0 response 0. 没有同步到点云上,有偏差,我用的是2.3.0的SDK,应该是最新的 —You are receiving this because you modified the open/close state.Reply to this email directly, view it on GitHub, or unsubscribe. [ { ***@***.***": "http://schema.org", ***@***.***": "EmailMessage", "potentialAction": { ***@***.***": "ViewAction", "target": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859195069", "url": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859195069", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { ***@***.***": "Organization", "name": "GitHub", "url": "https://github.com" } } ]
feiwei93 commented 2021-06-11 03:51:04 +02:00 (Migrated from github.com)

不是的,要先同步一下主机时间,你这个点云的时间不是GPS的时间,是主机的localtime,你看一下sample里面的lvx_file代码,确认一下是否用到过这个函数发自我的iPhone------------------ 原始邮件 ------------------发件人: Gitwlmai @.>发送时间: 2021年6月11日 09:44收件人: Livox-SDK/Livox-SDK @.>抄送: feiwei93 @.>, State change @.>主题: 回复:[Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)
不是直接解析GPS端发过来的时间直接通过SDK给到雷达吗?

—You are receiving this because you modified the open/close state.Reply to this email directly, view it on GitHub, or unsubscribe.
[
{
@.": "http://schema.org",
@.
": "EmailMessage",
"potentialAction": {
@.": "ViewAction",
"target": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859199255",
"url": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859199255",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
@.
": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]

不是的,要先同步一下主机时间,你这个点云的时间不是GPS的时间,是主机的localtime,你看一下sample里面的lvx_file代码,确认一下是否用到过这个函数发自我的iPhone------------------ 原始邮件 ------------------发件人: Gitwlmai ***@***.***>发送时间: 2021年6月11日 09:44收件人: Livox-SDK/Livox-SDK ***@***.***>抄送: feiwei93 ***@***.***>, State change ***@***.***>主题: 回复:[Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不是直接解析GPS端发过来的时间直接通过SDK给到雷达吗? —You are receiving this because you modified the open/close state.Reply to this email directly, view it on GitHub, or unsubscribe. [ { ***@***.***": "http://schema.org", ***@***.***": "EmailMessage", "potentialAction": { ***@***.***": "ViewAction", "target": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859199255", "url": "https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859199255", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { ***@***.***": "Organization", "name": "GitHub", "url": "https://github.com" } } ]
Gitwlmai commented 2021-06-11 03:57:11 +02:00 (Migrated from github.com)

我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢?

我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢?
feiwei93 commented 2021-06-11 04:04:28 +02:00 (Migrated from github.com)

那个lidar_utc_sample代码本身就不是完整的代码。你只运行了lidar_utc_sample这一个代码吗?这样吧,你先把主机的时间随便改成一个错误的时间,然后在运行你之前的代码,打印出来看看。
来自 Outlookhttp://aka.ms/weboutlook


发件人: Gitwlmai @.>
发送时间: 2021年6月11日 9:57
收件人: Livox-SDK/Livox-SDK @.
>
抄送: feiwei93 @.>; State change @.>
主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢?


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHubhttps://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859204312, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKX3OHXXQFTB3EDGMXLTSFUQHANCNFSM43LQXVZA.

那个lidar_utc_sample代码本身就不是完整的代码。你只运行了lidar_utc_sample这一个代码吗?这样吧,你先把主机的时间随便改成一个错误的时间,然后在运行你之前的代码,打印出来看看。 来自 Outlook<http://aka.ms/weboutlook> ________________________________ 发件人: Gitwlmai ***@***.***> 发送时间: 2021年6月11日 9:57 收件人: Livox-SDK/Livox-SDK ***@***.***> 抄送: feiwei93 ***@***.***>; State change ***@***.***> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢? ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859204312>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARFAWKX3OHXXQFTB3EDGMXLTSFUQHANCNFSM43LQXVZA>.
Gitwlmai commented 2021-06-11 04:13:20 +02:00 (Migrated from github.com)

我大概理解您的意思,就是点云输出的时间戳应该是主机的localtime,我只需要根据GPS的时间修正主机的localtime就行了。但是我有个疑问,SDK为啥提供发送UTC时间的接口给lidar,然后官网的文档这样描述的:Livox 设备接收到 PPS 信号上升沿,并由 GPRMC 数据解析出正确的时间信息后,会设置点云时间为 GPS 时间,并保持此时间基准持续累加,来实现和 GPS 设备的时间同步 看它的意思是会设置点云时间为GPS时间。

我大概理解您的意思,就是点云输出的时间戳应该是主机的localtime,我只需要根据GPS的时间修正主机的localtime就行了。但是我有个疑问,SDK为啥提供发送UTC时间的接口给lidar,然后官网的文档这样描述的:_**Livox 设备接收到 PPS 信号上升沿,并由 GPRMC 数据解析出正确的时间信息后,会设置点云时间为 GPS 时间,并保持此时间基准持续累加,来实现和 GPS 设备的时间同步**_ 看它的意思是会设置点云时间为GPS时间。
Gitwlmai commented 2021-06-11 07:36:54 +02:00 (Migrated from github.com)

那个lidar_utc_sample代码本身就不是完整的代码。你只运行了lidar_utc_sample这一个代码吗?这样吧,你先把主机的时间随便改成一个错误的时间,然后在运行你之前的代码,打印出来看看。 来自 Outlookhttp://aka.ms/weboutlook

________________________________ 发件人: Gitwlmai @.> 发送时间: 2021年6月11日 9:57 收件人: Livox-SDK/Livox-SDK @.> 抄送: feiwei93 @.>; State change @.> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢? ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKX3OHXXQFTB3EDGMXLTSFUQHANCNFSM43LQXVZA.

您好,我按照您的方法,将主机的时间修改之后,实际上点云的时间戳还是按照GPS时间进行输出的,只不过这个时间戳没有对齐,相差几秒。不知您那边是这么做的

> 那个lidar_utc_sample代码本身就不是完整的代码。你只运行了lidar_utc_sample这一个代码吗?这样吧,你先把主机的时间随便改成一个错误的时间,然后在运行你之前的代码,打印出来看看。 来自 Outlook<http://aka.ms/weboutlook> > […](#) > ________________________________ 发件人: Gitwlmai ***@***.***> 发送时间: 2021年6月11日 9:57 收件人: Livox-SDK/Livox-SDK ***@***.***> 抄送: feiwei93 ***@***.***>; State change ***@***.***> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我看了一下那个lidar_utc_sample,它是直接读取/dev/ttyUSB0发过来的GPRMC数据,然后解析出里面的UTC时间,直接通过SDK发给雷达,所以我是参照它这个sample做的,您说同步主机时间,官方提供的demo里面没看到这一步骤呢? ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<[#123 (comment)](https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-859204312)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARFAWKX3OHXXQFTB3EDGMXLTSFUQHANCNFSM43LQXVZA>. 您好,我按照您的方法,将主机的时间修改之后,实际上点云的时间戳还是按照GPS时间进行输出的,只不过这个时间戳没有对齐,相差几秒。不知您那边是这么做的
tianyu-56 commented 2021-06-16 07:54:09 +02:00 (Migrated from github.com)

我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlookhttp://aka.ms/weboutlook

________________________________ 发件人: Fei Wei @.> 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK @.> 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlookhttp://aka.ms/weboutlook
________________________________ 发件人: Gitwlmai @.> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK @.> 抄送: feiwei93 @.>; State change @.> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA.

您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢!

> 我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlook<http://aka.ms/weboutlook> > […](#) > ________________________________ 发件人: Fei Wei ***@***.***> 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK ***@***.***> 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlook<http://aka.ms/weboutlook> > ________________________________ 发件人: Gitwlmai ***@***.***> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK ***@***.***> 抄送: feiwei93 ***@***.***>; State change ***@***.***> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<[#123 (comment)](https://github.com/Livox-SDK/Livox-SDK/issues/123#issuecomment-858240176)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA>. 您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢!
tianyu-56 commented 2021-06-18 11:53:59 +02:00 (Migrated from github.com)

非常感谢您!我好好学习一下,再次感谢!!

---原始邮件---
发件人: @.>
发送时间: 2021年6月18日(周五) 下午5:17
收件人: @.
>;
抄送: @.@.>;
主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlookhttp://aka.ms/weboutlook

________________________________ 发件人: Fei Wei @.> 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK @**.> 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlookhttp://aka.ms/weboutlook
________________________________ 发件人: Gitwlmai @.> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK @._> 抄送: feiwei93 @.>; State change @.**_> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA.

您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢!

你好,这是我整合后的完整代码,已经测试过可以运行希望对你有所帮助。大家相互学习,欢迎交流!
#include
#include <string.h>
#include "lvx_file.h"
#include "cmdline.h"
#include <stdio.h>
#include <stdlib.h>
#include
#include
#include "lds_lidar.h"
#include "synchro.h"

DeviceItem devices[kMaxLidarCount];
LvxFileHandle lvx_file_handler;
std::list point_packet_list;
std::vectorstd::string broadcast_code_rev;
std::condition_variable lidar_arrive_condition;
std::condition_variable extrinsic_condition;
std::condition_variable point_pack_condition;
std::mutex mtx;
int lvx_file_save_time =10; //设置运行时间(s)
bool is_finish_extrinsic_parameter = false;
bool is_read_extrinsic_from_xml = false;
uint8_t connected_lidar_count = 0;

#define FRAME_RATE 20

using namespace std::chrono;

/** Cmdline input broadcast code */
static std::vectorstd::string cmdline_broadcast_code;

/** Connect all the broadcast device in default and connect specific device when use program options or broadcast_code_list is not empty. */
std::vectorstd::string broadcast_code_list = {
"3GGDJ3300100351"
};

/** Receiving error message from Livox Lidar. */
void OnLidarErrorStatusCallback(livox_status status, uint8_t handle, ErrorMessage *message) {
static uint32_t error_message_count = 0;
if (message != NULL) {
++error_message_count;
if (0 == (error_message_count % 100)) {
printf("handle: %u\n", handle);
printf("temp_status : %u\n", message->lidar_error_code.temp_status);
printf("volt_status : %u\n", message->lidar_error_code.volt_status);
printf("motor_status : %u\n", message->lidar_error_code.motor_status);
printf("dirty_warn : %u\n", message->lidar_error_code.dirty_warn);
printf("firmware_err : %u\n", message->lidar_error_code.firmware_err);
printf("pps_status : %u\n", message->lidar_error_code.device_status);
printf("fan_status : %u\n", message->lidar_error_code.fan_status);
printf("self_heating : %u\n", message->lidar_error_code.self_heating);
printf("ptp_status : %u\n", message->lidar_error_code.ptp_status);
printf("time_sync_status : %u\n", message->lidar_error_code.time_sync_status);
printf("system_status : %u\n", message->lidar_error_code.system_status);
}
}
}

/** Receiving point cloud data from Livox LiDAR. */
void GetLidarData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *client_data) {
if (data) {
if (handle < connected_lidar_count && is_finish_extrinsic_parameter) {
std::unique_lockstd::mutex lock(mtx);
LvxBasePackDetail packet;
packet.device_index = handle;
lvx_file_handler.BasePointsHandle(data, packet);
point_packet_list.push_back(packet);
}
}
}

/** Callback function of starting sampling. */
void OnSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) {
printf("OnSampleCallback statues %d handle %d response %d \n", status, handle, response);
if (status == kStatusSuccess) {
if (response != 0) {
devices[handle].device_state = kDeviceStateConnect;
}
} else if (status == kStatusTimeout) {
devices[handle].device_state = kDeviceStateConnect;
}
}

/** Callback function of stopping sampling. */
void OnStopSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) {
}

/** Callback function of get LiDARs' extrinsic parameter. */
void OnGetLidarExtrinsicParameter(livox_status status, uint8_t handle, LidarGetExtrinsicParameterResponse *response, void *data) {
if (status == kStatusSuccess) {
if (response != 0) {
printf("OnGetLidarExtrinsicParameter statue %d handle %d response %d \n", status, handle, response->ret_code);
std::unique_lockstd::mutex lock(mtx);
LvxDeviceInfo lidar_info;
strncpy((char *)lidar_info.lidar_broadcast_code, devices[handle].info.broadcast_code, kBroadcastCodeSize);
memset(lidar_info.hub_broadcast_code, 0, kBroadcastCodeSize);
lidar_info.device_index = handle;
lidar_info.device_type = devices[handle].info.type;
lidar_info.extrinsic_enable = true;
lidar_info.pitch = response->pitch;
lidar_info.roll = response->roll;
lidar_info.yaw = response->yaw;
lidar_info.x = static_cast(response->x / 1000.0);
lidar_info.y = static_cast(response->y / 1000.0);
lidar_info.z = static_cast(response->z / 1000.0);
lvx_file_handler.AddDeviceInfo(lidar_info);
if (lvx_file_handler.GetDeviceInfoListSize() == connected_lidar_count) {
is_finish_extrinsic_parameter = true;
extrinsic_condition.notify_one();
}
}
}
else if (status == kStatusTimeout) {
printf("GetLidarExtrinsicParameter timeout! \n");
}
}

/** Get LiDARs' extrinsic parameter from file named "extrinsic.xml". */
void LidarGetExtrinsicFromXml(uint8_t handle) {
LvxDeviceInfo lidar_info;
ParseExtrinsicXml(devices[handle], lidar_info);
lvx_file_handler.AddDeviceInfo(lidar_info);
lidar_info.extrinsic_enable = true;
if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) {
is_finish_extrinsic_parameter = true;
extrinsic_condition.notify_one();
}
}

/** Query the firmware version of Livox LiDAR. */
void OnDeviceInformation(livox_status status, uint8_t handle, DeviceInformationResponse *ack, void *data) {
if (status != kStatusSuccess) {
printf("Device Query Informations Failed %d\n", status);
}
if (ack) {
printf("firm ver: %d.%d.%d.%d\n",
ack->firmware_version[0],
ack->firmware_version[1],
ack->firmware_version[2],
ack->firmware_version[3]);
}
}

void LidarConnect(const DeviceInfo *info) {
uint8_t handle = info->handle;
QueryDeviceInformation(handle, OnDeviceInformation, NULL);
if (devices[handle].device_state == kDeviceStateDisconnect) {
devices[handle].device_state = kDeviceStateConnect;
devices[handle].info = *info;
}
}

void LidarDisConnect(const DeviceInfo *info) {
uint8_t handle = info->handle;
devices[handle].device_state = kDeviceStateDisconnect;
}

void LidarStateChange(const DeviceInfo *info) {
uint8_t handle = info->handle;
devices[handle].info = *info;
}

/** Callback function of changing of device state. */
void OnDeviceInfoChange(const DeviceInfo *info, DeviceEvent type) {
if (info == nullptr) {
return;
}
printf("OnDeviceChange broadcast code %s update type %d\n", info->broadcast_code, type);
uint8_t handle = info->handle;
if (handle >= kMaxLidarCount) {
return;
}

if (type == kEventConnect) {
LidarConnect(info);
printf("[WARNING] Lidar sn: [%s] Connect!!!\n", info->broadcast_code);
} else if (type == kEventDisconnect) {
LidarDisConnect(info);
printf("[WARNING] Lidar sn: [%s] Disconnect!!!\n", info->broadcast_code);
} else if (type == kEventStateChange) {
LidarStateChange(info);
printf("[WARNING] Lidar sn: [%s] StateChange!!!\n", info->broadcast_code);
}

if (devices[handle].device_state == kDeviceStateConnect) {
printf("Device Working State %d\n", devices[handle].info.state);
if (devices[handle].info.state == kLidarStateInit) {
printf("Device State Change Progress %u\n", devices[handle].info.status.progress);
} else {
printf("Device State Error Code 0X%08x\n", devices[handle].info.status.status_code.error_code);
}
printf("Device feature %d\n", devices[handle].info.feature);
SetErrorMessageCallback(handle, OnLidarErrorStatusCallback);
if (devices[handle].info.state == kLidarStateNormal) {
if (!is_read_extrinsic_from_xml) {
LidarGetExtrinsicParameter(handle, OnGetLidarExtrinsicParameter, nullptr);
} else {
LidarGetExtrinsicFromXml(handle);
}
LidarStartSampling(handle, OnSampleCallback, nullptr);
devices[handle].device_state = kDeviceStateSampling;
}
}
}

/** Callback function when broadcast message received.

You need to add listening device broadcast code and set the point cloud data callback in this function.
*/
void OnDeviceBroadcast(const BroadcastDeviceInfo *info) {
if (info == nullptr || info->dev_type == kDeviceTypeHub) {
return;
}

printf("Receive Broadcast Code %s\n", info->broadcast_code);
if ((broadcast_code_rev.size() == 0) ||
(std::find(broadcast_code_rev.begin(), broadcast_code_rev.end(), info->broadcast_code) == broadcast_code_rev.end())) {
broadcast_code_rev.push_back(info->broadcast_code);
lidar_arrive_condition.notify_one();
}
}

/** Wait until no new device arriving in 2 second. */
void WaitForDevicesReady( ) {
bool device_ready = false;
seconds wait_time = seconds(2);
steady_clock::time_point last_time = steady_clock::now();
while (!device_ready) {
std::unique_lockstd::mutex lock(mtx);
lidar_arrive_condition.wait_for(lock,wait_time);
if ((steady_clock::now() - last_time + milliseconds(50)) >= wait_time) {
device_ready = true;
} else {
last_time = steady_clock::now();
}
}
}

void WaitForExtrinsicParameter() {
std::unique_lockstd::mutex lock(mtx);
extrinsic_condition.wait(lock);
}

void AddDevicesToConnect() {
if (broadcast_code_rev.size() == 0)
return;

for (int i = 0; i < broadcast_code_rev.size(); ++i) {
if ((broadcast_code_list.size() != 0) &&
(std::find(broadcast_code_list.begin(), broadcast_code_list.end(), broadcast_code_rev[i]) == broadcast_code_list.end())) {
continue;
}
uint8_t handle = 0;
livox_status result = AddLidarToConnect(broadcast_code_rev[i].c_str(), &handle);
if (result == kStatusSuccess) {
/** Set the point cloud data for a specific Livox LiDAR. */
SetDataCallback(handle, GetLidarData, nullptr);
devices[handle].handle = handle;
devices[handle].device_state = kDeviceStateDisconnect;
connected_lidar_count++;
}
}
}

/** Set the program options.

You can input the registered device broadcast code and decide whether to save the log file.
*/
void SetProgramOption(int argc, const char *argv[]) {
cmdline::parser cmd;
cmd.addstd::string("code", 'c', "Register device broadcast code", false);
cmd.add("log", 'l', "Save the log file");
cmd.add("time", 't', "Time to save point cloud to the lvx file", false);
cmd.add("param", 'p', "Get the extrinsic parameter from extrinsic.xml file");
cmd.add("help", 'h', "Show help");
cmd.parse_check(argc, const_cast<char **>(argv));
if (cmd.exist("code")) {
std::string sn_list = cmd.getstd::string("code");
printf("Register broadcast code: %s\n", sn_list.c_str());
size_t pos = 0;
broadcast_code_list.clear();
while ((pos = sn_list.find("&")) != std::string::npos) {
broadcast_code_list.push_back(sn_list.substr(0, pos));
sn_list.erase(0, pos + 1);
}
broadcast_code_list.push_back(sn_list);
}
if (cmd.exist("log")) {
printf("Save the log file.\n");
SaveLoggerFile();
}
if (cmd.exist("time")) {
printf("Time to save point cloud to the lvx file:%d.\n", cmd.get("time"));
lvx_file_save_time = cmd.get("time");
}
if (cmd.exist("param")) {
printf("Get the extrinsic parameter from extrinsic.xml file.\n");
is_read_extrinsic_from_xml = true;
}
return;
}

int main(int argc, const char argv[]) {
/* Set the program options. */
SetProgramOption(argc, argv);

LdsLidar& read_lidar = LdsLidar::GetInstance();

int ret = read_lidar.InitLdsLidar(cmdline_broadcast_code);
if (!ret) {
printf("Init lds lidar success!\n");
} else {
printf("Init lds lidar fail!\n");
return 0;
}

printf("Start discovering device.\n");

Synchro& synchro = Synchro::GetInstance();
#ifdef WIN32
synchro.SetPortName("COM1");
#else
synchro.SetPortName("/dev/ttyUSB0");
#endif

/** Set Synchro's Baudrate: 115200. /
synchro.SetBaudRate(BR115200);
/* Set Synchro's Parity: No parity (8N1). /
synchro.SetParity(P_8N1);
/* SyncTimer Callback will trigger when Synchro's GPRMC/GNRMC signal is ready. */
synchro.SetSyncTimerCallback(read_lidar.SetRmcSyncTime);
if (synchro.Start()) {
printf("Synchro start success\n");
} else {
printf("Synchro start failed\n");
return 0;
}

std::this_thread::sleep_for(std::chrono::seconds(2));

//synchro.Stop();
read_lidar.DeInitLdsLidar();
//printf("Livox lidar demo end!\n");
std::this_thread::sleep_for(std::chrono::seconds(2));

/*********************************************************/
printf("Livox SDK initializing.\n");
//Initialize Livox-SDK.
if (!Init()) {
return -1;
}
printf("Livox SDK has been initialized.\n");

LivoxSdkVersion _sdkversion;
GetLivoxSdkVersion(&_sdkversion);
printf("Livox SDK version %d.%d.%d .\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch);

memset(devices, 0, sizeof(devices));

/** Set the callback function receiving broadcast message from Livox LiDAR. */
SetBroadcastCallback(OnDeviceBroadcast);

/** Set the callback function called when device state change,

which means connection/disconnection and changing of LiDAR state.
*/
SetDeviceStateUpdateCallback(OnDeviceInfoChange);

/** Start the device discovering routine. */
if (!Start()) {
Uninit();
return -1;
}
printf("Start discovering device.\n");

WaitForDevicesReady();

AddDevicesToConnect();

if (connected_lidar_count == 0) {
printf("No device will be connected.\n");
Uninit();
return -1;
}

WaitForExtrinsicParameter();

/等待GPS同步后, 才记录点云数据生成.lvx文件*******/

printf("Start initialize lvx file.\n");
if (!lvx_file_handler.InitLvxFile()) {
Uninit();
return -1;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
lvx_file_handler.InitLvxFileHeader();
int i = 0;
steady_clock::time_point last_time = steady_clock::now();
for (i = 0; i < lvx_file_save_time * FRAME_RATE; ++i) {
std::list point_packet_list_temp;
{
std::unique_lockstd::mutex lock(mtx);
point_pack_condition.wait_for(lock, milliseconds(kDefaultFrameDurationTime) - (steady_clock::now() - last_time));
last_time = steady_clock::now();
point_packet_list_temp.swap(point_packet_list);
}
if(point_packet_list_temp.empty()) {
printf("Point cloud packet is empty.\n");
break;
}
printf("Finish save %d frame to lvx file.\n", i);
lvx_file_handler.SaveFrameToLvxFile(point_packet_list_temp);
}

lvx_file_handler.CloseLvxFile();

for (i = 0; i < kMaxLidarCount; ++i) {
if (devices[i].device_state == kDeviceStateSampling) {
/** Stop the sampling of Livox LiDAR. */
LidarStopSampling(devices[i].handle, OnStopSampleCallback, nullptr);
}
}

/** Uninitialize Livox-SDK. */
Uninit();
}


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

非常感谢您!我好好学习一下,再次感谢!! ---原始邮件--- 发件人: ***@***.***&gt; 发送时间: 2021年6月18日(周五) 下午5:17 收件人: ***@***.***&gt;; 抄送: ***@***.******@***.***&gt;; 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlookhttp://aka.ms/weboutlook … ________________________________ 发件人: Fei Wei @.&gt; 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK _@**._&gt; 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlookhttp://aka.ms/weboutlook ________________________________ 发件人: Gitwlmai ***@***.***&gt; 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK @._&gt; 抄送: feiwei93 ***@***.***&gt;; State change @.**_&gt; 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)&gt;, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA. 您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢! 你好,这是我整合后的完整代码,已经测试过可以运行希望对你有所帮助。大家相互学习,欢迎交流! #include #include <string.h&gt; #include "lvx_file.h" #include "cmdline.h" #include <stdio.h&gt; #include <stdlib.h&gt; #include #include #include "lds_lidar.h" #include "synchro.h" DeviceItem devices[kMaxLidarCount]; LvxFileHandle lvx_file_handler; std::list point_packet_list; std::vectorstd::string broadcast_code_rev; std::condition_variable lidar_arrive_condition; std::condition_variable extrinsic_condition; std::condition_variable point_pack_condition; std::mutex mtx; int lvx_file_save_time =10; //设置运行时间(s) bool is_finish_extrinsic_parameter = false; bool is_read_extrinsic_from_xml = false; uint8_t connected_lidar_count = 0; #define FRAME_RATE 20 using namespace std::chrono; /** Cmdline input broadcast code */ static std::vectorstd::string cmdline_broadcast_code; /** Connect all the broadcast device in default and connect specific device when use program options or broadcast_code_list is not empty. */ std::vectorstd::string broadcast_code_list = { "3GGDJ3300100351" }; /** Receiving error message from Livox Lidar. */ void OnLidarErrorStatusCallback(livox_status status, uint8_t handle, ErrorMessage *message) { static uint32_t error_message_count = 0; if (message != NULL) { ++error_message_count; if (0 == (error_message_count % 100)) { printf("handle: %u\n", handle); printf("temp_status : %u\n", message-&gt;lidar_error_code.temp_status); printf("volt_status : %u\n", message-&gt;lidar_error_code.volt_status); printf("motor_status : %u\n", message-&gt;lidar_error_code.motor_status); printf("dirty_warn : %u\n", message-&gt;lidar_error_code.dirty_warn); printf("firmware_err : %u\n", message-&gt;lidar_error_code.firmware_err); printf("pps_status : %u\n", message-&gt;lidar_error_code.device_status); printf("fan_status : %u\n", message-&gt;lidar_error_code.fan_status); printf("self_heating : %u\n", message-&gt;lidar_error_code.self_heating); printf("ptp_status : %u\n", message-&gt;lidar_error_code.ptp_status); printf("time_sync_status : %u\n", message-&gt;lidar_error_code.time_sync_status); printf("system_status : %u\n", message-&gt;lidar_error_code.system_status); } } } /** Receiving point cloud data from Livox LiDAR. */ void GetLidarData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *client_data) { if (data) { if (handle < connected_lidar_count &amp;&amp; is_finish_extrinsic_parameter) { std::unique_lockstd::mutex lock(mtx); LvxBasePackDetail packet; packet.device_index = handle; lvx_file_handler.BasePointsHandle(data, packet); point_packet_list.push_back(packet); } } } /** Callback function of starting sampling. */ void OnSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) { printf("OnSampleCallback statues %d handle %d response %d \n", status, handle, response); if (status == kStatusSuccess) { if (response != 0) { devices[handle].device_state = kDeviceStateConnect; } } else if (status == kStatusTimeout) { devices[handle].device_state = kDeviceStateConnect; } } /** Callback function of stopping sampling. */ void OnStopSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) { } /** Callback function of get LiDARs' extrinsic parameter. */ void OnGetLidarExtrinsicParameter(livox_status status, uint8_t handle, LidarGetExtrinsicParameterResponse *response, void *data) { if (status == kStatusSuccess) { if (response != 0) { printf("OnGetLidarExtrinsicParameter statue %d handle %d response %d \n", status, handle, response-&gt;ret_code); std::unique_lockstd::mutex lock(mtx); LvxDeviceInfo lidar_info; strncpy((char *)lidar_info.lidar_broadcast_code, devices[handle].info.broadcast_code, kBroadcastCodeSize); memset(lidar_info.hub_broadcast_code, 0, kBroadcastCodeSize); lidar_info.device_index = handle; lidar_info.device_type = devices[handle].info.type; lidar_info.extrinsic_enable = true; lidar_info.pitch = response-&gt;pitch; lidar_info.roll = response-&gt;roll; lidar_info.yaw = response-&gt;yaw; lidar_info.x = static_cast(response-&gt;x / 1000.0); lidar_info.y = static_cast(response-&gt;y / 1000.0); lidar_info.z = static_cast(response-&gt;z / 1000.0); lvx_file_handler.AddDeviceInfo(lidar_info); if (lvx_file_handler.GetDeviceInfoListSize() == connected_lidar_count) { is_finish_extrinsic_parameter = true; extrinsic_condition.notify_one(); } } } else if (status == kStatusTimeout) { printf("GetLidarExtrinsicParameter timeout! \n"); } } /** Get LiDARs' extrinsic parameter from file named "extrinsic.xml". */ void LidarGetExtrinsicFromXml(uint8_t handle) { LvxDeviceInfo lidar_info; ParseExtrinsicXml(devices[handle], lidar_info); lvx_file_handler.AddDeviceInfo(lidar_info); lidar_info.extrinsic_enable = true; if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) { is_finish_extrinsic_parameter = true; extrinsic_condition.notify_one(); } } /** Query the firmware version of Livox LiDAR. */ void OnDeviceInformation(livox_status status, uint8_t handle, DeviceInformationResponse *ack, void *data) { if (status != kStatusSuccess) { printf("Device Query Informations Failed %d\n", status); } if (ack) { printf("firm ver: %d.%d.%d.%d\n", ack-&gt;firmware_version[0], ack-&gt;firmware_version[1], ack-&gt;firmware_version[2], ack-&gt;firmware_version[3]); } } void LidarConnect(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; QueryDeviceInformation(handle, OnDeviceInformation, NULL); if (devices[handle].device_state == kDeviceStateDisconnect) { devices[handle].device_state = kDeviceStateConnect; devices[handle].info = *info; } } void LidarDisConnect(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; devices[handle].device_state = kDeviceStateDisconnect; } void LidarStateChange(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; devices[handle].info = *info; } /** Callback function of changing of device state. */ void OnDeviceInfoChange(const DeviceInfo *info, DeviceEvent type) { if (info == nullptr) { return; } printf("OnDeviceChange broadcast code %s update type %d\n", info-&gt;broadcast_code, type); uint8_t handle = info-&gt;handle; if (handle &gt;= kMaxLidarCount) { return; } if (type == kEventConnect) { LidarConnect(info); printf("[WARNING] Lidar sn: [%s] Connect!!!\n", info-&gt;broadcast_code); } else if (type == kEventDisconnect) { LidarDisConnect(info); printf("[WARNING] Lidar sn: [%s] Disconnect!!!\n", info-&gt;broadcast_code); } else if (type == kEventStateChange) { LidarStateChange(info); printf("[WARNING] Lidar sn: [%s] StateChange!!!\n", info-&gt;broadcast_code); } if (devices[handle].device_state == kDeviceStateConnect) { printf("Device Working State %d\n", devices[handle].info.state); if (devices[handle].info.state == kLidarStateInit) { printf("Device State Change Progress %u\n", devices[handle].info.status.progress); } else { printf("Device State Error Code 0X%08x\n", devices[handle].info.status.status_code.error_code); } printf("Device feature %d\n", devices[handle].info.feature); SetErrorMessageCallback(handle, OnLidarErrorStatusCallback); if (devices[handle].info.state == kLidarStateNormal) { if (!is_read_extrinsic_from_xml) { LidarGetExtrinsicParameter(handle, OnGetLidarExtrinsicParameter, nullptr); } else { LidarGetExtrinsicFromXml(handle); } LidarStartSampling(handle, OnSampleCallback, nullptr); devices[handle].device_state = kDeviceStateSampling; } } } /** Callback function when broadcast message received. You need to add listening device broadcast code and set the point cloud data callback in this function. */ void OnDeviceBroadcast(const BroadcastDeviceInfo *info) { if (info == nullptr || info-&gt;dev_type == kDeviceTypeHub) { return; } printf("Receive Broadcast Code %s\n", info-&gt;broadcast_code); if ((broadcast_code_rev.size() == 0) || (std::find(broadcast_code_rev.begin(), broadcast_code_rev.end(), info-&gt;broadcast_code) == broadcast_code_rev.end())) { broadcast_code_rev.push_back(info-&gt;broadcast_code); lidar_arrive_condition.notify_one(); } } /** Wait until no new device arriving in 2 second. */ void WaitForDevicesReady( ) { bool device_ready = false; seconds wait_time = seconds(2); steady_clock::time_point last_time = steady_clock::now(); while (!device_ready) { std::unique_lockstd::mutex lock(mtx); lidar_arrive_condition.wait_for(lock,wait_time); if ((steady_clock::now() - last_time + milliseconds(50)) &gt;= wait_time) { device_ready = true; } else { last_time = steady_clock::now(); } } } void WaitForExtrinsicParameter() { std::unique_lockstd::mutex lock(mtx); extrinsic_condition.wait(lock); } void AddDevicesToConnect() { if (broadcast_code_rev.size() == 0) return; for (int i = 0; i < broadcast_code_rev.size(); ++i) { if ((broadcast_code_list.size() != 0) &amp;&amp; (std::find(broadcast_code_list.begin(), broadcast_code_list.end(), broadcast_code_rev[i]) == broadcast_code_list.end())) { continue; } uint8_t handle = 0; livox_status result = AddLidarToConnect(broadcast_code_rev[i].c_str(), &amp;handle); if (result == kStatusSuccess) { /** Set the point cloud data for a specific Livox LiDAR. */ SetDataCallback(handle, GetLidarData, nullptr); devices[handle].handle = handle; devices[handle].device_state = kDeviceStateDisconnect; connected_lidar_count++; } } } /** Set the program options. You can input the registered device broadcast code and decide whether to save the log file. */ void SetProgramOption(int argc, const char *argv[]) { cmdline::parser cmd; cmd.addstd::string("code", 'c', "Register device broadcast code", false); cmd.add("log", 'l', "Save the log file"); cmd.add("time", 't', "Time to save point cloud to the lvx file", false); cmd.add("param", 'p', "Get the extrinsic parameter from extrinsic.xml file"); cmd.add("help", 'h', "Show help"); cmd.parse_check(argc, const_cast<char **&gt;(argv)); if (cmd.exist("code")) { std::string sn_list = cmd.getstd::string("code"); printf("Register broadcast code: %s\n", sn_list.c_str()); size_t pos = 0; broadcast_code_list.clear(); while ((pos = sn_list.find("&amp;")) != std::string::npos) { broadcast_code_list.push_back(sn_list.substr(0, pos)); sn_list.erase(0, pos + 1); } broadcast_code_list.push_back(sn_list); } if (cmd.exist("log")) { printf("Save the log file.\n"); SaveLoggerFile(); } if (cmd.exist("time")) { printf("Time to save point cloud to the lvx file:%d.\n", cmd.get("time")); lvx_file_save_time = cmd.get("time"); } if (cmd.exist("param")) { printf("Get the extrinsic parameter from extrinsic.xml file.\n"); is_read_extrinsic_from_xml = true; } return; } int main(int argc, const char argv[]) { /* Set the program options. */ SetProgramOption(argc, argv); LdsLidar&amp; read_lidar = LdsLidar::GetInstance(); int ret = read_lidar.InitLdsLidar(cmdline_broadcast_code); if (!ret) { printf("Init lds lidar success!\n"); } else { printf("Init lds lidar fail!\n"); return 0; } printf("Start discovering device.\n"); Synchro&amp; synchro = Synchro::GetInstance(); #ifdef WIN32 synchro.SetPortName("COM1"); #else synchro.SetPortName("/dev/ttyUSB0"); #endif /** Set Synchro's Baudrate: 115200. / synchro.SetBaudRate(BR115200); /* Set Synchro's Parity: No parity (8N1). / synchro.SetParity(P_8N1); /* SyncTimer Callback will trigger when Synchro's GPRMC/GNRMC signal is ready. */ synchro.SetSyncTimerCallback(read_lidar.SetRmcSyncTime); if (synchro.Start()) { printf("Synchro start success\n"); } else { printf("Synchro start failed\n"); return 0; } std::this_thread::sleep_for(std::chrono::seconds(2)); //synchro.Stop(); read_lidar.DeInitLdsLidar(); //printf("Livox lidar demo end!\n"); std::this_thread::sleep_for(std::chrono::seconds(2)); /*********************************************************/ printf("Livox SDK initializing.\n"); //Initialize Livox-SDK. if (!Init()) { return -1; } printf("Livox SDK has been initialized.\n"); LivoxSdkVersion _sdkversion; GetLivoxSdkVersion(&amp;_sdkversion); printf("Livox SDK version %d.%d.%d .\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch); memset(devices, 0, sizeof(devices)); /** Set the callback function receiving broadcast message from Livox LiDAR. */ SetBroadcastCallback(OnDeviceBroadcast); /** Set the callback function called when device state change, which means connection/disconnection and changing of LiDAR state. */ SetDeviceStateUpdateCallback(OnDeviceInfoChange); /** Start the device discovering routine. */ if (!Start()) { Uninit(); return -1; } printf("Start discovering device.\n"); WaitForDevicesReady(); AddDevicesToConnect(); if (connected_lidar_count == 0) { printf("No device will be connected.\n"); Uninit(); return -1; } WaitForExtrinsicParameter(); /等待GPS同步后, 才记录点云数据生成.lvx文件*******/ printf("Start initialize lvx file.\n"); if (!lvx_file_handler.InitLvxFile()) { Uninit(); return -1; } std::this_thread::sleep_for(std::chrono::seconds(5)); lvx_file_handler.InitLvxFileHeader(); int i = 0; steady_clock::time_point last_time = steady_clock::now(); for (i = 0; i < lvx_file_save_time * FRAME_RATE; ++i) { std::list point_packet_list_temp; { std::unique_lockstd::mutex lock(mtx); point_pack_condition.wait_for(lock, milliseconds(kDefaultFrameDurationTime) - (steady_clock::now() - last_time)); last_time = steady_clock::now(); point_packet_list_temp.swap(point_packet_list); } if(point_packet_list_temp.empty()) { printf("Point cloud packet is empty.\n"); break; } printf("Finish save %d frame to lvx file.\n", i); lvx_file_handler.SaveFrameToLvxFile(point_packet_list_temp); } lvx_file_handler.CloseLvxFile(); for (i = 0; i < kMaxLidarCount; ++i) { if (devices[i].device_state == kDeviceStateSampling) { /** Stop the sampling of Livox LiDAR. */ LidarStopSampling(devices[i].handle, OnStopSampleCallback, nullptr); } } /** Uninitialize Livox-SDK. */ Uninit(); } — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
tianyu-56 commented 2021-06-19 11:48:31 +02:00 (Migrated from github.com)

非常抱歉又打扰您,我最近两天尝试编译了您发给我的代码,但我发现里面有很多错误,您发给我的应该是替换后的main.cpp,我已经把ample_cc\lidar_utc_sync下的lds_lidar和synchro代码复制到了sample\lidar_lvx_file文件夹下,运行还是会出错,请教下是我的过程有误吗,如果方便能在邮件附件里附上所有的文件吗?  十分抱歉浪费您的时间了!

------------------ 原始邮件 ------------------
发件人: "Livox-SDK/Livox-SDK" @.>;
发送时间: 2021年6月18日(星期五) 下午5:17
@.
>;
@.@.>;
主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123)

我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlookhttp://aka.ms/weboutlook

________________________________ 发件人: Fei Wei @.> 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK @**.> 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlookhttp://aka.ms/weboutlook
________________________________ 发件人: Gitwlmai @.> 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK @._> 抄送: feiwei93 @.>; State change @.**_> 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA.

您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢!

你好,这是我整合后的完整代码,已经测试过可以运行希望对你有所帮助。大家相互学习,欢迎交流!
#include
#include <string.h>
#include "lvx_file.h"
#include "cmdline.h"
#include <stdio.h>
#include <stdlib.h>
#include
#include
#include "lds_lidar.h"
#include "synchro.h"

DeviceItem devices[kMaxLidarCount];
LvxFileHandle lvx_file_handler;
std::list point_packet_list;
std::vectorstd::string broadcast_code_rev;
std::condition_variable lidar_arrive_condition;
std::condition_variable extrinsic_condition;
std::condition_variable point_pack_condition;
std::mutex mtx;
int lvx_file_save_time =10; //设置运行时间(s)
bool is_finish_extrinsic_parameter = false;
bool is_read_extrinsic_from_xml = false;
uint8_t connected_lidar_count = 0;

#define FRAME_RATE 20

using namespace std::chrono;

/** Cmdline input broadcast code */
static std::vectorstd::string cmdline_broadcast_code;

/** Connect all the broadcast device in default and connect specific device when use program options or broadcast_code_list is not empty. */
std::vectorstd::string broadcast_code_list = {
"3GGDJ3300100351"
};

/** Receiving error message from Livox Lidar. */
void OnLidarErrorStatusCallback(livox_status status, uint8_t handle, ErrorMessage *message) {
static uint32_t error_message_count = 0;
if (message != NULL) {
++error_message_count;
if (0 == (error_message_count % 100)) {
printf("handle: %u\n", handle);
printf("temp_status : %u\n", message->lidar_error_code.temp_status);
printf("volt_status : %u\n", message->lidar_error_code.volt_status);
printf("motor_status : %u\n", message->lidar_error_code.motor_status);
printf("dirty_warn : %u\n", message->lidar_error_code.dirty_warn);
printf("firmware_err : %u\n", message->lidar_error_code.firmware_err);
printf("pps_status : %u\n", message->lidar_error_code.device_status);
printf("fan_status : %u\n", message->lidar_error_code.fan_status);
printf("self_heating : %u\n", message->lidar_error_code.self_heating);
printf("ptp_status : %u\n", message->lidar_error_code.ptp_status);
printf("time_sync_status : %u\n", message->lidar_error_code.time_sync_status);
printf("system_status : %u\n", message->lidar_error_code.system_status);
}
}
}

/** Receiving point cloud data from Livox LiDAR. */
void GetLidarData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *client_data) {
if (data) {
if (handle < connected_lidar_count && is_finish_extrinsic_parameter) {
std::unique_lockstd::mutex lock(mtx);
LvxBasePackDetail packet;
packet.device_index = handle;
lvx_file_handler.BasePointsHandle(data, packet);
point_packet_list.push_back(packet);
}
}
}

/** Callback function of starting sampling. */
void OnSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) {
printf("OnSampleCallback statues %d handle %d response %d \n", status, handle, response);
if (status == kStatusSuccess) {
if (response != 0) {
devices[handle].device_state = kDeviceStateConnect;
}
} else if (status == kStatusTimeout) {
devices[handle].device_state = kDeviceStateConnect;
}
}

/** Callback function of stopping sampling. */
void OnStopSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) {
}

/** Callback function of get LiDARs' extrinsic parameter. */
void OnGetLidarExtrinsicParameter(livox_status status, uint8_t handle, LidarGetExtrinsicParameterResponse *response, void *data) {
if (status == kStatusSuccess) {
if (response != 0) {
printf("OnGetLidarExtrinsicParameter statue %d handle %d response %d \n", status, handle, response->ret_code);
std::unique_lockstd::mutex lock(mtx);
LvxDeviceInfo lidar_info;
strncpy((char *)lidar_info.lidar_broadcast_code, devices[handle].info.broadcast_code, kBroadcastCodeSize);
memset(lidar_info.hub_broadcast_code, 0, kBroadcastCodeSize);
lidar_info.device_index = handle;
lidar_info.device_type = devices[handle].info.type;
lidar_info.extrinsic_enable = true;
lidar_info.pitch = response->pitch;
lidar_info.roll = response->roll;
lidar_info.yaw = response->yaw;
lidar_info.x = static_cast(response->x / 1000.0);
lidar_info.y = static_cast(response->y / 1000.0);
lidar_info.z = static_cast(response->z / 1000.0);
lvx_file_handler.AddDeviceInfo(lidar_info);
if (lvx_file_handler.GetDeviceInfoListSize() == connected_lidar_count) {
is_finish_extrinsic_parameter = true;
extrinsic_condition.notify_one();
}
}
}
else if (status == kStatusTimeout) {
printf("GetLidarExtrinsicParameter timeout! \n");
}
}

/** Get LiDARs' extrinsic parameter from file named "extrinsic.xml". */
void LidarGetExtrinsicFromXml(uint8_t handle) {
LvxDeviceInfo lidar_info;
ParseExtrinsicXml(devices[handle], lidar_info);
lvx_file_handler.AddDeviceInfo(lidar_info);
lidar_info.extrinsic_enable = true;
if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) {
is_finish_extrinsic_parameter = true;
extrinsic_condition.notify_one();
}
}

/** Query the firmware version of Livox LiDAR. */
void OnDeviceInformation(livox_status status, uint8_t handle, DeviceInformationResponse *ack, void *data) {
if (status != kStatusSuccess) {
printf("Device Query Informations Failed %d\n", status);
}
if (ack) {
printf("firm ver: %d.%d.%d.%d\n",
ack->firmware_version[0],
ack->firmware_version[1],
ack->firmware_version[2],
ack->firmware_version[3]);
}
}

void LidarConnect(const DeviceInfo *info) {
uint8_t handle = info->handle;
QueryDeviceInformation(handle, OnDeviceInformation, NULL);
if (devices[handle].device_state == kDeviceStateDisconnect) {
devices[handle].device_state = kDeviceStateConnect;
devices[handle].info = *info;
}
}

void LidarDisConnect(const DeviceInfo *info) {
uint8_t handle = info->handle;
devices[handle].device_state = kDeviceStateDisconnect;
}

void LidarStateChange(const DeviceInfo *info) {
uint8_t handle = info->handle;
devices[handle].info = *info;
}

/** Callback function of changing of device state. */
void OnDeviceInfoChange(const DeviceInfo *info, DeviceEvent type) {
if (info == nullptr) {
return;
}
printf("OnDeviceChange broadcast code %s update type %d\n", info->broadcast_code, type);
uint8_t handle = info->handle;
if (handle >= kMaxLidarCount) {
return;
}

if (type == kEventConnect) {
LidarConnect(info);
printf("[WARNING] Lidar sn: [%s] Connect!!!\n", info->broadcast_code);
} else if (type == kEventDisconnect) {
LidarDisConnect(info);
printf("[WARNING] Lidar sn: [%s] Disconnect!!!\n", info->broadcast_code);
} else if (type == kEventStateChange) {
LidarStateChange(info);
printf("[WARNING] Lidar sn: [%s] StateChange!!!\n", info->broadcast_code);
}

if (devices[handle].device_state == kDeviceStateConnect) {
printf("Device Working State %d\n", devices[handle].info.state);
if (devices[handle].info.state == kLidarStateInit) {
printf("Device State Change Progress %u\n", devices[handle].info.status.progress);
} else {
printf("Device State Error Code 0X%08x\n", devices[handle].info.status.status_code.error_code);
}
printf("Device feature %d\n", devices[handle].info.feature);
SetErrorMessageCallback(handle, OnLidarErrorStatusCallback);
if (devices[handle].info.state == kLidarStateNormal) {
if (!is_read_extrinsic_from_xml) {
LidarGetExtrinsicParameter(handle, OnGetLidarExtrinsicParameter, nullptr);
} else {
LidarGetExtrinsicFromXml(handle);
}
LidarStartSampling(handle, OnSampleCallback, nullptr);
devices[handle].device_state = kDeviceStateSampling;
}
}
}

/** Callback function when broadcast message received.

You need to add listening device broadcast code and set the point cloud data callback in this function.
*/
void OnDeviceBroadcast(const BroadcastDeviceInfo *info) {
if (info == nullptr || info->dev_type == kDeviceTypeHub) {
return;
}

printf("Receive Broadcast Code %s\n", info->broadcast_code);
if ((broadcast_code_rev.size() == 0) ||
(std::find(broadcast_code_rev.begin(), broadcast_code_rev.end(), info->broadcast_code) == broadcast_code_rev.end())) {
broadcast_code_rev.push_back(info->broadcast_code);
lidar_arrive_condition.notify_one();
}
}

/** Wait until no new device arriving in 2 second. */
void WaitForDevicesReady( ) {
bool device_ready = false;
seconds wait_time = seconds(2);
steady_clock::time_point last_time = steady_clock::now();
while (!device_ready) {
std::unique_lockstd::mutex lock(mtx);
lidar_arrive_condition.wait_for(lock,wait_time);
if ((steady_clock::now() - last_time + milliseconds(50)) >= wait_time) {
device_ready = true;
} else {
last_time = steady_clock::now();
}
}
}

void WaitForExtrinsicParameter() {
std::unique_lockstd::mutex lock(mtx);
extrinsic_condition.wait(lock);
}

void AddDevicesToConnect() {
if (broadcast_code_rev.size() == 0)
return;

for (int i = 0; i < broadcast_code_rev.size(); ++i) {
if ((broadcast_code_list.size() != 0) &&
(std::find(broadcast_code_list.begin(), broadcast_code_list.end(), broadcast_code_rev[i]) == broadcast_code_list.end())) {
continue;
}
uint8_t handle = 0;
livox_status result = AddLidarToConnect(broadcast_code_rev[i].c_str(), &handle);
if (result == kStatusSuccess) {
/** Set the point cloud data for a specific Livox LiDAR. */
SetDataCallback(handle, GetLidarData, nullptr);
devices[handle].handle = handle;
devices[handle].device_state = kDeviceStateDisconnect;
connected_lidar_count++;
}
}
}

/** Set the program options.

You can input the registered device broadcast code and decide whether to save the log file.
*/
void SetProgramOption(int argc, const char *argv[]) {
cmdline::parser cmd;
cmd.addstd::string("code", 'c', "Register device broadcast code", false);
cmd.add("log", 'l', "Save the log file");
cmd.add("time", 't', "Time to save point cloud to the lvx file", false);
cmd.add("param", 'p', "Get the extrinsic parameter from extrinsic.xml file");
cmd.add("help", 'h', "Show help");
cmd.parse_check(argc, const_cast<char **>(argv));
if (cmd.exist("code")) {
std::string sn_list = cmd.getstd::string("code");
printf("Register broadcast code: %s\n", sn_list.c_str());
size_t pos = 0;
broadcast_code_list.clear();
while ((pos = sn_list.find("&")) != std::string::npos) {
broadcast_code_list.push_back(sn_list.substr(0, pos));
sn_list.erase(0, pos + 1);
}
broadcast_code_list.push_back(sn_list);
}
if (cmd.exist("log")) {
printf("Save the log file.\n");
SaveLoggerFile();
}
if (cmd.exist("time")) {
printf("Time to save point cloud to the lvx file:%d.\n", cmd.get("time"));
lvx_file_save_time = cmd.get("time");
}
if (cmd.exist("param")) {
printf("Get the extrinsic parameter from extrinsic.xml file.\n");
is_read_extrinsic_from_xml = true;
}
return;
}

int main(int argc, const char argv[]) {
/* Set the program options. */
SetProgramOption(argc, argv);

LdsLidar& read_lidar = LdsLidar::GetInstance();

int ret = read_lidar.InitLdsLidar(cmdline_broadcast_code);
if (!ret) {
printf("Init lds lidar success!\n");
} else {
printf("Init lds lidar fail!\n");
return 0;
}

printf("Start discovering device.\n");

Synchro& synchro = Synchro::GetInstance();
#ifdef WIN32
synchro.SetPortName("COM1");
#else
synchro.SetPortName("/dev/ttyUSB0");
#endif

/** Set Synchro's Baudrate: 115200. /
synchro.SetBaudRate(BR115200);
/* Set Synchro's Parity: No parity (8N1). /
synchro.SetParity(P_8N1);
/* SyncTimer Callback will trigger when Synchro's GPRMC/GNRMC signal is ready. */
synchro.SetSyncTimerCallback(read_lidar.SetRmcSyncTime);
if (synchro.Start()) {
printf("Synchro start success\n");
} else {
printf("Synchro start failed\n");
return 0;
}

std::this_thread::sleep_for(std::chrono::seconds(2));

//synchro.Stop();
read_lidar.DeInitLdsLidar();
//printf("Livox lidar demo end!\n");
std::this_thread::sleep_for(std::chrono::seconds(2));

/*********************************************************/
printf("Livox SDK initializing.\n");
//Initialize Livox-SDK.
if (!Init()) {
return -1;
}
printf("Livox SDK has been initialized.\n");

LivoxSdkVersion _sdkversion;
GetLivoxSdkVersion(&_sdkversion);
printf("Livox SDK version %d.%d.%d .\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch);

memset(devices, 0, sizeof(devices));

/** Set the callback function receiving broadcast message from Livox LiDAR. */
SetBroadcastCallback(OnDeviceBroadcast);

/** Set the callback function called when device state change,

which means connection/disconnection and changing of LiDAR state.
*/
SetDeviceStateUpdateCallback(OnDeviceInfoChange);

/** Start the device discovering routine. */
if (!Start()) {
Uninit();
return -1;
}
printf("Start discovering device.\n");

WaitForDevicesReady();

AddDevicesToConnect();

if (connected_lidar_count == 0) {
printf("No device will be connected.\n");
Uninit();
return -1;
}

WaitForExtrinsicParameter();

/等待GPS同步后, 才记录点云数据生成.lvx文件*******/

printf("Start initialize lvx file.\n");
if (!lvx_file_handler.InitLvxFile()) {
Uninit();
return -1;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
lvx_file_handler.InitLvxFileHeader();
int i = 0;
steady_clock::time_point last_time = steady_clock::now();
for (i = 0; i < lvx_file_save_time * FRAME_RATE; ++i) {
std::list point_packet_list_temp;
{
std::unique_lockstd::mutex lock(mtx);
point_pack_condition.wait_for(lock, milliseconds(kDefaultFrameDurationTime) - (steady_clock::now() - last_time));
last_time = steady_clock::now();
point_packet_list_temp.swap(point_packet_list);
}
if(point_packet_list_temp.empty()) {
printf("Point cloud packet is empty.\n");
break;
}
printf("Finish save %d frame to lvx file.\n", i);
lvx_file_handler.SaveFrameToLvxFile(point_packet_list_temp);
}

lvx_file_handler.CloseLvxFile();

for (i = 0; i < kMaxLidarCount; ++i) {
if (devices[i].device_state == kDeviceStateSampling) {
/** Stop the sampling of Livox LiDAR. */
LidarStopSampling(devices[i].handle, OnStopSampleCallback, nullptr);
}
}

/** Uninitialize Livox-SDK. */
Uninit();
}


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

非常抱歉又打扰您,我最近两天尝试编译了您发给我的代码,但我发现里面有很多错误,您发给我的应该是替换后的main.cpp,我已经把ample_cc\lidar_utc_sync下的lds_lidar和synchro代码复制到了sample\lidar_lvx_file文件夹下,运行还是会出错,请教下是我的过程有误吗,如果方便能在邮件附件里附上所有的文件吗?&nbsp; 十分抱歉浪费您的时间了! ------------------&nbsp;原始邮件&nbsp;------------------ 发件人: "Livox-SDK/Livox-SDK" ***@***.***&gt;; 发送时间:&nbsp;2021年6月18日(星期五) 下午5:17 ***@***.***&gt;; ***@***.******@***.***&gt;; 主题:&nbsp;Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 我的是先确认收到GPS信号,用GPS信号同步TX2本机时钟localtime,之后再运行lidar_utc_sync与lidar_lvx_sample的整合代码。 来自 Outlookhttp://aka.ms/weboutlook … ________________________________ 发件人: Fei Wei @.&gt; 发送时间: 2021年6月11日 9:12 收件人: Livox-SDK/Livox-SDK _@**._&gt; 主题: 回复: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 不知道你用的是那种同步方式,我用的是GPS同步,你的是最新版的Livox-SDK吗? 来自 Outlookhttp://aka.ms/weboutlook ________________________________ 发件人: Gitwlmai ***@***.***&gt; 发送时间: 2021年6月10日 10:55 收件人: Livox-SDK/Livox-SDK @._&gt; 抄送: feiwei93 ***@***.***&gt;; State change @.**_&gt; 主题: Re: [Livox-SDK/Livox-SDK] 如何使用SDK进行UTC时间同步 (#123) 兄弟,我看你把这个问题关闭了,你是解决了吗?能分享一下吗?问题一直卡在这里 ― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub<#123 (comment)&gt;, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ARFAWKUY5AY25REHKZPVK5LTSASQRANCNFSM43LQXVZA. 您好,我最近也碰到了这个问题,我想先通过lidar_utc_sync进行雷达和UTC时间同步,然后使用lidar_lvx_sample保存lvx文件,但我发现两个不能同时运行,端口冲突,请问下您是通过什么方法解决的这个问题,把lidar_utc_sync和lidar_lvx_sample整合成一个代码运行吗? 可以提供下参考吗 感谢! 你好,这是我整合后的完整代码,已经测试过可以运行希望对你有所帮助。大家相互学习,欢迎交流! #include #include <string.h&gt; #include "lvx_file.h" #include "cmdline.h" #include <stdio.h&gt; #include <stdlib.h&gt; #include #include #include "lds_lidar.h" #include "synchro.h" DeviceItem devices[kMaxLidarCount]; LvxFileHandle lvx_file_handler; std::list point_packet_list; std::vectorstd::string broadcast_code_rev; std::condition_variable lidar_arrive_condition; std::condition_variable extrinsic_condition; std::condition_variable point_pack_condition; std::mutex mtx; int lvx_file_save_time =10; //设置运行时间(s) bool is_finish_extrinsic_parameter = false; bool is_read_extrinsic_from_xml = false; uint8_t connected_lidar_count = 0; #define FRAME_RATE 20 using namespace std::chrono; /** Cmdline input broadcast code */ static std::vectorstd::string cmdline_broadcast_code; /** Connect all the broadcast device in default and connect specific device when use program options or broadcast_code_list is not empty. */ std::vectorstd::string broadcast_code_list = { "3GGDJ3300100351" }; /** Receiving error message from Livox Lidar. */ void OnLidarErrorStatusCallback(livox_status status, uint8_t handle, ErrorMessage *message) { static uint32_t error_message_count = 0; if (message != NULL) { ++error_message_count; if (0 == (error_message_count % 100)) { printf("handle: %u\n", handle); printf("temp_status : %u\n", message-&gt;lidar_error_code.temp_status); printf("volt_status : %u\n", message-&gt;lidar_error_code.volt_status); printf("motor_status : %u\n", message-&gt;lidar_error_code.motor_status); printf("dirty_warn : %u\n", message-&gt;lidar_error_code.dirty_warn); printf("firmware_err : %u\n", message-&gt;lidar_error_code.firmware_err); printf("pps_status : %u\n", message-&gt;lidar_error_code.device_status); printf("fan_status : %u\n", message-&gt;lidar_error_code.fan_status); printf("self_heating : %u\n", message-&gt;lidar_error_code.self_heating); printf("ptp_status : %u\n", message-&gt;lidar_error_code.ptp_status); printf("time_sync_status : %u\n", message-&gt;lidar_error_code.time_sync_status); printf("system_status : %u\n", message-&gt;lidar_error_code.system_status); } } } /** Receiving point cloud data from Livox LiDAR. */ void GetLidarData(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *client_data) { if (data) { if (handle < connected_lidar_count &amp;&amp; is_finish_extrinsic_parameter) { std::unique_lockstd::mutex lock(mtx); LvxBasePackDetail packet; packet.device_index = handle; lvx_file_handler.BasePointsHandle(data, packet); point_packet_list.push_back(packet); } } } /** Callback function of starting sampling. */ void OnSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) { printf("OnSampleCallback statues %d handle %d response %d \n", status, handle, response); if (status == kStatusSuccess) { if (response != 0) { devices[handle].device_state = kDeviceStateConnect; } } else if (status == kStatusTimeout) { devices[handle].device_state = kDeviceStateConnect; } } /** Callback function of stopping sampling. */ void OnStopSampleCallback(livox_status status, uint8_t handle, uint8_t response, void *data) { } /** Callback function of get LiDARs' extrinsic parameter. */ void OnGetLidarExtrinsicParameter(livox_status status, uint8_t handle, LidarGetExtrinsicParameterResponse *response, void *data) { if (status == kStatusSuccess) { if (response != 0) { printf("OnGetLidarExtrinsicParameter statue %d handle %d response %d \n", status, handle, response-&gt;ret_code); std::unique_lockstd::mutex lock(mtx); LvxDeviceInfo lidar_info; strncpy((char *)lidar_info.lidar_broadcast_code, devices[handle].info.broadcast_code, kBroadcastCodeSize); memset(lidar_info.hub_broadcast_code, 0, kBroadcastCodeSize); lidar_info.device_index = handle; lidar_info.device_type = devices[handle].info.type; lidar_info.extrinsic_enable = true; lidar_info.pitch = response-&gt;pitch; lidar_info.roll = response-&gt;roll; lidar_info.yaw = response-&gt;yaw; lidar_info.x = static_cast(response-&gt;x / 1000.0); lidar_info.y = static_cast(response-&gt;y / 1000.0); lidar_info.z = static_cast(response-&gt;z / 1000.0); lvx_file_handler.AddDeviceInfo(lidar_info); if (lvx_file_handler.GetDeviceInfoListSize() == connected_lidar_count) { is_finish_extrinsic_parameter = true; extrinsic_condition.notify_one(); } } } else if (status == kStatusTimeout) { printf("GetLidarExtrinsicParameter timeout! \n"); } } /** Get LiDARs' extrinsic parameter from file named "extrinsic.xml". */ void LidarGetExtrinsicFromXml(uint8_t handle) { LvxDeviceInfo lidar_info; ParseExtrinsicXml(devices[handle], lidar_info); lvx_file_handler.AddDeviceInfo(lidar_info); lidar_info.extrinsic_enable = true; if (lvx_file_handler.GetDeviceInfoListSize() == broadcast_code_list.size()) { is_finish_extrinsic_parameter = true; extrinsic_condition.notify_one(); } } /** Query the firmware version of Livox LiDAR. */ void OnDeviceInformation(livox_status status, uint8_t handle, DeviceInformationResponse *ack, void *data) { if (status != kStatusSuccess) { printf("Device Query Informations Failed %d\n", status); } if (ack) { printf("firm ver: %d.%d.%d.%d\n", ack-&gt;firmware_version[0], ack-&gt;firmware_version[1], ack-&gt;firmware_version[2], ack-&gt;firmware_version[3]); } } void LidarConnect(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; QueryDeviceInformation(handle, OnDeviceInformation, NULL); if (devices[handle].device_state == kDeviceStateDisconnect) { devices[handle].device_state = kDeviceStateConnect; devices[handle].info = *info; } } void LidarDisConnect(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; devices[handle].device_state = kDeviceStateDisconnect; } void LidarStateChange(const DeviceInfo *info) { uint8_t handle = info-&gt;handle; devices[handle].info = *info; } /** Callback function of changing of device state. */ void OnDeviceInfoChange(const DeviceInfo *info, DeviceEvent type) { if (info == nullptr) { return; } printf("OnDeviceChange broadcast code %s update type %d\n", info-&gt;broadcast_code, type); uint8_t handle = info-&gt;handle; if (handle &gt;= kMaxLidarCount) { return; } if (type == kEventConnect) { LidarConnect(info); printf("[WARNING] Lidar sn: [%s] Connect!!!\n", info-&gt;broadcast_code); } else if (type == kEventDisconnect) { LidarDisConnect(info); printf("[WARNING] Lidar sn: [%s] Disconnect!!!\n", info-&gt;broadcast_code); } else if (type == kEventStateChange) { LidarStateChange(info); printf("[WARNING] Lidar sn: [%s] StateChange!!!\n", info-&gt;broadcast_code); } if (devices[handle].device_state == kDeviceStateConnect) { printf("Device Working State %d\n", devices[handle].info.state); if (devices[handle].info.state == kLidarStateInit) { printf("Device State Change Progress %u\n", devices[handle].info.status.progress); } else { printf("Device State Error Code 0X%08x\n", devices[handle].info.status.status_code.error_code); } printf("Device feature %d\n", devices[handle].info.feature); SetErrorMessageCallback(handle, OnLidarErrorStatusCallback); if (devices[handle].info.state == kLidarStateNormal) { if (!is_read_extrinsic_from_xml) { LidarGetExtrinsicParameter(handle, OnGetLidarExtrinsicParameter, nullptr); } else { LidarGetExtrinsicFromXml(handle); } LidarStartSampling(handle, OnSampleCallback, nullptr); devices[handle].device_state = kDeviceStateSampling; } } } /** Callback function when broadcast message received. You need to add listening device broadcast code and set the point cloud data callback in this function. */ void OnDeviceBroadcast(const BroadcastDeviceInfo *info) { if (info == nullptr || info-&gt;dev_type == kDeviceTypeHub) { return; } printf("Receive Broadcast Code %s\n", info-&gt;broadcast_code); if ((broadcast_code_rev.size() == 0) || (std::find(broadcast_code_rev.begin(), broadcast_code_rev.end(), info-&gt;broadcast_code) == broadcast_code_rev.end())) { broadcast_code_rev.push_back(info-&gt;broadcast_code); lidar_arrive_condition.notify_one(); } } /** Wait until no new device arriving in 2 second. */ void WaitForDevicesReady( ) { bool device_ready = false; seconds wait_time = seconds(2); steady_clock::time_point last_time = steady_clock::now(); while (!device_ready) { std::unique_lockstd::mutex lock(mtx); lidar_arrive_condition.wait_for(lock,wait_time); if ((steady_clock::now() - last_time + milliseconds(50)) &gt;= wait_time) { device_ready = true; } else { last_time = steady_clock::now(); } } } void WaitForExtrinsicParameter() { std::unique_lockstd::mutex lock(mtx); extrinsic_condition.wait(lock); } void AddDevicesToConnect() { if (broadcast_code_rev.size() == 0) return; for (int i = 0; i < broadcast_code_rev.size(); ++i) { if ((broadcast_code_list.size() != 0) &amp;&amp; (std::find(broadcast_code_list.begin(), broadcast_code_list.end(), broadcast_code_rev[i]) == broadcast_code_list.end())) { continue; } uint8_t handle = 0; livox_status result = AddLidarToConnect(broadcast_code_rev[i].c_str(), &amp;handle); if (result == kStatusSuccess) { /** Set the point cloud data for a specific Livox LiDAR. */ SetDataCallback(handle, GetLidarData, nullptr); devices[handle].handle = handle; devices[handle].device_state = kDeviceStateDisconnect; connected_lidar_count++; } } } /** Set the program options. You can input the registered device broadcast code and decide whether to save the log file. */ void SetProgramOption(int argc, const char *argv[]) { cmdline::parser cmd; cmd.addstd::string("code", 'c', "Register device broadcast code", false); cmd.add("log", 'l', "Save the log file"); cmd.add("time", 't', "Time to save point cloud to the lvx file", false); cmd.add("param", 'p', "Get the extrinsic parameter from extrinsic.xml file"); cmd.add("help", 'h', "Show help"); cmd.parse_check(argc, const_cast<char **&gt;(argv)); if (cmd.exist("code")) { std::string sn_list = cmd.getstd::string("code"); printf("Register broadcast code: %s\n", sn_list.c_str()); size_t pos = 0; broadcast_code_list.clear(); while ((pos = sn_list.find("&amp;")) != std::string::npos) { broadcast_code_list.push_back(sn_list.substr(0, pos)); sn_list.erase(0, pos + 1); } broadcast_code_list.push_back(sn_list); } if (cmd.exist("log")) { printf("Save the log file.\n"); SaveLoggerFile(); } if (cmd.exist("time")) { printf("Time to save point cloud to the lvx file:%d.\n", cmd.get("time")); lvx_file_save_time = cmd.get("time"); } if (cmd.exist("param")) { printf("Get the extrinsic parameter from extrinsic.xml file.\n"); is_read_extrinsic_from_xml = true; } return; } int main(int argc, const char argv[]) { /* Set the program options. */ SetProgramOption(argc, argv); LdsLidar&amp; read_lidar = LdsLidar::GetInstance(); int ret = read_lidar.InitLdsLidar(cmdline_broadcast_code); if (!ret) { printf("Init lds lidar success!\n"); } else { printf("Init lds lidar fail!\n"); return 0; } printf("Start discovering device.\n"); Synchro&amp; synchro = Synchro::GetInstance(); #ifdef WIN32 synchro.SetPortName("COM1"); #else synchro.SetPortName("/dev/ttyUSB0"); #endif /** Set Synchro's Baudrate: 115200. / synchro.SetBaudRate(BR115200); /* Set Synchro's Parity: No parity (8N1). / synchro.SetParity(P_8N1); /* SyncTimer Callback will trigger when Synchro's GPRMC/GNRMC signal is ready. */ synchro.SetSyncTimerCallback(read_lidar.SetRmcSyncTime); if (synchro.Start()) { printf("Synchro start success\n"); } else { printf("Synchro start failed\n"); return 0; } std::this_thread::sleep_for(std::chrono::seconds(2)); //synchro.Stop(); read_lidar.DeInitLdsLidar(); //printf("Livox lidar demo end!\n"); std::this_thread::sleep_for(std::chrono::seconds(2)); /*********************************************************/ printf("Livox SDK initializing.\n"); //Initialize Livox-SDK. if (!Init()) { return -1; } printf("Livox SDK has been initialized.\n"); LivoxSdkVersion _sdkversion; GetLivoxSdkVersion(&amp;_sdkversion); printf("Livox SDK version %d.%d.%d .\n", _sdkversion.major, _sdkversion.minor, _sdkversion.patch); memset(devices, 0, sizeof(devices)); /** Set the callback function receiving broadcast message from Livox LiDAR. */ SetBroadcastCallback(OnDeviceBroadcast); /** Set the callback function called when device state change, which means connection/disconnection and changing of LiDAR state. */ SetDeviceStateUpdateCallback(OnDeviceInfoChange); /** Start the device discovering routine. */ if (!Start()) { Uninit(); return -1; } printf("Start discovering device.\n"); WaitForDevicesReady(); AddDevicesToConnect(); if (connected_lidar_count == 0) { printf("No device will be connected.\n"); Uninit(); return -1; } WaitForExtrinsicParameter(); /等待GPS同步后, 才记录点云数据生成.lvx文件*******/ printf("Start initialize lvx file.\n"); if (!lvx_file_handler.InitLvxFile()) { Uninit(); return -1; } std::this_thread::sleep_for(std::chrono::seconds(5)); lvx_file_handler.InitLvxFileHeader(); int i = 0; steady_clock::time_point last_time = steady_clock::now(); for (i = 0; i < lvx_file_save_time * FRAME_RATE; ++i) { std::list point_packet_list_temp; { std::unique_lockstd::mutex lock(mtx); point_pack_condition.wait_for(lock, milliseconds(kDefaultFrameDurationTime) - (steady_clock::now() - last_time)); last_time = steady_clock::now(); point_packet_list_temp.swap(point_packet_list); } if(point_packet_list_temp.empty()) { printf("Point cloud packet is empty.\n"); break; } printf("Finish save %d frame to lvx file.\n", i); lvx_file_handler.SaveFrameToLvxFile(point_packet_list_temp); } lvx_file_handler.CloseLvxFile(); for (i = 0; i < kMaxLidarCount; ++i) { if (devices[i].device_state == kDeviceStateSampling) { /** Stop the sampling of Livox LiDAR. */ LidarStopSampling(devices[i].handle, OnStopSampleCallback, nullptr); } } /** Uninitialize Livox-SDK. */ Uninit(); } — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
This repo is archived. You cannot comment on issues.
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mmr/Livox-SDK#123