锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

linux下读取ATI公司力传感器数据&&c++中调用c源文件&&移植到ros+问题解决

时间:2023-02-25 00:00:00 y力传感器

linux下读取ATI公司传感器数据&&c 中调c源文件&&移植到ros 问题解决

    • 源文件
    • 在cppc文件被调用到文件中
    • ros中实现
    • 存在的问题
      • 还愿

源文件

关于源代码makefile学习文件的编写。

netft: netft.o  gcc netft.o -o netft  netft.o: netft.c  gcc -c netft.c -o netft.o clean:  rm *.o netft 

书写格式一般为:
首先写下最终生成的可执行文件。
2、gcc netft.o -o netft 的效果与 gcc -o netft netft.o一样。
3.冒号前面是需要生成的文件;冒号后面需要空间;冒号后面的文件是需要的文件。
4、-c是编译,-o链接成可执行文件。
5、clean可通过执行make clean实现。

在cppc文件被调用到文件中

因为源代码是用C语言编写的,ros中常用的是c 因此,首先试着单独写文件cppc文件被调用到文件中。
既然是要在cpp在文件中调用c文件,首先要在原始c文件中调用c文件main函数改为普通函数,然后添加返回值。在这里返回指针型。
然后在c和c 需要之间调用
在.h文件中

#include  #ifndef _NETFT_H_ #define _NETFT_H_ #ifdef __cplusplus extern "C" { 
         #endif int *a(int argc,char **argv); #ifdef __cplusplus } #endif #endif  

在.c将头文件导入文件
在.cpp文件中

#include  #ifdef __cplusplus extern "C" { 
         #endif #include "netft.h" #ifdef __cplusplus } #endif int main(int argc, char **argv) { 
         while(1) printf("%d\n",a(argc,argv)[1]);
}

完成了程序设计,接下来需要进行编译和链接等。
首先需要生成c源文件的库文件

gcc -c netft.c -o netft.o

这里会报错netft.c:10:19: fatal error: netft.h: 没有那个文件或目录
这里一种可行的办法是,将**.h文件移动到/usr/include**然后再执行就可。
生成库文件以后,就要进行链接生成可执行文件

g++ diaoyong.cpp netft

完成!

ros中实现

首先需要选择合适的消息结构,以及正确的赋值方法:(ps:当然也需要加上上面的技巧)

/** * 该例程将发布chatter话题,消息类型String */
 
#include 
#include "ros/ros.h"
#include "geometry_msgs/WrenchStamped.h"
#include 

#ifdef __cplusplus
extern "C"
{ 
        
#endif
#include "netft.h"
#ifdef __cplusplus
}
#endif
int main(int argc, char **argv)
{ 
        
    // ROS节点初始化
    ros::init(argc, argv, "talker");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
    ros::Publisher chatter_pub = n.advertise<geometry_msgs::WrenchStamped>("chatter", 1000);

    // 设置循环的频率
    ros::Rate loop_rate(100);

    int nn = 0;

    int count = 0;
    while (ros::ok())
    { 
        
        // 初始化std_msgs::String类型的消息
        geometry_msgs::WrenchStamped msg;
        msg.wrench.force.x = a(argc,argv)[0];
        msg.wrench.force.y = a(argc,argv)[1];
        msg.wrench.force.z = a(argc,argv)[2];
        msg.wrench.torque.x = a(argc,argv)[3];
        msg.wrench.torque.y = a(argc,argv)[4];
        msg.wrench.torque.z = a(argc,argv)[5];
        nn++;
printf("%d\n",nn);
        // 发布消息

        chatter_pub.publish(msg);

        // 循环等待回调函数
        ros::spinOnce();

        // 按照循环频率延时
        loop_rate.sleep();
        ++count;
    }

    return 0;
}

然后将c源文件、头文件与cpp文件放在统一功能包的src文件夹下。最后就是cmakelist文件。就比较神奇,在这里我们不需要进行链接操作,除了添加消息结构的库以外,只需要在这里加上这句就可以:

add_executable(talker src/talker.cpp src/netft.c)

存在的问题

比较狗的问题是:好像这个程序本身也只能读取一段数据,然后好象就断了连接。在单独测试效果就是这样,在ros中会报错:Couldn’t find an AF_INET address for [localhost]
试了网上的方法都不可。
希望以后可以填坑,也希望大佬多多指教!

May the force be with you!


还愿

emmmmmm忽然就那么解决了。
想想解决问题的步骤:首先测试了单独程序,想在源代码中实现while,所以就需要想这个while应该加在什么地方,最终想到了不能重复初始化这个问题,因此在源代码中加上初始化部分只进一次的标志,并将定义移到函数外,解决!!!

/* Simple demo showing how to communicate with Net F/T using C language. */
//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "netft.h"
#define PORT 49152 /* Port the Net F/T always uses */
#define COMMAND 2 /* Command code 2 starts streaming */
#define NUM_SAMPLES 1 /* Will send 1 sample before stopping */

/* Typedefs used so integer sizes are more explicit */
typedef unsigned int uint32;
typedef int int32;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned char byte;
typedef struct response_struct { 
        
	uint32 rdt_sequence;
	uint32 ft_sequence;
	uint32 status;
	int32 FTData[6];
} RESPONSE;
int pp[6];
	int socketHandle;			/* Handle to UDP socket used to communicate with Net F/T. */
	struct sockaddr_in addr;	/* Address of Net F/T. */
	struct hostent *he;			/* Host entry for Net F/T. */
	byte request[8];			/* The request data sent to the Net F/T. */
	RESPONSE resp;				/* The structured response received from the Net F/T. */
	byte response[36];			/* The raw response data received from the Net F/T. */
	int i;						/* Generic loop/array index. */
	int err;					/* Error status of operations. */
	char * AXES[] = { 
         "Fx", "Fy", "Fz", "Tx", "Ty", "Tz" };	/* The names of the force and torque axes. */
int m = 0;
int *a( int argc, char ** argv ) { 
        
if(m==0)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这里
{ 
        


	if ( 2 > argc )
	{ 
        
		fprintf( stderr, "Usage: %s IPADDRESS\n", argv[0] );
		return -1;
	}

	/* Calculate number of samples, command code, and open socket here. */
	socketHandle = socket(AF_INET, SOCK_DGRAM, 0);
	if (socketHandle == -1) { 
        
		exit(1);
	}
		}
m = 1;
	*(uint16*)&request[0] = htons(0x1234); /* standard header. */
	*(uint16*)&request[2] = htons(COMMAND); /* per table 9.1 in Net F/T user manual. */
	*(uint32*)&request[4] = htonl(NUM_SAMPLES); /* see section 9.1 in Net F/T user manual. */
	
	/* Sending the request. */
	he = gethostbyname(argv[1]);
	memcpy(&addr.sin_addr, he->h_addr_list[0], he->h_length);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	
	err = connect( socketHandle, (struct sockaddr *)&addr, sizeof(addr) );

	send( socketHandle, request, 8, 0 );

	/* Receiving the response. */
	recv( socketHandle, response, 36, 0 );
	resp.rdt_sequence = ntohl(*(uint32*)&response[0]);
	resp.ft_sequence = ntohl(*(uint32*)&response[4]);
	resp.status = ntohl(*(uint32*)&response[8]);
	for( i = 0; i < 6; i++ ) { 
        
		resp.FTData[i] = ntohl(*(int32*)&response[12 + i * 4]);
	}

	/* Output the response data. */
	for (i =0;i < 6;i++) { 
        
		pp[i] = resp.FTData[i];
	}

	
	return pp;
}

//int main(int argc, char ** argv )
//{ 
        
//int e =1;
//while(e--)
// for (int i =0;i < 6;i++) { 
        
// printf("%d\n",a(argc,argv)[i]);
// }

//return 0;
//}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章