笔者最近在用ROS编写一款传感器的驱动包,无奈这方面的教程实在太少了,网上的ROS教学基本都是已经写好了的,直接拿来用,但是对于怎么获取数据实在不知所措。于是笔者在自己弄完一个驱动包后和大家分享,希望能帮到大家。        

第一步:首先按照下面的博客安装libmodbus的工具

Linux编译安装libmodbus库_linux modbus库_一只嵌入式爱好者的博客-CSDN博客Linux编译安装libmodbus库下载libmodbus库源码安装配置编译使用下载libmodbus库源码git clone git://github.com/stephane/libmodbus若报错如下fatal: Unable to look up github.com (port 9418) (未知的名称或服务)使用如下命令清理缓存npm cache clean --force清理完缓存就可以下载了,新建一个文件夹modbus并下载安装下载好后会出现一个libmodhttps://blog.csdn.net/weixin_45905650/article/details/122387556

注意其中的动态库文件和几个头文件,后面会用到

 

         

        第二步:按照自己的传感器和modbus协议编写代码,这部分可以参考网上其他教程,笔者参考的是 

Modbus驱动库—libmodbus驱动库的使用_whik1194的博客-CSDN博客文章目录为什么要使用驱动库?libmodbus简介libmodbus常用函数Windows平台libmodbus 使用1.获取源代码2.生成config.h配置文件3.编写测试代码4.编译测试代码Linux平台下libmodbus使用ARM平台下libmodbus使用libmodbus 从机地址限制的问题这篇文章是接上一篇Modbus协议简介,介绍Modbus实际项目应用,断断续续写了近两周时间。为什么要使用驱动库?上一篇文章,我们介绍了Modbus协议物理层和协议层,我们知道了Modbus是一种总线https://blog.csdn.net/whik1194/article/details/119010616

这里笔者分享自己测试的一款自己的代码

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "modbus.h"
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <time.h> 
	
modbus_t *mb=NULL;
#define addr_phy 0x01C2
#define addr_num 0x0002

uint16_t mbbuf[2];
std::string connection_port = "";
int main(int argc, char **argv)
{
	ros::init(argc,argv,"pulldata_node");
	ROS_INFO("scaning available port");
	bool is_connected = false;
	if(mb=modbus_new_rtu("/dev/ttyUSB0",115200,'N',8,1)) //声明modbus的句柄
	{
		if(modbus_set_slave(mb,1)==-1)//设置从机位置为1
           {
			ROS_ERROR_STREAM("set slave failed");
              modbus_free(mb);
           }
           if(modbus_connect(mb)==-1)
			{
				ROS_ERROR_STREAM("connect failed");
              modbus_free(mb);
			}
           //modbus_set_response_timeout(mb,0,200000);//设置超时时间
           //int m_en = modbus_write_register(mb,0,1);//modbus使能
		//不过好像这一步在另外的版本中没有“使能”用到
           	if(modbus_read_registers(mb,addr_phy,addr_num,mbbuf)!=(-1))//读取该地址中的数据。
            {
				ROS_INFO("read register success");
               connection_port = "/dev/ttyUSB0";
               is_connected = true;    
            }
			else 
			ROS_ERROR_STREAM("read register failed");
       
	}
	if(!is_connected) 
	{
        ROS_ERROR_STREAM("control borad connection failed");
        return -1;
    }
	ROS_INFO_STREAM("available prot: " << connection_port);
	//ros::Rate loop_rate(0.2);
	//ros::NodeHandle nh;
	//ros::Publisher car_data_pub = nh.advertise<my_msgs::car_data>("car_data", 10);
    //ros::Subscriber car_control_sub=nh.subscribe("car_cmd",10,twistCallback);
	
	
	while (ros::ok()) 
		{
        	//memset(mbbuf,0,10*2);//置零
        	if(modbus_read_registers(mb,addr_phy,addr_num,mbbuf)!=(-1))
        		{
		   	//loop_rate.sleep();
			ROS_INFO("The data is : %x %x", mbbuf[0],mbbuf[1]);
		   	//translate_mb_data();//数据传输
		   	//car_data_pub.publish(my_data);//发布节点
        		}
        
        	//ros::spinOnce();
    	}
    	modbus_close(mb);
    	modbus_free(mb);
    	return 0;
//此函数在主函数(main)中一直循环

}

        第三步:可以参考B站上的ROS机器人工匠阿杰的方法,修改CMakelists,当然还有更重要的编译指令。

然后接下来的步骤非常重要,笔者也是花了很大力气才调通的。

①把第一步下的几个头文件.h放入到自己写的传感器的包package的include下

 ②在和include的同级目录下创建一个lib文件夹,把第一步写的几个动态库文件.so拷贝进去

 ③在按照上述说的将CMakelists修改后,继续添加两句

(1)参考这篇文章

CMakeLists.txt模板+常用库头文件添加和库文件链接+调用头文件_YMWM_的博客-CSDN博客CMakeLists.txt模板#声明要求的cmake最低版本cmake_minimum_required(VERSION 3.10)#设置c++版本set(CMAKE_CXX_STANDARD 11)#声明一个cmake工程project("Hello world")#添加头文件include_directories("库头文件名")find_package(库名 REQUIRED)#find_package命令是cmake提供的寻找某个库的头文件与库文件的指令。如果cmake能够找到https://blog.csdn.net/YMWM_/article/details/109022872?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168197524116800186592815%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168197524116800186592815&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-109022872-null-null.142%5Ev85%5Econtrol,239%5Ev2%5Einsert_chatgpt&utm_term=cmakelists.txt%20%E6%B7%BB%E5%8A%A0%E5%A4%B4%E6%96%87%E4%BB%B6&spm=1018.2226.3001.4187

在这里的下一行添加一句,这句的作用是将头文件的路径包含进来

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
include_directories("/home/book/catkin_ws/src/pulldata_pkg/include/pulldata_pkg")

(2)这里笔者参考的是这篇博客

ROS编译 调用第三方动态库(xxx.so)_ros使用第三方库_Will_Ye的博客-CSDN博客在做项目过程中,不可避免,有时需要使用一些第三方的开源库,或者自己写的动态库,然后就需要CMakeLists中添加这些动态库对应的路径,进行编译。需要调用的动态库后缀一般为,有时也会遇到除了,还有和这些,如,还有和在后缀后的这些数字,其实代表的是不同版本,用来做版本管理的,所以整个动态库的文件名是有讲究的。比如,lib是固定代表共享库,zzz是共享库名称,.so是固定后缀,1表示的是主版本号,2表示次版本号,3表示发行版本号。而且这个名字最长的,是实际的库文件,含有的是可执行的二进制代码。所以就可以用指令https://blog.csdn.net/Will_Ye/article/details/125629587?spm=1001.2014.3001.5506

 于是在target_link_libraries处的末尾添加动态库文件,具体结果如下,这句的作用是将库文件加进来

target_link_libraries(pulldata_node
  ${catkin_LIBRARIES} libmodbus.so
 )

第四步:以上弄完之后,编译。

运行roscore,rosrun xxx,但是笔者运行自建的节点时又报错了,说找不到可执行的文件什么的。后来又找了一个小时左右,得到如下结论:

可执行的文件放在下图这样一个devel_isolated的后续目录下,可能有的小伙伴是devel文件夹,具体看各自报错调试。

然后,把这个文件拷贝到机器人工作空间,笔者按照报错也是逐步找到的

 再编译及后续

重新编译,再重复替换可执行文件到上图的目录下,这样子笔者的传感器就能用modbus+ROS读出来了。

 

 

当然这只是个简单的测试程序,笔者并没有添加节点发布和订阅的功能。为大家在ROS下编写自己的驱动包贡献一份力。

GitHub 加速计划 / li / libmodbus
3.36 K
1.72 K
下载
libmodbus: libmodbus 是一个自由软件库,用于使用 Modbus 协议发送和接收数据,支持串行端口或以太网连接。
最近提交(Master分支:2 个月前 )
5c14f139 - 8 个月前
3f9f17e2 - 9 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐