【发布时间】:2021-06-02 23:20:09
【问题描述】:
我正在尝试在 c++11 中创建一个 ROS 节点,该节点将获取存储在 json 文件中的坐标以将它们发布到特定的 rostopic(随附 json 文件供您查看结构)。
我决定创建一个名为“DroneTopic”的类对象,它将从 json 文件中读取日志,创建一个发布者对象,然后在其中发布。
我面临的主要问题是指针的使用。由于我正在使用的库中的 Json 类型(jsoncpp)是特殊类型(const signed int for ex),我必须使用指针来获取值并将其作为 int 传输到正确的属性。
我还使用此类对象的向量来更轻松地处理对象的数量,因为我一开始不知道我将要处理多少个 rostopic。
关于路点数量的类对象内部也会发生相同的情况。我所有的无人机对象都不会有相同数量的航点,这就是为什么我创建了一个结构向量 (x,y,z) 来处理不断变化的数字。
这是我的完整代码:
class DroneTopic
{
protected:
struct Waypoint{
int x,y,z;
};
std::string topicName;
ros::Publisher pub;
std::vector<Waypoint> waypoints;
public:
DroneTopic(std::string topic,ros::NodeHandle &nh)
{
topicName = topic;
pub = nh.advertise<geometry_msgs::Pose>(topicName,1000);
}
//Methodes
std::vector<Waypoint> read_logs(Json::Value &logs){
int nb_waypts = logs.size();
Json::Value *ptr;
Waypoint tmp {0,0,0};
for(int i=0; i < nb_waypts; i++){
ptr = &logs[i]["x"];
tmp.x = ptr->asInt();
ptr = &logs[i]["y"];
tmp.y = ptr->asInt();
ptr = &logs[i]["z"];
tmp.z = ptr->asInt();
waypoints.push_back(tmp);
std::cout << i << std::endl;
}
delete ptr;
ptr=NULL;
}
void publish_message()
{
for(int i = 0; i<waypoints.size();i++){
geometry_msgs::Pose msg;
msg.position.x=waypoints[i].x;
msg.position.y=waypoints[i].y;
msg.position.z=waypoints[i].z;
pub.publish(msg);
}
}
};
std::string filename;
int main(int argc, char **argv)
{
//Init ROS Node
ros::init(argc,argv,"mesa2drone");
ros::NodeHandle nh;
ROS_INFO_STREAM("MESA Node Up");
nh.param<std::string>("Json_File_Name", filename, "output");
std::string extension = ".json";
filename+=extension;
Json::Value logs;
std::ifstream jfile(filename);
jfile >> logs;
// Create vector of DroneTopic
std::vector<DroneTopic> drone;
drone.push_back(DroneTopic("test",nh));
int nb_drone = logs.size();
if(nb_drone > 0){
for(int i=1;i<=nb_drone;i++){
std::string j = std::to_string(i);
std::ostringstream flux;
flux << "intelaero_laserscan_" << j <<"/new_target";
std::string name = flux.str();
std::cout<< "ok_3" <<std::endl;
drone.push_back(DroneTopic(name,nh));
std::cout<< "ok_5" <<std::endl;
}
}
ros::Rate rate(1);
while(ros::ok())
{
for(int k=1; k<=nb_drone;k++)
{
std::cout<<"ok_6"<<std::endl;
std::string j = std::to_string(k);
drone[k].read_logs(logs[j]);
std::cout<<"ok_7"<<std::endl;
drone[k].publish_message();
std::cout<<"ok_8"<<std::endl;
}
//j++;
rate.sleep();
}
ros::shutdown();
return 0;
}
我使用(但为了清楚起见已删除)std::cout 标记来查看代码崩溃的位置,似乎它在这一行崩溃:
drone[k].read_logs(logs[j]);
它实际上从未脱离函数。它执行完整的“for-loop”,但由于某种原因我不明白它没有出来并给我这个错误:
Erreur de segmentation (core dumped)
据我所见,这与分配错误有关,但我检查了向量的大小,一切正常(或者我认为)。
任何帮助都将不胜感激,因为我已经为此苦苦挣扎了几天。
谢谢!
FIY:我使用的是 Linux Ubuntu 16、c++11(不是我的选择)。
PS:这是我正在使用的 json 文件
{
"1": [
{
"x": -2,
"y": 27.5,
"z": 20.0
},
{
"x": -2,
"y": 67.5,
"z": 12.0
},
{
"x": -2,
"y": 91.5,
"z": 11.5
},
{
"x": -2,
"y": 89.5,
"z": 9.5
},
{
"x": -2,
"y": 23.0,
"z": 17.0
},
{
"x": -2,
"y": 50.5,
"z": 1.5
},
{
"x": -2,
"y": 82.5,
"z": 5.5
},
{
"x": -2,
"y": 97.5,
"z": 21.0
}
],
"2": [
{
"x": -2,
"y": 82.5,
"z": 20.0
},
{
"x": -2,
"y": 64.0,
"z": 0.0
},
{
"x": -2,
"y": 160.5,
"z": 11.0
},
{
"x": -2,
"y": 85.5,
"z": 14.0
},
{
"x": -2,
"y": 132.0,
"z": 19.0
},
{
"x": -2,
"y": 146.0,
"z": 1.0
}
],
"3": [
{
"x": -2,
"y": 137.5,
"z": 20.0
},
{
"x": -2,
"y": 156.5,
"z": 17.5
},
{
"x": -2,
"y": 28.0,
"z": 4.0
},
{
"x": -2,
"y": 67.0,
"z": 15.0
},
{
"x": -2,
"y": 40.0,
"z": 9.5
},
{
"x": -2,
"y": 81.0,
"z": 5.0
},
{
"x": -2,
"y": 77.0,
"z": 0.0
}
]
}
【问题讨论】:
-
在 "crash" 之前在该行停止时,您在调试器中观察到了什么?当时
k和j的值是多少?恐怕您正在尝试使用一些已经悬而未决的东西,但是如果没有看到minimal reproducible example(强调minimal),这很难说。 -
在您的
read_logs函数中,delete ptr感觉不对。除了您只删除分配给ptr的last 赋值之外,指针指向的对象还不是您自己用new创建的。 -
你甚至不需要
ptr。为什么不使用例如tmp.x = logs[i]["x"].asInt()? -
嗨,@Someprogrammerdude 我不能直接使用你建议的 Json::Value 类型不仅仅是一个“int”,而是一个“const signed int”或类似的东西。错误会告诉我它不能将 const signed int 放入 int var。
-
int与signed int相同。而且你总是可以复制一个常量值(到一个非常量变量,这就是从函数返回常量值没有意义的原因)。
标签: c++ c++11 pointers stdvector