ROS采集GPS/北斗数据在百度地图中可视化位置

2023-05-16

关注微信公众号“混沌无形”,后台回复:13462F2。免费获取完整工程源码!

基于USB-RS232协议输出UM220-III/3-N/北斗GPS模块定位信息,使用ROS与js的接口包——roslibjs,调用百度地图js API,并可视化数据,笔者测试的效果如下(红点表示经过的路径点,GPS/北斗数据存在误差,所以路径点不连续)

使用者需要先下载安装roslibjs,再注册百度地图或高德地图。

读取GPS/北斗的定位数据代码

import serial

import rospy

from nmea_msgs.msg import Sentence
from libnmea_navsat_driver.driver import RosNMEADriver

if __name__ == '__main__':
    rospy.init_node('nmea_topic_serial_reader')

    # fine when using 10 Hz
    nmea_pub = rospy.Publisher("nmea_sentence", Sentence, queue_size=3)

    serial_port = rospy.get_param('~port','/dev/ttyUSB0')
    serial_baud = rospy.get_param('~baud',115200)

    # Get the frame_id
    frame_id = RosNMEADriver.get_frame_id()

    try:
        GPS = serial.Serial(port=serial_port, baudrate=serial_baud, timeout=2)
        while not rospy.is_shutdown():
            data = GPS.readline().strip()

            sentence = Sentence()
            sentence.header.stamp = rospy.get_rostime()
	    sentence.header.frame_id = frame_id
            sentence.sentence = data

            nmea_pub.publish(sentence)

    except rospy.ROSInterruptException:
        GPS.close() #Close GPS serial port

数据点在网页的可视化代码为

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
		body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
	</style>
<title>地图显示</title>
<script  src="http://api.map.baidu.com/api?v=2.0&ak=Ii2oy8BEXRtwXOW1wo0oRb4xGneV6nCm"></script>

<script src="https://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
<script src="../build/roslib.js"></script>
</head>

<body>
  
  <div id="statusIndicator">
    <p id="connecting">
      Connecting to rosbridge...
    </p>
    <p id="connected" style="color:#00D600; display:none">
      Connected
    </p>
    <p id="error" style="color:#FF0000; display:none">
      Error in the backend!
    </p>
    <p id="closed" style="display:none">
      Connection closed.
    </p>
  </div>
</ol>
  <div id="allmap"></div>
  
<script type="text/javascript"> 
  // Connecting to ROS
  // -----------------
  var ros = new ROSLIB.Ros();

  // If there is an error on the backend, an 'error' emit will be emitted.
  ros.on('error', function(error) {
    document.getElementById('connecting').style.display = 'none';
    document.getElementById('connected').style.display = 'none';
    document.getElementById('closed').style.display = 'none';
    document.getElementById('error').style.display = 'inline';
    console.log(error);
  });

  // Find out exactly when we made a connection.
  ros.on('connection', function() {
    console.log('Connection made!');
    document.getElementById('connecting').style.display = 'none';
    document.getElementById('error').style.display = 'none';
    document.getElementById('closed').style.display = 'none';
    document.getElementById('connected').style.display = 'inline'; 
  });

  ros.on('close', function() {
    console.log('Connection closed.');
    document.getElementById('connecting').style.display = 'none';
    document.getElementById('connected').style.display = 'none';
    document.getElementById('closed').style.display = 'inline';
  });

  // Create a connection to the rosbridge WebSocket server.
  ros.connect('ws://localhost:9090');

  // define two global variant
  var x = 0;
  var y = 0;

  //Subscribing to a Topic
  //----------------------

  // Like when publishing a topic, we first create a Topic object with details of the topic's name
  // and message type. Note that we can call publish or subscribe on the same topic object.
  var carPose = new ROSLIB.Topic({
    ros : ros,
    name : '/simplegps',
    messageType : 'geometry_msgs/Pose2D'
  });

  var sample = new ROSLIB.Topic({
    ros : ros,
    name : '/simplegps',
    messageType : 'geometry_msgs/Pose2D'
  });
  // Then we add a callback to be called every time a message is published on this topic.

  carPose.subscribe(function (message) {
    window.x = message.x;
    window.y = message.y;
    var map = new BMap.Map("allmap",{minZoom:3,maxZoom:19}); // 创建Map实例,设置地图允许的最小/大级别 

    var gpspoint = new BMap.Point(window.x, window.y); // 创建点坐标
    
    // 添加带有定位的导航控件
  var navigationControl = new BMap.NavigationControl({
    // 靠左上角位置
    anchor: BMAP_ANCHOR_TOP_LEFT,
    // LARGE类型
    type: BMAP_NAVIGATION_CONTROL_LARGE,
    // 启用显示定位
    enableGeolocation: true
  });
  map.addControl(navigationControl);


// 添加定位控件
  var geolocationControl = new BMap.GeolocationControl();
  geolocationControl.addEventListener("locationSuccess", function(e){
    // 定位成功事件
    var address = '';
    address += e.addressComponent.province;
    address += e.addressComponent.city;
    address += e.addressComponent.district;
    address += e.addressComponent.street;
    address += e.addressComponent.streetNumber;
    alert("当前定位地址为:" + address);
  });
  geolocationControl.addEventListener("locationError",function(e){
    // 定位失败事件
    alert(e.message);
  });
  map.addControl(geolocationControl);


    //添加地图类型控件
	map.addControl(new BMap.MapTypeControl({
		mapTypes:[
            BMAP_NORMAL_MAP,
            BMAP_HYBRID_MAP
        ]}));	  
    map.setCurrentCity("重庆");          // 设置地图显示的城市 此项是必须设置的
	
  //坐标转换完之后的回调函数
    translateCallback = function (data){

	var bdpoint = data.points[0];
     	map.centerAndZoom(bdpoint, 12);	
        
    	map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放         
	function Sample()  //标住更新的位置
	{ 
 		sample.subscribe(function (message) {
    		window.x = message.x;  //更新点坐标
    		window.y = message.y;
		var gpspoint = new BMap.Point(window.x, window.y); // 创建点坐标
   		translateCallback1 = function (data)
			{	
			var bdpoint1 = data.points[0]	//创建点坐标
			var marker = new BMap.Marker(bdpoint1); // 创建标注
       			map.addOverlay(marker); // 将标注添加到地图中
        		}

		function zbzh1()   //坐标转换
		{
 			var convertor = new BMap.Convertor();
       			var pointArr = [];
       			pointArr.push(gpspoint);
        		convertor.translate(pointArr, 1, 5, translateCallback1)
		}		 
		
		zbzh1();
		sample.unsubscribe();
  		});
	}

  	function xh() //无限循环
	{

		
			setTimeout(function(){
			Sample ();
			xh();
					},3000);
		

	}
       
   	setTimeout(xh(),3000);
    }


    function zbzh()   //坐标转换
	{
 	var convertor = new BMap.Convertor();
        var pointArr = [];
        pointArr.push(gpspoint);
        convertor.translate(pointArr, 1, 5, translateCallback)
	}
    
    zbzh();

    // If desired, we can unsubscribe from the topic as well.
    carPose.unsubscribe();
  });

</script>

</body>
</html>

喜欢的话,请关注微信公众号,可阅读更多好文!

 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS采集GPS/北斗数据在百度地图中可视化位置 的相关文章

  • SpringBoot使用阿里云邮件服务实现账户分享

    1 阿里云邮件集成 详情参见 xff1a Java SpringBoot集成阿里云短信与邮件服务 阿里云短信jar包 大鱼 gt 的博客 CSDN博客 2 使用Html模板实现邮件内容样式 2 1 引入pom lt dependency g
  • OSM学习之路(一):OSM介绍

    背景 xff1a 公司作为车联网行业 xff0c 少不了与地图打交道 xff0c 之前一直依赖谷歌 xff0c 百度等三方地图供应商来处理地图方面问题 但是随着客户量越来越大 xff0c 谷歌的吃相变得越来越难看 自7月16日起 xff0c
  • C语言单链表和结构体的结合

    链表与结构体的结合 xff0c 可以很好的方便输入输出 xff0c 以后使用链表时只需要将结构体的信息稍作修改就可以使用 xff0c 非常方便 xff01 xff01 xff01 下面是写学生学号和姓名的结构体与链表的结合create函数
  • struct和class的区别

    总结 xff0c 主要有这么几点不同 xff1a 1 struct 是值类型 xff0c class 是对象类型 2 struct 不能被继承 xff0c class 可以被继承 3 struct 默认的访问权限是public 而class
  • c++中模板类的成员函数的声明与定义应该放在头文件里

    今天尝试自己实现vector数据结构底层 xff0c 在定义vector模板类的时候 xff0c 还想像往常一样把类分为 h文件和 cpp文件 xff0c 把成员函数的声明放在 h文件中 xff0c 把具体实现放在 cpp文件中 xff0c
  • Byte 高位/低位简介绍(大端格式/小端格式)

    一个byte由8个二进制位构成1个字节 即1Byte 61 8Bit 其中左边是高位 xff0c 右边是低位 high four 61 byte amp 0xf0 gt gt 4 0xf0 61 11110000 low four 61 b
  • Python3+Requests库带验证码登陆学校教务系统的尝试。

    毕业快两年了 xff0c 上班空闲摸鱼的时候无意中打开了学校的教务系统 发现浏览器还记着我的学号和登陆密码 果然是很多东西你自己都忘了 xff0c 浏览器的云端都帮你记着 xff0c 输入验证码之后居然登陆进去了 学校的教务系统还是一如既往
  • RK3568开发笔记-socketCan编程

    目录 前言 一 socket can创建 xff1f 二 系统can节点设置 三 can过滤器设置 四 can数据发送 五 can数据接收 总结 前言 CAN是ControllerArea Network xff08 控制器局域网 xff0
  • vs2015基于UDP协议的简单通信例程

    vs2015基于UDP协议的简单通信例程 关键字 xff1a socket套接字 udp通信 注意 xff1a 1 UDP发送和接受数据分别使用sendto 和recvfrom 函数 xff0c 注意函数的用法 xff1b 2 在vs201
  • memcpy与结构体

    前言 最近小学期做通信的实验 xff0c 很有意思 通讯是用了老师统一规定的结构体 xff0c 但是苦于结构体与要传输时字符串数组的转换 xff0c 思索了很久没有结果 启发 在zigbee协议栈已经看到 xff0c 传输结构体时 xff0
  • (一)SAS初识

    1 SAS常用工作窗口 结果 xff08 Result xff09 窗口 管理SAS程序的输出结果 xff1b 日志 xff08 Log xff09 窗口 记录程序的运行情况 xff1b SAS资源管理器 xff08 Explore xff
  • 2021-08-31

    二次规划求解器OOQP的基础使用 前言一 OOQP所包含参数的定义二 简单调用1 头文件2 参数设置3 进行求解4 取出计算结果 总结 前言 OOQP作为一款强大的开源凸优化库 支持C 43 43 Matlab调用 现在这里记录下其简单的使
  • Smart PLC与Wincc通过Simatic NET建立OPC通讯(1)

    有已经组态好的XDB文件可以在我的博客下载中心下载SIMATIC NET通讯 xff0c 下载完成直接导入到Simaticnet软件即可 xff0c 如下图 xff1a 下载链接 xff1a https download csdn net
  • 如何下载西门子PLC的CAD图库

    1 进入西门子下载中心 xff0c 网址如下 xff1a https www automation siemens com bilddb search aspx multipleObjectTypes 61 61 64 63 65 60 2
  • 串联电阻和并联电阻的计算方法

    注 xff1a 并联电路的电阻计算公式 1 R总 61 1 R1 43 1 R2 电阻可以无限数量的串联和并联组合连接在一起形成复杂的电阻电路 在之前的教程中 xff0c 我们学习了如何将各个电阻连接在一起形成一个系列电阻器网络或并联电阻器
  • 西门子V90 PN控制FB284块的个人理解

    FB284块的引脚定义 xff1a 1 MDI xff08 Manual Data Input xff09 称为设定值直接给定运行方式 即上位控制器直接设置目标位置 速度 加减速度后 xff0c 轴自动移动到目标位置的定位方式 MDI也是实
  • 伺服驱动

    1 什么是丝杠的导程 xff1f 伺服电机旋转一圈360度 xff0c 同时带动丝杠旋转360度 导程只是关系到丝杆转一圈 xff0c 丝杆螺母走的距离 如果配有减速机的话 xff0c 会有一个减速比 xff0c 如果减速比为1 12的话
  • 增量式编码器与绝对值编码器的区别

    增量式编码器只能记住自己走了多少步 xff0c 当然会有一个原点 在开机第一次走过原点一千 xff0c 它是不知道自己的位置在什么地方 绝对值编码器只要上电就能知道自己现在所处的位置 xff0c 绝对值编码器需要刻更多的线 xff0c 成本
  • RS422-RS485-RS232标准接线

    1 RS422标准接线 2 RS485标准接线 3 RS485全双工接线
  • C语言中关于合法的数值常量

    1 八进制常量 xff1a 开头必须是0 xff0c 且八进制是0 7之间组成的数 xff0c 例如 xff0c 029就是错误的八进制表示方式 2 十六进制常量 xff1a 0X开头 xff0c 包含字母ABCDEF xff0c 不区分大

随机推荐