利⽤ros的发布订阅机制来传输建图⽣成的yaml⽂件和pgm⽂件(实现地图共
享)
传输yaml⽂件
由于采⽤C++编写需要安装什么解析yaml的包yaml-cpp。我⼀整个周⽇都花费在安装这个上⾯了,也没按好,所以采⽤的python。(简直不要太好⽤)
这时我们的yaml⽂件内容:
image: turtlebot_test_map.pgm
resolution: 0.050000
origin: [-13.800000, -15.400000, 0.000000]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196
然后根据内容我们确定了⾃定义消息的格式:天津hr培训
string image
float64 resolution
float64 X
float64 Y
float64 W
int32 negate
float64 occupied_thresh
float64 free_thresh
废话不多说,我们先整上代码。
⾸先是发布端:talker:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import sys
import rospy
import yaml
from handle_yaml.msg import yamlMsg
def nd_yaml():
rospy.init_node("read_yaml_talker",anonymous=True)
pub=rospy.Publisher("handle_yaml",yamlMsg,queue_size=50)
f=open('/home/daniel/map/turtlebot_test_map.yaml')
content=yaml.load(f)
print(content)
temp=yamlMsg()英文培训
temp.image=content['image']
temp.X=content['origin'][0]
temp.Y=content['origin'][1]
temp.W=content['origin'][2]
元旦来历
temp.free_thresh=content['free_thresh']
rate=rospy.Rate(10)
#count=0
while not rospy.is_shutdown():
#if(count==0):
print(temp)
pub.publish(temp)
print("already nt")
ie是什么意思# count=1
rate.sleep()
if __name__=='__main__':
try:
nd_yaml()
eliza
except rospy.ROSInterruptException:
pass
然后我们对代码进⾏解析:
import sys
import rospy
import yaml
from handle_yaml.msg import yamlMsg
先导⼊rospy模块,yaml模块 和⾃定义的消息模块
decompof=open('/home/daniel/map/turtlebot_test_map.yaml')
content=yaml.load(f)
这段代码是打开我们指定路径的yaml⽂件,然后将其加载成字典
temp=yamlMsg()
temp.image=content['image']
temp.X=content['origin'][0]
temp.Y=content['origin'][1]
temp.W=content['origin'][2]
temp.free_thresh=content['free_thresh']
这⾥是将字典的值赋给我们⾃定义消息类的对象。然后之后将⾃定义消息对象进⾏发布。pub.publish(temp)
然后将消息进⾏发布
listener:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ ='Anthony'
import sys
import rospy
import yaml
import os
from handle_yaml.msg import yamlMsg
def callback(Msg):
yaml_dict={}
yaml_dict['image']=Msg.image
yaml_dict['resolution']=solution
#yaml_dict['origin'][0]=Msg.X
#yaml_dict['origin'][1]=Msg.Y
#yaml_dict['origin'][2]=Msg.W
yaml_dict['origin']=[Msg.X,Msg.Y,Msg.W]
yaml_dict['negate']=ate
yaml_dict['occupied_thresh']=upied_thresh
yaml_dict['free_thresh']=Msg.free_thresh
curpath=os.path.dirname(alpath(__file__))
yamlpath=os.path.join(curpath,"test.yaml")
print('the path is:%s',yamlpath)
# write yaml file
with open(yamlpath,'w',1)as f:
yaml.dump(yaml_dict,f)
def rec_yaml():
rospy.init_node('write_yaml_listener',anonymous=True)
rospy.Subscriber('handle_yaml',yamlMsg,callback)
rospy.spin()
if __name__=='__main__':
try:
rec_yaml()
except rospy.ROSInterruptException:
pass
下⾯解析这段代码:
yaml_dict['image']=Msg.image
yaml_dict['resolution']=solution
#yaml_dict['origin'][0]=Msg.X
#yaml_dict['origin'][1]=Msg.Y
#yaml_dict['origin'][2]=Msg.W
yaml_dict['origin']=[Msg.X,Msg.Y,Msg.W]
何凯文四六级yaml_dict['negate']=ate
yaml_dict['occupied_thresh']=upied_thresh
rviceasdfghyaml_dict['free_thresh']=Msg.free_thresh
这个是将订阅过来的消息付给我们建⽴的字典(注意注释这样不⾏)必须是下⾯那⾏代码,才能可以(这⼜坑了我半天时间55555555555555)唉,不熟悉py的原因,
curpath=os.path.dirname(alpath(__file__))
yamlpath=os.path.join(curpath,"test.yaml")
第⼀⾏是获取当前运⾏⽂件的路径,然后将我们的test.yaml ⽂件加⼊到当前路径⾥⾯
with open(yamlpath,'w',1)as f:
yaml.dump(yaml_dict,f)
将字典写到test.yaml⽂件中,⼤功告成
传输地图⽂件pgm
我们使⽤image_transport发布者,它可以发布单⼀图像或多个图像。这个我找了github上的⼀个源码。链接是
然后注释掉我们不需要的功能就ok了。
发布端:
#include<ros/ros.h>
#include<image_transport/image_transport.h>
#include<cv_bridge/cv_bridge.h>
#include<nsor_msgs/image_encodings.h>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
static const std::string IMAGE_PATH ="/home/daniel/map/turtlebot_test_map.pgm";
static const std::string TOPIC_NAME ="camera/rgb/image";
int publishImage(std::string filepath)
{
Mat image;
image =imread(filepath, CV_LOAD_IMAGE_COLOR);// Read the file
std::cout <<"Path "<< filepath << std::endl;
if(!image.data)// Check for invalid input
{
std::cout <<"Could not open or find the image"<< std::endl ;
return-1;
}
ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Publisher pub = it.adverti(TOPIC_NAME,1);
nsor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(),"bgr8", image).toImageMsg(); ros::Rate loop_rate(5);
while(nh.ok()){
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
int publishImageWithoutImage_transport()
{
ROS_INFO("Topic : %s", TOPIC_NAME.c_str());
ROS_INFO("IMAGE PATH : %s", IMAGE_PATH.c_str());
ros::NodeHandle nh;
std::string image_path = IMAGE_PATH;
男士面部美白
cv_bridge::CvImage cv_image;
cv_image.image = cv::imread(image_path, CV_LOAD_IMAGE_COLOR);
ding ="bgr8";
nsor_msgs::Image ros_image;
ImageMsg(ros_image);
ros::Publisher pub = nh.adverti<nsor_msgs::Image>(TOPIC_NAME,1);
ros::Rate loop_rate(5);
while(nh.ok())
{
pub.publish(ros_image);
ros::spinOnce();
loop_rate.sleep();
}
}
int main(int argc,char** argv)
{
ros::init(argc, argv,"image_transport_publisher");
publishImageWithoutImage_transport();
return0;
}