0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在ROS中调用.so文件

福州市凌睿智捷电子有限公司 2024-06-30 08:23 次阅读

设备

笔者有一个需求,需要结合ROS模拟量采集。有一种解决方法是ADC芯片+STM32主控,通过串口的方式与上位机通信,但串口通信速度很慢,达不到要求遂放弃。也考虑过使用NI的数据采集卡,貌似NI没有给ubuntu作配套,也放弃了。在淘宝上找到一款凌智电子的DAQ,价格便宜,也能满足使用需求,故做记录。

系统环境 ubuntu20.04 + ROS noetic

硬件设备 i5-12500+凌智电子DAQ122

驱动下载

驱动要到gitee下载,支持ubuntu x86_64的驱动要注意分支TestZKFT。

git clone --branch=TestZKFT https://gitee.com/Lockzhiner-Electronics/DAQ122-IPC.git

下在之后可以尝试运行 几个demo,都是用Qt写的,也可以拷贝Linux/libdaq的目录单独开发。最关键的是 liblibdaq-2.0.0.so这个文件,下面以ROS为例子怎么调用.so文件。

结合cmake的使用

新建工作空间,功能包等流程不再赘述,网上已经有很多教程了。着重讲cmakelist的配置。

沿用官方demo中QT的使用,因此

find_package(
Qt5 REQUIRED COMPONENTS Core Widgets
)

除此之外,还要包含头文件目录,除了包含官方libdaq的路径以外,还要包含QT安装的路径

include_directories(
include/daq_122 #自己写了一个.h文件
${catkin_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/include/daq_122
${CMAKE_CURRENT_SOURCE_DIR}/include/daq_122/include
${CMAKE_CURRENT_SOURCE_DIR}/include/daq_122/third_party/include

${catkin_INCLUDE_DIRS}
${Qt5Core_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
)

链接官方的.so库文件

link_directories(
lib/x86_64 # 相对路径,指定动态链接库的访问路径
${catkin_LIB_DIRS}
)

再就是ROS 编译C++的cmake写法了。虽然so文件叫liblibdaq-2.0.0,但cmake中需要去掉一个lib才能执行下去。

add_library(${PROJECT_NAME}
src/daq_read.cpp
)
add_executable(daq_read src/daq_read.cpp)
add_dependencies(daq_read ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(daq_read
${catkin_LIBRARIES}
libdaq-2.0.0 #这里额外注意,编译时候cmake会自动加个前缀lib
Qt5::Core
Qt5::Widgets
)

至此,完成了cmakelist的写法。

此外还有package.xml文件,需要引用如下

catkin
roscpp
rospy
std_msgs
qtbase5-dev
geometry_msgs
roscpp
rospy
std_msgs
geometry_msgs
roscpp
rospy
std_msgs
qtbase5-dev
geometry_msgs

其中geometry_msgs是笔者实现自己功能用的一个包,可以不用,其他的包都是必须的。

ROS的写法

现在要写一个.h文件,定义一些变量。之前cmake已经有了对QT的引用,因此直接用QT函数就行。

# ifndef DAQ_READ_H
# define DAQ_READ_H
#include
#include
#include
#include
#include
using namespace libdaq::device;
DAQ122 daq_device;
uint8_t adc_channel_state_ = 0b11111111;
uint8_t legal_channel_size = 8;
uint32_t storage_depth = 1;
QVector> receive_data(8);
geometry_msgs::Vector3 laser_distance;
# endif

各个变量的作用,参考官方的示例即可。

接下来是C++文件,运行程序要求有sudo 权限。笔者这里用前三个姿态,以5K频率读,再以5K频率发送,设置如下

#include
#include
#include "data_read.h"

/*
运行这个程序要求sudo权限
sudo su
然后输入你的用户名+密码

包含两部分 ros+daq读取
*/

void DAQcallback()
{
auto read_result = true;
for (int i = 0; i < 3; i++) {
// 判断当前通道是否打开,没有打开则跳过
if((adc_channel_state_ & (0b00000001) << i) == 0){
continue;
}
// 读取数据
read_result = daq_device.TryReadADCData(i, receive_data[i].data(), receive_data[i].size(), 1000);
if(!read_result){

}
}
QVector x_data(storage_depth);
for (int var = 0; var < storage_depth; ++var) {
x_data[var] = 1000.0 / storage_depth * var;
}
// read_result = daq_device.TryReadADCData(1,receive_data.data(),10,10);
// 只配置了三个通道
auto current_buffer_size = daq_device.GetADCBufferDataSize(0);
qDebug() << receive_data[1];
// 停止读取
// daq_device.StopADCCollection();
// receive_data[0].clear();
// receive_data[1].clear();
// receive_data[2].clear();
laser_distance.x = receive_data[0].at(0);
laser_distance.y = receive_data[1].at(0);
laser_distance.z = receive_data[2].at(0);

}

int main(int argc, char *argv[])
{
// 初始化DAQ122
if (!daq_device.InitializeDevice())
{
std::cout << "InitializeDevice Error";
}
if(!daq_device.ConnectedDevice())
{
std::cout << "ConnectedDevice Error";
}

// 采样范围5V
auto voltage_range = DAQVoltage::Voltage5V;
// 采样频率定义为1KHz
auto sample_rate = DAQADCSampleRate::SampleRate5K;
if (!daq_device.ConfigureADCParameters(sample_rate, voltage_range))
{
std::cout << "Configure Error";
}
// 配置前三个通道为输入
adc_channel_state_ = DAQADCChannel::AIN1 | DAQADCChannel::AIN2 | DAQADCChannel::AIN3;
daq_device.ConfigADCChannel(adc_channel_state_);

// 开始采集数据
daq_device.StartADCCollection();

// 定义存储数组
for (int var = 0; var < receive_data.size(); ++var) {
receive_data[var].resize(storage_depth);
}

// ros初始化
ros::init(argc,argv,"daq_pub_node");
ros::NodeHandle nh;
// 1ms 执行一次
ros::Publisher daq_pub = nh.advertise("daq_pub",10);

ros::Duration(1).sleep();
// 判断当前数据是否已经满足读取的条件
if(!daq_device.ADCDataIsReady(storage_depth)){
std::cout << "not enough" << std::endl;
}

auto read_result = true;
for (int i = 0; i < legal_channel_size; i++) {
// 判断当前通道是否打开,没有打开则跳过
if((adc_channel_state_ & (0b00000001) << i) == 0){
continue;
}

// 读取数据
read_result = daq_device.TryReadADCData(i, receive_data[i].data(), receive_data[i].size(), 1000);
if(!read_result){
// qDebug() << "Error";
}
}

QVector x_data(storage_depth);
for (int var = 0; var < storage_depth; ++var) {
x_data[var] = 1000.0 / storage_depth * var;
}
ros::Rate daq_rate(5000);
while (ros::ok())
{
DAQcallback();
daq_pub.publish(laser_distance);

daq_rate.sleep();
}
// ros::spin();
return 0;
}

编译,运行即可将数据发送到rostopic中。

采集正弦信号

f213d158-3676-11ef-a655-92fbcf53809c.jpg

采集方波信号

f22c81e4-3676-11ef-a655-92fbcf53809c.jpg

采集三角波信号

f2431724-3676-11ef-a655-92fbcf53809c.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 串口通信
    +关注

    关注

    34

    文章

    1601

    浏览量

    55199
  • ROS
    ROS
    +关注

    关注

    1

    文章

    276

    浏览量

    16870
  • 模拟量采集
    +关注

    关注

    0

    文章

    23

    浏览量

    2926
收藏 人收藏

    评论

    相关推荐

    何在ROS的基础上提升无人驾驶系统的可靠性

    本文着重介绍基于机器人操作系统ROS的无人驾驶系统。文中将介绍ROS以及它在无人驾驶场景的优缺点,并讨论如何在ROS的基础上提升无人驾驶系
    的头像 发表于 02-15 10:26 3585次阅读
    如<b class='flag-5'>何在</b><b class='flag-5'>ROS</b>的基础上提升无人驾驶系统的可靠性

    何在ROS调用.so文件

    。 采集正弦信号 采集方波信号 采集三角波信号 原文链接:如何在ROS调用.so
    发表于 07-02 14:44

    何在两个文件间进行函数的调用

    何在两个文件间进行函数的调用
    发表于 01-16 16:28

    何在VEE 8.5调用viopen和viclose

    Vee 8.5调用viopen和viclose函数。非常感谢。最好的问候亚历克斯 以上来自于谷歌翻译 以下为原文dear all, I want to close an instrument( can
    发表于 07-30 14:21

    在Android中使用ROS

    /buildscript.gradle"}然后在文件添加subprojects { apply plugin: 'ros-android' afterEvaluate { project ->android
    发表于 05-16 19:16

    如何移植ROS程序到Android

    在Android上运行ROS程序一般使用rosjava-android。但是也可以直接利用NDK编译成so文件移植到Android上。当然移植过程也并不简单。 下面是一个简单的例子。安装cmake
    发表于 05-16 19:20

    ROS何在代码层面去接收stm32发送过来的数据?

    如何实现ROS与stm32之间的通信?ROS对stm32发送过来的数据做了哪些处理?ROS主控主要实现的功能有哪些?ROS何在代码层面去接
    发表于 10-12 08:17

    何在ROS2运行小乌龟呢

    ROS2运行小乌龟,其实主要就是安装两个工具,turtlesim和rqt。A: 安装turtlesim。输入【sudo apt update】输入【sudo apt install
    发表于 11-05 06:08

    怎样去使用ROS的launch启动文件

    怎样去使用ROS的launch启动文件呢?ROS的launch启动文件该怎样去使用呢?
    发表于 02-14 07:23

    何在ROS上使用serial包进行串口通信

    作者:良知犹存转载授权以及围观:欢迎添加微信公众号:羽林君前言主题:串口是一种设备间常用的通讯接口,rosserial将串口字符数据转发到标准ROS网络,并输出到rosout和其日志文件。本文将记录
    发表于 02-21 07:27

    何在普通的鸿蒙工程中使用编译好的SO文件

    。二、SO库的使用本篇主要介绍如何在普通的鸿蒙工程中使用编译好的SO文件。首先,新建一个普通的鸿蒙项目工程,我的工程名叫SOTest。项目工程建好后,就将
    发表于 03-25 10:06

    何在启动文件调用定义为uint32_t getValue(void)的C函数呢?

    我如何在启动文件调用定义为 uint32_t getValue(void) 的 C 函数(在 Reset_Handler 例程)?需要什
    发表于 12-09 07:27

    JNI java调用so动态库方法

    JNI Java调用so包相关问题总结,出现了很多问题,按照操作应该不会发生不到so包的错误,其实最后出现的也是说加载不到libpython2.7.x.so.1,我就纳闷了,怎么和py
    发表于 11-28 13:13 3446次阅读

    Android下的DEX文件SO文件梳理总结

    android逆向分析、脱壳破解分析过程免不了和android的各种文件格式打交道(so、dex、xml、art、oat等等)。
    的头像 发表于 11-04 09:32 6514次阅读

    何在ROS检查保存log的文件夹有多大

    _comm-noetic-develtoolsroslaunchsrcroslaunch_ init _.py文件的main函数里,有以下语句。 看名字就知道是干啥的了。 rlutil .check_log_disk_usage () 再打开同一路径下的rlutil.p
    的头像 发表于 09-14 18:07 1493次阅读
    如<b class='flag-5'>何在</b><b class='flag-5'>ROS</b><b class='flag-5'>中</b>检查保存log的<b class='flag-5'>文件</b>夹有多大