rosserial_arduino学习笔记11《红外测距仪》

1 硬件设置

要开始使用,请将红外测距仪连接到Arduino,如下所示。并将红外测距仪的信号引脚连接到模拟输入0

  • arduino_ir_ranger.jpg

2 软件设置

2.1 代码

接下来,打开您的Arduino IDE并复制下面的代码。

/* 
 * rosserial IR Ranger Example  
 * 
 * This example is calibrated for the Sharp GP2D120XJ00F.
 */

#include <ros.h>
#include <ros/time.h>
#include <sensor_msgs/Range.h>

ros::NodeHandle  nh;
sensor_msgs::Range range_msg;
ros::Publisher pub_range( "range_data", &range_msg);

const int analog_pin = 0;
unsigned long range_timer;

/*
 * getRange() - samples the analog input from the ranger
 * and converts it into meters.  
 * 
 * NOTE: This function is only applicable to the GP2D120XJ00F !!
 * Using this function with other Rangers will provide incorrect readings.
 */
float getRange(int pin_num){
    int sample;
    // Get data
    sample = analogRead(pin_num)/4;
    // if the ADC reading is too low, 
    //   then we are really far away from anything
    if(sample < 10)
        return 254;     // max range
    // Magic numbers to get cm
    sample= 1309/(sample-3);
    return (sample - 1)/100; //convert to meters
}

char frameid[] = "/ir_ranger";

void setup()
{
  nh.initNode();
  nh.advertise(pub_range);
  
  range_msg.radiation_type = sensor_msgs::Range::INFRARED;
  range_msg.header.frame_id =  frameid;
  range_msg.field_of_view = 0.01;
  range_msg.min_range = 0.03;  // For GP2D120XJ00F only. Adjust for other IR rangers
  range_msg.max_range = 0.4;   // For GP2D120XJ00F only. Adjust for other IR rangers
}

void loop()
{
  // publish the range value every 50 milliseconds
  //   since it takes that long for the sensor to stabilize
  if ( (millis()-range_timer) > 50){
    range_msg.range = getRange(analog_pin);
    range_msg.header.stamp = nh.now();
    pub_range.publish(&range_msg);
    range_timer =  millis();
  }
  nh.spinOnce();
}

2.2 程序解释

现在让我们分析代码。

#include <ros.h>
#include <ros/time.h>
#include <sensor_msgs/Range.h>

ros::NodeHandle  nh;
sensor_msgs::Range range_msg;
ros::Publisher pub_range( "range_data", &range_msg);

与往常一样,代码首先从rosserial库中包含适当的消息头文件和ros头文件,然后实例化发布者。

const int analog_pin = 0;
unsigned long range_timer;

/*
 * getRange() - samples the analog input from the ranger
 * and converts it into meters.  
 * 
 * NOTE: This function is only applicable to the GP2D120XJ00F !!
 * Using this function with other Rangers will provide incorrect readings.
 */
float getRange(int pin_num){
    int sample;
    // Get data
    sample = analogRead(pin_num)/4;
    // if the ADC reading is too low, 
    //   then we are really far away from anything
    if(sample < 10)
        return 254;     // max range
    // Magic numbers to get cm
    sample= 1309/(sample-3);

然后,我们定义了红外测距仪附加到的analog_pin,创建了一个时间变量,定义了一个将模拟信号转换为以米为单位的相应距离读数的函数。

return (sample - 1)/100; //convert to meters

这里,代码为传感器帧id字符串创建一个全局变量。重要的是这个字符串全局化,以便只要消息正在使用它就会存活。

char frameid[] = "/ir_ranger";

void setup()
{
  nh.initNode();
  nh.advertise(pub_range);
  
  range_msg.radiation_type = sensor_msgs::Range::INFRARED;
  range_msg.header.frame_id =  frameid;
  range_msg.field_of_view = 0.01;
  range_msg.min_range = 0.03;  // For GP2D120XJ00F only. Adjust for other IR rangers
  range_msg.max_range = 0.4;   // For GP2D120XJ00F only. Adjust for other IR rangers

在Arduino的设置函数中,代码初始化节点句柄,然后填写range_msg的描述符字段。这个特殊的IR Ranger读数在3厘米到40厘米之间。

注意:默认情况下,许多IR库以厘米为单位报告。

如果您使用不同的Ranger或IR助手库,则可能需要将其读数转换为米。

}

void loop()
{
  // publish the range value every 50 milliseconds
  //   since it takes that long for the sensor to stabilize
  if ( (millis()-range_timer) > 50){
    range_msg.range = getRange(analog_pin);
    range_msg.header.stamp = nh.now();
    pub_range.publish(&range_msg);
    range_timer =  millis();
  }

最后,在发布循环中,Arduino每隔50毫秒对游侠进行一次采样并发布范围数据。

3 启动应用程序

在对Arduino进行编程之后,可以使用rxplot对传感器测量进行可视化。

roscore
rosrun rosserial_python serial_node.py _port:= / dev / ttyUSB0
rqt_plot range_data / range

如果这是您第一次运行rqt_plot,则需要先安装软件包

猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/83549176
今日推荐