Marcello Chiurazzi
Marcello Chiurazzi

Reputation: 43

Connection between cpp files

How I can pass a variable from a C++ program to another? the variable that I need to pass is a string. This is the C++ file in which I have to send the string:

#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")
  .........

In this program I decide what string M is, but I want that this M comes from the output of another cpp file that obviously has to give a string as output.

this is the c++ that has to send me a string:

#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();
}

This program recognize a marker with a specific Id! i want to use the second program using this specific marker as input

The best way to do this?

Upvotes: 0

Views: 324

Answers (2)

Andrzej Pronobis
Andrzej Pronobis

Reputation: 36096

The code below will run a separate process specified by the command command and pipe the output of stdout to the string 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);

If you know that command will print whatever you need on its standard output, this should do what you want. Required includes:

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

EDIT:

After you posted the code of the other process, it is clear to me that you are approaching the problem wrong. You are using ROS which is basically a middleware facilitating interprocess communication in robotic applications. ROS itself provides the tools for performing the exchange of strings between the processes and you should use ROS to perform that exchange. You use topics to exchange data and in your case, one process should subscribe to a topic while another should publish to it. The receiving process will receive a callback whenever string is being published and will have access to the data. Check out http://wiki.ros.org/Topics for more info about topics in ROS.

Upvotes: 1

SU3
SU3

Reputation: 5387

If you are on a unix/linux system, you can pass output of one program to another with a pipe. For example

ls | wc -l

ls prints the names of all the files in a directory and wc -l takes that output and counts the number of lines.

To accept a pipe, your receiving program needs to read from stdin. For example

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

Upvotes: 0

Related Questions