2015-05-23 1 views
0

Как передать переменную из программы на C++ в другую? переменной, которую мне нужно передать, является строка. Это файл C++, в котором я должен послать строку:Связь между файлами cpp

#include <string> 
#include <iostream> 

#include <ros/ros.h> 
#include <json_prolog/prolog.h> 

using namespace std; 
using namespace json_prolog; 


int main(int argc, char *argv[]) 
{ 
    ros::init(argc, argv, "Info"); 
    Prolog pl; 
    int c=0; 
    do 
    { 
    int i=0; 
    std::string M; 
    cout<<"Declare the name of the class of interest"<< "\t"; 
    cin>>M; 
    if (M=="knife") 
    ......... 

В этой программе я решаю, что строка М, но я хочу, что это М приходит с выхода другого файла CPP, который, очевидно, должен введите строку в качестве вывода.

это C++, который должен послать мне строку:

#include<aruco_marker_detector/arucoMarkerDetector.h> 

    namespace MarkerDetector { 

    void FilterButter(Vector3d &s, Vector3d &sf, Vector3d &bButter, Vector3d &aButter) 

{ 
    double r,rf; 
r=bButter.transpose()*s; 
rf=aButter.transpose()*sf; 

sf(0)=r-rf; 

s(2)=s(1); 
s(1)=s(0); 

sf(2)=sf(1); 
sf(1)=sf(0); 
} 

MarkerTracker::MarkerTracker(ros::NodeHandle &n) 
{ 
    this->nh = n;//dopo questa istruzione l'indirizzo che contiene l'id del nodo n e' salvato in nh 
    this->it = new image_transport::ImageTransport(this->nh);//salva in &it l'indirizzo della funzione ImageTransport(this->nh) appartenente al nuovo namespace image_transport 

    // ros::Duration r(1); 


    XmlRpc::XmlRpcValue my_list; 

    nh.getParam("marker_ids", my_list); 
    for (int32_t i = 0; i < my_list.size(); ++i) 
    { 
     this->markerIDs.push_back(-1); 
     //ROS_ASSERT(my_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble); 
     this->markerIDs[i]=static_cast<int>(my_list[i]); 
     //ROS_ERROR_STREAM("markerIDs["<<i<<"]: "<<this->markerIDs[i]); 
    } 
//r.sleep(); 

nh.getParam("marker_labels", my_list); 
for (int32_t i = 0; i < my_list.size(); ++i) 
{ 
    this->markerLables.push_back("NotSet"); 
    //ROS_ASSERT(my_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble); 
    this->markerLables[i]=static_cast<std::string>(my_list[i]); 
    //ROS_ERROR_STREAM("markerLables["<<i<<"]: "<<this->markerLables[i]); 
} 
//r.sleep(); 

this->markerTrackerID=-1; 
// 
//Load Parameters (rosparameters) 
nh.getParam("marker_tracker_id",this->markerTrackerID); 
//nh.getParam("marker_id",this->markerID); 
nh.getParam("camera_info_url",this->cameraParametersFile); 
nh.getParam("marker_size",this->markerSize); 
nh.getParam("block_size",this->thresParam1); 
nh.getParam("sub_constant",this->thresParam2); 
nh.getParam("camera_reference_frame",this->cameraReferenceFrame); 


nh.getParam("filter_coefficient_B", my_list); 
for (int32_t i = 0; i < my_list.size(); ++i) 
{ 
    //ROS_ASSERT(my_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble); 
    this->B(i)=static_cast<double>(my_list[i]); 
} 
nh.getParam("filter_coefficient_A", my_list); 
for (int32_t i = 0; i < my_list.size(); ++i) 
{ 
    //ROS_ASSERT(my_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble); 
    this->A(i)=static_cast<double>(my_list[i]); 
} 

nh.getParam("image_topic_name_raw",this->imageTopicRaw); 
nh.getParam("image_topic_name_proc",this->imageTopicProcessed); 
nh.getParam("camera_name_tag",this->cameraNameTag); 
nh.getParam("broadcast_tf_flag",this->broadcastTF); 




nh.getParam("camera_extrinsics",my_list); 

VectorXd in(16); 
this->TC_torso.Identity(); 

for (int32_t i = 0; i < my_list.size(); ++i) 
{ 
    in(i)=static_cast<double>(my_list[i]); 
} 

ROS_WARN_STREAM("in: \n"<<in.transpose()); 
// r.sleep(); 

// this->TC_torso.matrix()(0,0)=in(0*4+0); 
// this->TC_torso.matrix()(0,1)=in(0*4+1); 
// this->TC_torso.matrix()(0,2)=in(0*4+2); 
// this->TC_torso.matrix()(0,3)=in(0*4+3); 

// this->TC_torso.matrix()(1,0)=in(1*4+0); 
// this->TC_torso.matrix()(1,1)=in(1*4+1); 
// this->TC_torso.matrix()(1,2)=in(1*4+2); 
// this->TC_torso.matrix()(1,3)=in(1*4+3); 

// this->TC_torso.matrix()(2,0)=in(2*4+0); 
// this->TC_torso.matrix()(2,1)=in(2*4+1); 
// this->TC_torso.matrix()(2,2)=in(2*4+2); 
// this->TC_torso.matrix()(2,3)=in(2*4+3); 

// this->TC_torso.matrix()(3,0)=in(3*4+0); 
// this->TC_torso.matrix()(3,1)=in(3*4+1); 
// this->TC_torso.matrix()(3,2)=in(3*4+2); 
// this->TC_torso.matrix()(3,3)=in(3*4+3); 

for(unsigned int i=0;i<4;i++) 
{ 
    for(unsigned int j=0;j<4;j++) 
    { 
     this->TC_torso.matrix()(i,j)=in(i*4+j); 
    } 
} 




// this->TC_torso=Tmp; 


// Tmp.matrix()<<in; 
// 
// this->TC_torso=Tmp.matrix().transpose(); 


ROS_WARN_STREAM("TC_torso: \n"<<TC_torso.matrix()); 
//r.sleep(); 

//ROS_INFO_STREAM("B: "<<this->B.transpose()); 
//ROS_INFO_STREAM("A: "<<this->A.transpose()); 
//r.sleep(); 


//ROS_INFO_STREAM("marker_size: "<<this->markerSize); 
//r.sleep(); 
//ROS_INFO_STREAM("block_size: "<<this->thresParam1); 
//ROS_INFO_STREAM("sub_constant: "<<this->thresParam2); 
//r.sleep(); 
//ROS_INFO_STREAM("camera_info_url: "<<this->cameraParametersFile); 
//ROS_INFO_STREAM("markerTrackerID: "<<this->markerTrackerID); 
//r.sleep(); 
//ROS_INFO_STREAM("markerID: "<<this->markerID); 

std::stringstream label; 

label<<"SwitchFilter_"<<this->markerTrackerID; 
this->switchFilterService=this->nh.advertiseService(label.str(),&MarkerDetector::MarkerTracker::SwitchFilterCallBack,this); 
label.str(""); 

//this->cameraParameters.readFromXMLFile(this->cameraParametersFile); 

this->sub = it->subscribe(this->imageTopicRaw, 1, &MarkerDetector::MarkerTracker::imageCallback,this); 

//Publisher for the processed image 
this->pub = it->advertise(this->imageTopicProcessed, 1); 

// label<<"tfTarget_"<<this->cameraNameTag<<"_"<<this->markerTrackerID; 
// this->pubTF = nh.advertise<geometry_msgs::TransformStamped>(label.str(),100); 
// label.str(""); 

label<<"visualPoints_"<<this->cameraNameTag<<"_"<<this->markerTrackerID; 
this->pubVisData=nh.advertise<aruco_marker_detector::MarkerDataArray>(label.str(),100); 
label.str(""); 


this->Rz180<<-1,0,0,0,-1,0,0,0,1; 

this->setOld=true; 
this->filtered=true; 
this->cameraConfigured=false; 
} 

MarkerTracker::~MarkerTracker() 
{ 
    delete it; 

} 
//bool function switch on/off the filter 
bool MarkerTracker::SwitchFilterCallBack(aruco_marker_detector::switch_filter::Request &req,aruco_marker_detector::switch_filter::Response &res) 
{ 
    this->filtered=!this->filtered;//req.filtered; 
    res.confirm=this->filtered; 
    if(this->filtered) 
     ROS_INFO_STREAM("Marker Tracker ("<<this->markerTrackerID<<") Filter Switched ON ("<<this->filtered<<")"); 
    else 
     ROS_INFO_STREAM("Marker Tracker ("<<this->markerTrackerID<<") Filter Switched OFF ("<<this->filtered<<")"); 

    return true; 
} 

//This function is called everytime a new image is published 
void MarkerTracker::imageCallback(const sensor_msgs::ImageConstPtr& original_image) 
{ 
    //Convert from the ROS image message to a CvImage suitable for working with OpenCV for processing 
    cv_bridge::CvImagePtr cv_ptr; 
    static tf::TransformBroadcaster br1; 
    tf::Transform transform; 
    double markerPosition[3]; 
    double markerOrientationQ[4]; 
    Matrix3d R,Rfixed; 
    //Affine3d TC_torso; 
    Quaterniond q_eigen; 
    tf::Quaternion q_tf; 
    // 
    try 
    { 
     //Always copy, returning a mutable CvImage 
     //OpenCV expects color images to use BGR channel order. 
     cv_ptr = cv_bridge::toCvCopy(original_image, sensor_msgs::image_encodings::BGR8); 
    } 
    catch (cv_bridge::Exception& e) 
    { 
     //if there is an error during conversion, display it 
     ROS_ERROR_STREAM(__FILE__<<"::cv_bridge exception("<<__LINE__<<": "<<e.what()); 
     return; 
    } 

    //Get intrinsic parameters of the camera and size from image 
    if(!this->cameraConfigured) 
    { 
     this->cameraParameters.readFromXMLFile(this->cameraParametersFile); 
     this->cameraParameters.resize(cv_ptr->image.size()); 
     this->cameraConfigured=true; 
    } 

    this->MDetector.pyrDown(0); 

    this->MDetector.setThresholdParams(this->thresParam1,this->thresParam2); 
    this->MDetector.setCornerRefinementMethod(aruco::MarkerDetector::SUBPIX); 

//Detect Markers 
this->MDetector.detect(cv_ptr->image,this->Markers,this->cameraParameters,this->markerSize); 

std::stringstream s; 

//Camera Frame 
// Rz180<<-1,0,0,0,-1,0,0,0,1; 

//This is the transformation from camera to world and it must be obtained from camera calib 
//TC_torso.matrix()<<0,0,1,-1.1,-1,0,0,0.1,0,-1,0,0.0; 
tf::transformEigenToTF(TC_torso,transform); 
if(this->broadcastTF) 
{ 
    br1.sendTransform(tf::StampedTransform(transform, ros::Time::now(), cameraReferenceFrame, this->cameraNameTag)); 
} 

tf::StampedTransform sTransform; 
geometry_msgs::Transform msgTransform; 
aruco_marker_detector::MarkerDataArray msgVisPointsArray; 
aruco_marker_detector::MarkerData aux; 

aruco::Marker tmp; 

bool publishTF=false; 
bool idNotDefined=true; 

//for each marker, draw info and its boundaries in the image 
for (unsigned int i=0;i<this->Markers.size();i++) 
{ 
    idNotDefined=true; 

    this->Markers[i].draw(cv_ptr->image,cv::Scalar(0,0,255),2); 


    this->Markers[i].OgreGetPoseParameters(markerPosition,markerOrientationQ); 

    R = Eigen::Quaterniond(markerOrientationQ[0], markerOrientationQ[1], markerOrientationQ[2], markerOrientationQ[3]); 

    Rfixed=this->Rz180*R; 

    q_eigen=Rfixed; 
    tf::quaternionEigenToTF(q_eigen,q_tf); 



    transform.setOrigin(tf::Vector3(-markerPosition[0], - markerPosition[1],markerPosition[2])); 
    transform.setRotation(q_tf); 

    for(unsigned int j=0;j<this->markerIDs.size();j++) 
    { 
     if(Markers[i].id==this->markerIDs[j]) 
     { 
      s<<this->markerLables[j]<<"_"<<this->cameraNameTag; 
      idNotDefined=false; 
      break; 
     } 
    } 




    //This is what he do if recognise a marker 
    //Marker with id 455 represents the target and we need to filter its pose 
    //If you need to filter any marker then remove the if statement and set publishTF=true 
if(Markers[i].id<=40 && Markers[i].id>=20) 
    { 
    int z=Markers[i].id; 
    switch (z){ 
     case 20: 
     { 
       publishTF=true; 
      s<<"Electronics:Phone"; 
     break; 
     } 
     case 30: 
     { 
       publishTF=true; 
      s<<"Electronics:Pc"; 
     break; 
     } 
     case 40: 
     { 
       publishTF=true; 
      s<<"Electronics:Printer"; 
     break; 
     } 
     default: 
     { 
      publishTF=true; 
      s<<"Electronics:Undefined_Object"; 
     } 
      } 
    } 
else if(Markers[i].id<=935 && Markers[i].id>=915) 
    { 
     int z=Markers[i].id; 
    switch (z){ 
     case 915: 
     { 
       publishTF=true; 
      s<<"Kitchen_utensil:Fork"; 
     break; 
     } 
     case 925: 
     { 
       publishTF=true; 
      s<<"Kitchen_utensil:Spoon"; 
     break; 
     } 
     case 935: 
     { 
       publishTF=true; 
      s<<"Kitchen_utensil:Knife"; 
     break; 
     } 
     default: 
     { 
      publishTF=true; 
      s<<"Kitchen_utensil:Undefined_Object"; 
     } 
      }   
} 
else if(Markers[i].id<=220 && Markers[i].id>=200) 
    { 
      int z=Markers[i].id; 
    switch (z){ 
     case 200: 
     { 
       publishTF=true; 
      s<<"Container:Pot"; 
     break; 
     } 
     case 210: 
     { 
       publishTF=true; 
      s<<"Container:Basket"; 
     break; 
     } 
     case 220: 
     { 
       publishTF=true; 
      s<<"Container:Box"; 
     break; 
     } 
     default: 
     { 
      publishTF=true; 
      s<<"Container:Undefined_Object"; 
     } 
      }   
} 
else 
    { 
     s<<"Unknown_Object"; 
    } 
    if(publishTF) 
    { 

     //Filter Signal 
     if(filtered) 
     { //If the signal is non filtered,filter it and than save values of position and orientation 
      tf::Vector3 X=transform.getOrigin(); 
      tf::Quaternion Q=transform.getRotation(); 

      //Orientation 
      this->qx(0)=Q.getX(); 
      this->qy(0)=Q.getY(); 
      this->qz(0)=Q.getZ(); 
      this->qw(0)=Q.getW(); 

      //Position 
      this->x(0)=X.getX(); 
      this->y(0)=X.getY(); 
      this->z(0)=X.getZ(); 


      if(setOld) 
      { 
       //copy the first transformation to old and vold in both real and filtered 
       for(unsigned int i=1;i<3;i++) 
       { 
        this->qx(i)=qx(0); 
        this->qy(i)=qy(0); 
        this->qz(i)=qz(0); 
        this->qw(i)=qw(0); 

        this->qxf(i)=qx(0); 
        this->qyf(i)=qy(0); 
        this->qzf(i)=qz(0); 
        this->qwf(i)=qw(0); 

        this->x(i)=x(0); 
        this->y(i)=y(0); 
        this->z(i)=z(0); 

        this->xf(i)=x(0); 
        this->yf(i)=y(0); 
        this->zf(i)=z(0); 

       } 

       setOld=false; 
      } 

      MarkerDetector::FilterButter(this->qx,this->qxf,this->B,this->A); 
      MarkerDetector::FilterButter(this->qy,this->qyf,this->B,this->A); 
      MarkerDetector::FilterButter(this->qz,this->qzf,this->B,this->A); 
      MarkerDetector::FilterButter(this->qw,this->qwf,this->B,this->A); 

      MarkerDetector::FilterButter(this->x,this->xf,this->B,this->A); 
      MarkerDetector::FilterButter(this->y,this->yf,this->B,this->A); 
      MarkerDetector::FilterButter(this->z,this->zf,this->B,this->A); 



      transform.setRotation(tf::Quaternion(this->qxf(0),this->qyf(0),this->qzf(0),this->qwf(0))); 
      transform.setOrigin(tf::Vector3(this->xf(0),this->yf(0),this->zf(0))); 
     } 


     sTransform=tf::StampedTransform(transform, ros::Time::now(), this->cameraNameTag, s.str()); 
     if(this->broadcastTF) 
     { 
      br1.sendTransform(sTransform); 
     } 

     publishTF=false; 
    } 
    else 
    { 
     sTransform=tf::StampedTransform(transform, ros::Time::now(), this->cameraNameTag, s.str()); 
     if(this->broadcastTF) 
     { 
      br1.sendTransform(sTransform); 
     } 
    } 

    //Clear the labels 
    s.str(""); 


    if (cameraParameters.isValid()) 
    { 

     //   aruco::CvDrawingUtils::draw3dCube(cv_ptr->image,Markers1[i],cameraParameters1); 
     aruco::CvDrawingUtils::draw3dAxis(cv_ptr->image,Markers[i],cameraParameters); 
    } 

    aux.markerID=Markers[i].id; 
    cv::Point2f cent=Markers[i].getCenter(); 
    for(unsigned int ind=0;ind<4;ind++) 
    { 
     aux.points[ind].x=Markers[i][ind].x; 
     aux.points[ind].y=Markers[i][ind].y; 
     //Force the visual points to be homogeneous --this is used with the homography transformation -- 
     aux.points[ind].z=1.0; 

    } 

    //Plot Marker Center 
    aux.points[4].x=cent.x; 
    aux.points[4].y=cent.y; 
    //Force the visual points to be homogeneous --this is used with the homography transformation -- 
    aux.points[4].z=1.0; 



    cv::circle(cv_ptr->image,cv::Point2f(aux.points[4].x,aux.points[4].y),1,cv::Scalar(0,255,255),6); 

    //Copy current transform 
    tf::transformTFToMsg(transform,msgTransform); 
    aux.tfMarker=msgTransform; 


    msgVisPointsArray.header.stamp = ros::Time::now(); 
    msgVisPointsArray.header.frame_id = this->cameraNameTag; 
    msgVisPointsArray.mTrackerID = this->markerTrackerID; 
    msgVisPointsArray.markerData.push_back(aux); 

    //Print the visual position of the marker's center 
    s<<"("<<msgVisPointsArray.markerData[i].points[4].x<<","<<msgVisPointsArray.markerData[i].points[4].y<<")"; 
    cv::putText(cv_ptr->image,s.str().c_str(),cent,cv::FONT_HERSHEY_COMPLEX,1,cv::Scalar(255,0,0),3); 
    s.str(""); 


} 

/** 
* The publish() function is how you send messages. The parameter 
* is the message object. The type of this object must agree with the type 
* given as a template parameter to the advertise<>() call, as was done 
* in the constructor in main(). 
*/ 
//Convert the CvImage to a ROS image message and publish it on the "camera/image_processed" topic. 
pub.publish(cv_ptr->toImageMsg()); 
pubVisData.publish(msgVisPointsArray); 
msgVisPointsArray.markerData.clear(); 
} 

Эта программа распознает маркер с определенным Id! Я хочу использовать вторую программу, используя этот конкретный маркер в качестве ввода

Лучший способ сделать это?

+1

Вы должны прочитать * interprocess communication *. – juanchopanza

+0

У вас есть много вариантов в зависимости от вашей ОС, но не тонны кросс-платформенных методов. Я часто использую сокеты для связи между моими программами. – wizebin

+0

Я использую ubuntu 12.04 с ros hydro –

ответ

0

Если вы находитесь в системе unix/linux, вы можете передавать выходные данные одной программы другой с помощью pipe. Например

ls | wc -l 

ls печатает имена всех файлов в каталоге и wc -l принимает этот вывод и подсчитывает количество строк.

Чтобы принять трубку, ваша приемная программа должна быть прочитана из stdin. Например

std::string s; 
while (std::cin >> s) { 
    // do something with the string 
} 
+0

если строка, которую я должен передавать, автоматически меняет каждые 5 секунд? этот способ также автоматически обновит строку? –

+0

Если первая программа печатает строку каждые 5 секунд, программа, получающая канал, увидит новую строку в stdin каждые 5 секунд. – SU3

1

Приведенный ниже код будет работать отдельный процесс, определенный с помощью команды command и трубы на выходе stdout к строке M.

FILE* p = popen("command", "r"); 
if (!p) 
    return 1; 

char buf[100]; 
std::string M; 
while (!feof(p)) { 
    if (fgets(buf, 100, p) != NULL) 
    M += buf; 
} 
pclose(p); 

Если вы знаете, что command будет печатать все, что вам нужно на стандартный вывод, это должен делать то, что вы хотите. Обязательно включает в себя:

#include <string> 
#include <iostream> 
#include <stdio.h> 

EDIT:

После того, как вы разместили код другого процесса, то мне ясно, что вы приближаетесь проблема неправильно. Вы используете ROS, который в основном представляет собой промежуточное программное обеспечение, облегчающее межпроцессное взаимодействие в роботизированных приложениях. Сама ROS предоставляет инструменты для выполнения обмена строк между процессами, и вы должны использовать ROS для выполнения этого обмена. Вы используете темы для обмена данными, и в вашем случае один процесс должен подписаться на тему, а другой должен опубликовать ее. Процесс получения будет получать обратный вызов всякий раз, когда строка публикуется и будет иметь доступ к данным. Отъезд http://wiki.ros.org/Topics для получения дополнительной информации по темам в ROS.

+0

ОК, может быть, я забыл думать: D есть ли какие-то проблемы, если строка ввода меняется каждые 5 секунд? или ваш код автоматически обновляет строку? –

+0

Ну, я не уверен, что понимаю, что вы имеете в виду. Вы можете просто запустить внешний процесс несколько раз. Я думаю, вы должны уточнить, что вы подразумеваете под другим файлом cpp. –

+0

ok теперь я переписываю вопрос, добавляя другой cpp, который должен дать мне вывод –