六维力数据中去除重力、漂移力任务---ros之talker、listener、ur、坑

本文介绍了一个使用ROS(Robot Operating System)进行六维力传感器数据读取及处理的应用案例。通过编写C++代码实现从ATI公司的力传感器获取数据,并利用正向运动学计算接触力,最终发布处理后的力矩信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

理论基础

见前面博文
六维力传感器参数辨识方法+matlab代码实现

talker

见前面博文
linux下读取ATI公司力传感器数据&&c++中调用c源文件&&移植到ros+问题解决
最终的talker

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

#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>("force0", 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++;
        // 发布消息
ROS_INFO("[%f]", msg.wrench.force.x);
        chatter_pub.publish(msg);

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

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

    return 0;
}

listener



#include <ros/ros.h>  
#include "std_msgs/String.h"
#include <sstream>
#include "geometry_msgs/WrenchStamped.h"
#include "sensor_msgs/JointState.h"
#include <cmath>
class SubscribeAndPublish  
{  
public:  
  SubscribeAndPublish()  
  {  
    pub_ = n_.advertise<geometry_msgs::WrenchStamped>("/force1", 1000);  
    sub_ = n_.subscribe("force0", 1000, &SubscribeAndPublish::callback1, this);  
    sub2_ = n_.subscribe("joint_states", 1000, &SubscribeAndPublish::callback2, this);  
  }  
//由正向运动学得到变换矩阵的最后一行元素,用于计算实际的接触力
float *qianxiang(const sensor_msgs::JointState::ConstPtr& a)
{
  a1 = a->position[0];
  a2 = a->position[1];
  a3 = a->position[2];
  a4 = a->position[3];
  a5 = a->position[4];
  a6 = a->position[5];
  

  b[0] = -0.5;
  b[1] = 0.707;
  b[2] = -0.5;
  return b;
}
  void callback1(const geometry_msgs::WrenchStamped::ConstPtr& msg1)  
  {  
    force.wrench.force.x = msg1->wrench.force.x/1000000+g*x*qq[0]+g*y*qq[1]-fx;
    force.wrench.force.y = msg1->wrench.force.y/1000000-g*y*qq[0]+g*x*qq[1]-fy;
    force.wrench.force.z = msg1->wrench.force.z/1000000+g*qq[2]-fz;
    force.wrench.torque.x = msg1->wrench.torque.x/1000000+g*y*pz*qq[0]-g*x*pz*qq[1]+g*py*qq[2]-tx;
    force.wrench.torque.y = msg1->wrench.torque.y/1000000+g*x*pz*qq[0]+g*y*pz*qq[1]-g*px*qq[2]-ty;
    force.wrench.torque.z = msg1->wrench.torque.z/1000000-g*x*py*qq[0]-g*y*py*qq[1]-g*y*px*qq[0]+g*x*px*qq[1]-tz;
    pub_.publish(force);
    ros::Rate loop_rate(10);
    loop_rate.sleep();
  }  
  
  void callback2(const sensor_msgs::JointState::ConstPtr& msg2)
  {
  qq[0] = qianxiang(msg2)[0];
  qq[1] = qianxiang(msg2)[1];
  qq[2] = qianxiang(msg2)[2];
for(int i=0;i<3;i++)
      ROS_INFO("[%f]", qq[i]);
  }
private: 
  float a1;
  float a2;
  float a3;
  float a4;
  float a5;
  float a6;
  float g = 2.96;
  float fx = 1.82;
  float fy = -15.41;
  float fz = -14.18;
  float tx = 0.071;
  float ty = 0.349;
  float tz = 0.000139;
  float x = 0.34176;
  float y = -0.24539;
  float px = -0.001740;
  float py = 0.00145;
  float pz = 0.02223;
  float qq[3];
  float b[3];
  ros::NodeHandle n_;   
  ros::Publisher pub_;  
  ros::Subscriber sub_;
  ros::Subscriber sub2_; 
  geometry_msgs::WrenchStamped force;
  sensor_msgs::JointState joint;

};//End of class SubscribeAndPublish  

int main(int argc, char **argv)  
{  
  //Initiate ROS  
  ros::init(argc, argv, "subscribe_and_publish");  

  //Create an object of class SubscribeAndPublish that will take care of everything  
  SubscribeAndPublish test;  
  //ros::spin();
  ros::MultiThreadedSpinner s(2);  //多线程
  ros::spin(s);  

  return 0;  
}  

这里面坑无数:
1、cmath不需要在cmakelists中添加;
2、boost可以不添加;
3、joint_states类型消息必须要先resize大小,才能用!!!,且消息不能用在函数的返回值中;

ur

好久不用ur,也有不少问题,其中经常性会连接不上,sock傻傻啥的。
1、可能本身电脑网段不对;
2、需要添加reserve_port:=30004,端口号可能不对,这个也是一个点
3、可以在common.launch文件中单独param参数,就不用再输入了。

还有个问题,就是需要将ur和传感器网络放在同一网段下,ur机械臂设置ip的方式:
点击文件,然后退出,就可以设置ur ip地址。

现在的一坑是matlab中计算的正向运动学的R3i,即变换矩阵第三行的元素与论文还中的不一样。

May the force be with you!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值