利用json文件实现不同设备间的交互(二)

      cartographer建图过程中,当json文件中map_builder_save属性的value置1,即接收到地图保存信号时,应实现结束建图且保存地图,同时将map_builder_save置0。保存地图完成后,将map_builder_exit置1,即发出结束建图进程的信号。对cartographer_ros源码做修改,新建监听json文件的线程,当json文件内容发生改变时,做出相应处理。

      因为不需要对json文件进行深层次的处理,仅需查询和修改的功能。我选取了rapidjson作为c++处理json文件的工具。rapidjson是全头文件包含的,使用简单;而jsoncpp需要内置编译或库编译,我花费比较长时间也没成功将其应用于手头工程。从github上下载rapidjson代码,将/include/rapidjson放入工程中即可在头文件中引用,再一起编译即可。rapidjson的github链接:https://github.com/Tencent/rapidjson

对mode_main.cc的修改如下:

#include "rapidjson/document.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
...
using namespace rapidjson;
using std::string;  
...
namespace cartographer_ros {
namespace {
int save_signal = 0;
std::string json_filepath = "/home/cabin/Desktop/remote_communication/task_state.json";
...
void modify_json(int m_value){
    rapidjson::Document m_newDoc;	
    char m_readbuffer[6556];
    FILE* m_myFile = fopen(json_filepath.c_str(),"r");
    FileReadStream m_frs(m_myFile,m_readbuffer,sizeof(m_readbuffer));
    m_newDoc.ParseStream(m_frs);
    fclose(m_myFile);
    
    if( 0 == m_value ){    
        m_newDoc["map_builder"]["map_builder_save"] = 0;
    }
    else {
	m_newDoc["map_builder"]["map_builder_exit"] = 1;
    }
    StringBuffer writebuffer;
    Writer<StringBuffer> writer(writebuffer);
    m_newDoc.Accept(writer);
    std::string strJson(writebuffer.GetString(),writebuffer.GetSize());
    std::ofstream outfile;
		
    outfile.open(json_filepath.c_str());
    outfile<<strJson;
    outfile.close();
        
  }
...
}}

   modify_json(0)即将json文件中的map_build.map_build_save修改为0;modify_json(1)即将json文件中的map_build.map_build_exit修改为1。实际上对json文件的处理可以写得更灵活,更模块化,比如void modified_json(jsonpath,key,value)形式,即将jsonpath路径下的json文件中的key修改为value。按实际工程上述的写法已经满足需求。

namespace cartographer_ros{
namespace{
...
void sub_save_signal_thread(){
	rapidjson::Document newDoc;	
	char readbuffer[6556];
	while(1){
	ros::Duration(1).sleep();
        FILE* myFile = fopen(json_filepath.c_str(),"r");
        FileReadStream frs(myFile,readbuffer,sizeof(readbuffer));
        newDoc.ParseStream(frs);
        fclose(myFile);
		
	save_signal = newDoc["map_builder"]["map_builder_save"].GetInt();
	}
}
...
}
}

      监听json文件的线程,将json文件的map_builder_save的值赋予全局变量save_signal。注意对json文件的监听时,不能读取频率太高,应设一个时延,否则会报错。

namespace cartographer_ros{
namespace{
void Run(){
    ...
  capture_input_id_ = new std::thread(&CaptureInputThread);
  sub_save_signal_thread_id = new std::thread(&sub_save_signal_thread);
    ...
  while(ros::ok()){
    ::ros::spinOnce();
    if(1 == save_signal){
        modify_json(0);
	ros::Duration(2).sleep();
	node.FinishAllTrajectories();
        node.RunFinalOptimization();
		
        if(node_options.flag_generate_pbstream_map){
            time_t now;
            struct tm *timenow;
            time(&now);
            timenow = localtime(&now);
            char time_now_str[100];
            strftime(time_now_str, 100, "%Y%m%d%H%M%S", timenow);
            string time_now = time_now_str;

            const string pbstream_filename_ = "/home/cabin/cartographer_map_file/"+time_now+".pbstream";       
            const string pgm_filename_ = "/home/cabin/cartographer_map_file/"+time_now;
            node.SerializeState(pbstream_filename_);
            Pbstream_to_ros_map pbstream_to_ros_map;
            std::cout<<"generating the map files, please wait ..."<<&std::endl;
            pbstream_to_ros_map.pgm_map_build(pbstream_filename_, pgm_filename_,0.05);
            generate_map_flag = '\0';
            std::cout<<"\n=====================map generate finished=============================\n"<<&std::endl;
            modify_json(1);
       } }		
     ...    
}
}
}
}

      实现开头描述的功能。建图过程中监听map_builder_save,当其为1时,将其修改为0,结束建图且保存地图,将map_builder_exit修改为1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值