cpp文件之间的连接

Connection between cpp files

本文关键字:连接 之间 文件 cpp      更新时间:2023-10-16

如何将变量从c++程序传递到另一个程序?我需要传递的变量是一个字符串。这是我必须发送字符串的c++文件:

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

在这个程序中,我决定了字符串M是什么,但是我希望这个M来自另一个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的标记!我想使用第二个程序使用这个特定的标记作为输入

最好的方法是什么?

下面的代码将运行由命令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>
编辑:

在你发布了另一个过程的代码之后,我很清楚你处理问题的方法是错误的。您正在使用ROS,它基本上是机器人应用程序中促进进程间通信的中间件。ROS本身提供了在进程之间执行字符串交换的工具,您应该使用ROS来执行该交换。您使用主题交换数据,在您的示例中,一个进程应该订阅主题,而另一个进程应该向主题发布。每当发布字符串时,接收进程将接收回调,并将访问数据。有关ROS主题的更多信息,请访问http://wiki.ros.org/Topics。

如果您在unix/linux系统上,您可以使用管道将一个程序的输出传递给另一个程序。例如

ls | wc -l

ls打印目录中所有文件的名称,wc -l获取该输出并计算行数。

要接受一个管道,你的接收程序需要从stdin中读取。例如

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