ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ROS开发(3)ROS串口解析GPS数据

2022-07-19 19:05:04  阅读:163  来源: 互联网

标签:std ROS catkin include add 串口 cpp GPS gps


 

 

ROS开发(2)ROS创建自定义消息-普通消息

https://www.cnblogs.com/gooutlook/p/16493595.html

 

1创建环境工程 

1创建catkin_gps/src工程文件环境

 

 

 在catkin_gps路径下编译

catkin_make

  

 

 

 自动生成

 

 

 

 2 创建项目工程

环境工程catkin_gps/src下创建工程v1_GetGPS

 

 

 在v1_GetGPS下创建文件.

 

2-1创建消息文件

在项目包里面创建msg文件夹

 

 

 

 

 

 

 

bool bool_msg
float64 lat
float64 lon
float64 high
string string_msg
time time_msg

  

2-2 创建编辑package.xml 

 

 

 包含文件依赖

1 自定义消息

2 串口

<?xml version="1.0"?>
<package format="2">
  <name>v1_GetGPS</name>
  <version>0.0.0</version>
  <description>The v1_GetGPS package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="dongdong@todo.todo">dongdong</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  
  <build_depend>message_generation</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>serial</build_depend>
  <build_depend>std_msgs</build_depend>

  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>serial</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>

  <exec_depend>message_runtime</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>serial</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

  

修改

1项目名字v1_GetGPS和文件夹一样

 

 

 

2-3创建编辑CMakeLists.txt

 

 

 

cmake_minimum_required(VERSION 3.0.2)
project(v1_GetGPS)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)


find_package(catkin REQUIRED COMPONENTS
  message_generation
  message_runtime
  roscpp
  rospy
  std_msgs
  serial #串口引用
)

add_message_files(
  FILES
  topic_msg.msg#消息引用-添加我们自己定义的xxx.msg文件
)

generate_messages(
  DEPENDENCIES
  std_msgs#消息引用-自带
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES my_topic002
#  CATKIN_DEPENDS message_generation message_runtime roscpp rospy std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########


include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

add_executable(publisher_gps src/publisher_gps.cpp)
target_link_libraries(publisher_gps ${catkin_LIBRARIES})
add_dependencies(publisher_gps ${PROJECT_NAME}_generate_messages_cpp) 

add_executable(subscriber_gps src/subscriber_gps.cpp)
target_link_libraries(subscriber_gps ${catkin_LIBRARIES})
add_dependencies(subscriber_gps ${PROJECT_NAME}_generate_messages_cpp) 


add_executable(serialPort src/serialPort.cpp)
target_link_libraries(serialPort ${catkin_LIBRARIES})
add_dependencies(serialPort ${PROJECT_NAME}_generate_messages_cpp) 

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp) 

 1修改项目名字和文件夹一样

 

 

 2 修改自定义的消息

 

 

 

 

 

3项目功能 

 

 

3-1发布器

v1_GetGPS/src下创建serialPort.cpp

 

 

 

#include <string>
#include <vector>
#include <sstream>
#include <cmath>
#include <cstdlib>//string转化为double
#include <iomanip>//保留有效小数

#include <ros/ros.h> 
#include <serial/serial.h>  //ROS已经内置了的串口包 


//0 导入消息 工程名字/消息名字
#include "v1_GetGPS/topic_msg.h"
#include "std_msgs/String.h"
#include <std_msgs/Empty.h> 

serial::Serial ser; //声明串口对象

//解析GPS
void RecePro(std::string s , double& lat , double& lon )
{
    //分割有效数据,存入vector中
    std::vector<std::string> v;
    std::string::size_type pos1, pos2;
    pos2 = s.find(",");
    pos1 = 0;
    while ( std::string::npos !=pos2 )
    {
        v.push_back( s.substr( pos1, pos2-pos1 ) );
        pos1 = pos2 + 1;
        pos2 = s.find(",",pos1);
    }
    if ( pos1 != s.length() )
        v.push_back( s.substr( pos1 ));
    //解析出经纬度
    if (v.max_size() >= 6 && (v[6] == "1" || v[6] == "2" || v[6] == "3" || v[6] == "4" || v[6] == "5" || v[6] == "6" || v[6] == "8" || v[6] == "9"))
    {
        //纬度
        if (v[2] != "") lat = std::atof(v[2].c_str()) / 100;
        int ilat = (int)floor(lat) % 100;
        lat = ilat + (lat - ilat) * 100 / 60;
        //经度
        if (v[4] != "") lon = std::atof(v[4].c_str()) / 100;
        int ilon = (int)floor(lon) % 1000;
        lon = ilon + (lon - ilon) * 100 / 60;

    }
}
int main(int argc, char** argv)
{
    //初始化节点
    ros::init(argc, argv, "serial_node");
    //声明节点句柄
    ros::NodeHandle nh;
    //注册Publisher到话题GPS
    ros::Publisher GPS_pub = nh.advertise<v1_GetGPS::topic_msg>("GPS",1000);
    try
    {
      //串口设置
      ser.setPort("/dev/ttyUSB0");
      ser.setBaudrate(115200);
      serial::Timeout to = serial::Timeout::simpleTimeout(5000);
      ser.setTimeout(to);
      ser.open();
    }
    catch (serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open Serial Port !");
        return -1;
    }
    if (ser.isOpen())
    {
        ROS_INFO_STREAM("Serial Port initialized");
    }
    else
    {
        return -1;
    }

    ros::Rate loop_rate(50);

    std::string strRece;
    while (ros::ok())
    {

        if (ser.available())
        {
            //1.读取串口信息:
            ROS_INFO_STREAM("Reading from serial port\n");
            //通过ROS串口对象读取串口信息
            //std::cout << ser.available();
            //std::cout << ser.read(ser.available());
            strRece += ser.read(ser.available());
            //std::cout <<"strRece:" << strRece << "\n" ;
            //strRece = "$GNGGA,122020.70,3908.17943107,N,11715.45190423,E,1,17,1.5,19.497,M,-8.620,M,,*54\r\n";
            //2.截取数据、解析数据:
            //GPS起始标志
            std::string gstart = "$GN";
            //GPS终止标志
            std::string gend = "\r\n";
            int i = 0, start = -1, end = -1;
            while ( i < strRece.length() )
            {
                //找起始标志

                start = strRece.find(gstart);
                //如果没找到,丢弃这部分数据,但要留下最后2位,避免遗漏掉起始标志
                if ( start == -1)
                {
                    if (strRece.length() > 2)   
                        strRece = strRece.substr(strRece.length()-3);
                        break;

                }
                //如果找到了起始标志,开始找终止标志
                else
                {
                    //找终止标志
                    end = strRece.find(gend);
                    //如果没找到,把起始标志开始的数据留下,前面的数据丢弃,然后跳出循环
                    if (end == -1)
                    {
                        if (end != 0)
                        strRece = strRece.substr(start);
                        break;
                    }
                    //如果找到了终止标志,把这段有效的数据剪切给解析的函数,剩下的继续开始寻找
                    else
                    {
                        i = end;

                        //把有效的数据给解析的函数以获取经纬度
                        double lat, lon;
                        RecePro(strRece.substr(start,end+2-start),lat,lon);
                        std::cout << std::setiosflags(std::ios::fixed)<<std::setprecision(7)<< "纬度:" << lat << " 经度:"<< lon << "\n";
                        //发布消息到话题
                        v1_GetGPS::topic_msg GPS_data;
                        GPS_data.lat = lat;
                        GPS_data.lon = lon;
                        GPS_pub.publish(GPS_data);
                        //如果剩下的字符大于等于4,则继续循环寻找有效数据,如果所剩字符小于等于3则跳出循环
                        if ( i+5 < strRece.length())
                            strRece = strRece.substr(end+2);
                        else
                        {   strRece = strRece.substr(end+2);
                            break;
                        }
                    }
                }
            }
        }
    ros::spinOnce();
    loop_rate.sleep();
    }
}

  

修改

1包含头文件

自定义消息路径和名字 工程包名字imu_gps_publish+自定义的消息名字topic_msg

 

 

 2 所有关于自定义消息的引用名字

包含头文件

 

 

 

 

3 修改波特率和串口号

并给与GPS串口权限

https://www.cnblogs.com/gooutlook/p/16494885.html

 

3-2接收节点

v1_GetGPS/src下创建listener.cpp

 

 

#include <iomanip>

#include "ros/ros.h"

#include "std_msgs/String.h"
#include "v1_GetGPS/topic_msg.h"


void chatterCallback(const v1_GetGPS::topic_msg::ConstPtr& msg)
{
    std::cout << "接收消息(小数10位):"<<std::setiosflags(std::ios::fixed) << std::setprecision(10) << "纬度:" << msg->lat << " 经度:" << msg->lon << "\n";
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("GPS", 1000, chatterCallback);
    ros::spin();
    return 0;
}

  

修改

1自定义消息路径和名字 工程包名字imu_gps_publish+自定义的消息名字topic_msg

 

 

 

2 所有关于自定义消息的引用名字

 

 

 

3-3 修改CMakeLists.txt编译节点

 

 

 添加发射和接受节点的生成

add_executable(serialPort src/serialPort.cpp)
target_link_libraries(serialPort ${catkin_LIBRARIES})
add_dependencies(serialPort ${PROJECT_NAME}_generate_messages_cpp) 

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp) 

  完整的

cmake_minimum_required(VERSION 3.0.2)
project(v1_GetGPS)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)


find_package(catkin REQUIRED COMPONENTS
  message_generation
  message_runtime
  roscpp
  rospy
  std_msgs
  serial #串口引用
)

add_message_files(
  FILES
  topic_msg.msg#消息引用-添加我们自己定义的xxx.msg文件
)

generate_messages(
  DEPENDENCIES
  std_msgs#消息引用-自带
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES my_topic002
#  CATKIN_DEPENDS message_generation message_runtime roscpp rospy std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########


include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

add_executable(publisher_gps src/publisher_gps.cpp)
target_link_libraries(publisher_gps ${catkin_LIBRARIES})
add_dependencies(publisher_gps ${PROJECT_NAME}_generate_messages_cpp) 

add_executable(subscriber_gps src/subscriber_gps.cpp)
target_link_libraries(subscriber_gps ${catkin_LIBRARIES})
add_dependencies(subscriber_gps ${PROJECT_NAME}_generate_messages_cpp) 


add_executable(serialPort src/serialPort.cpp)
target_link_libraries(serialPort ${catkin_LIBRARIES})
add_dependencies(serialPort ${PROJECT_NAME}_generate_messages_cpp) 

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp) 

3-4 编译工程

在大工程catkin_gps下编译

catkin_make

  

 

 

 

4运行工程

4-1 运行ros初始化

随意路径运行,必须单独运行在一个窗口

  

roscore

  

 

 

4-2 在命令行注册项目地址,使得命令行可以找到要执行的ros节点

 

 

source /home/dongdong/v2_Project/v4_ROS/catkin_gps/devel/setup.bash

  

4-3 运行节点

rosrun 项目名字 编译节点

运行发布节点

rosrun v1_GetGPS serialPort

  

 

 

 

 

 

 运行接受节点

 

 

 

 

使用脚本一次性执行

https://www.cnblogs.com/gooutlook/p/16495002.html

创建脚本

gedit ros_run_gps.sh

  

 

 

#!/bin/sh


#延迟1秒执行
sleep 1
  
echo "ROS——GPS 测试"
#echo "GPS 测试开始,消息记录到日志里" > /home/pi/start/test_desk1.log


echo "1 开启ros节点 roscore 等待完全开启再往后执行 "
gnome-terminal -t "1_roscore" -x bash -c "\
roscore; \
exit;exec bash;"
sleep 5


echo "2 开启发送节点 serialPort "
gnome-terminal -t "2_serialPort" -x bash -c "\
echo \"dongdong\" | sudo chmod 777 /dev/ttyUSB0; \ 
source /home/dongdong/v2_Project/v4_ROS/catkin_gps/devel/setup.bash; \
rosrun v1_GetGPS serialPort; \
exit;exec bash;"
sleep 1

echo "3 开启接收节点 listener"

gnome-terminal -t "3_listener" -x bash -c "\   
source /home/dongdong/v2_Project/v4_ROS/catkin_gps/devel/setup.bash; \
rosrun v1_GetGPS listener; \
exit;exec bash;"
sleep 1


#echo "执行前确保给与脚本本身执行权限 sudo chmod -R 777 xxx.sh"
#echo "查看串口: ls /dev/ttyUSB* "
#echo "临时给与一次串口权限: sudo chmod 777 /dev/ttyUSB0 "
# 开启新的命令窗口执行
# gnome-terminal -t "窗口名字" -x bash -c "要执行的命令1;命令2;exit;exec bash;"
#Shell 脚本自动输入密码 : echo "密码" | sudo 命令

   给与脚本执行权限

sudo chmod -R 777 ros_run_gps.sh

  

 

 

运行脚本

 

 

 

结果

 主窗口

 

 窗口1

逐个启动比较慢,所以要等待一会在执行后续的ROS脚本 

 

窗口2 

 

 手动输入密码

 

 

窗口3 

 

 

 

 

 

  

     

 

标签:std,ROS,catkin,include,add,串口,cpp,GPS,gps
来源: https://www.cnblogs.com/gooutlook/p/16495262.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有