RViz Panel: How not to freeze RViz?
Hey there,
I have written a C++ RViz custom panel. The implementation roughly follows this example link.
The panel subscribe to a specific topic PointStamped type, and fills a list that gets displayed inside the panel as x and y coordinates.
Now, I've created a push button and implemented an actionlib move_base
goal function. The purpose is, the robot to go from one point to another. The problem is while i succesfully send the goals, RViz Visualization is blocked/freezed until the move is complete probably because ac.waitForResult()
is a blocking function.
How can i overcome this and let RViz keep visualizing robot's position while the robot moves to a point, get the result and then move to another point in the list. What i was thinking is probably about blocking GUI thread, so i good idead proably is to spin a new thread, but how can i accomplish this? Correct me. if I am wrong, and please if you need more info just let me know.
Here is a block of code that i am using right now and is blocking:
void Waypoints::moveTo() {
//tell the action client that we want to spin a thread by default
MoveBaseClient ac("move_base",true);
//wait for the action server to come up
while(!ac.waitForServer(ros::Duration(5.0))){
ROS_INFO("Waiting for the move_base action server to come up");
}
ROS_INFO("Move_base action server has come up");
move_base_msgs::MoveBaseGoal goal;
for (size_t x = 0; x < mBestPathNodes.size() - 1; x++) {
// we'll send a goal to the robot to move 1 meter forward
goal.target_pose.header.frame_id = "map";
goal.target_pose.header.stamp = ros::Time::now();
goal.target_pose.pose.position.x = mWaypoints[mBestPathNodes[x]].point.x;
goal.target_pose.pose.position.y = mWaypoints[mBestPathNodes[x]].point.y;
goal.target_pose.pose.orientation.w = 1.0;
ROS_INFO("Sending goal");
ac.sendGoal(goal);
ac.waitForResult();
bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0));
if (finished_before_timeout)
{
actionlib::SimpleClientGoalState state = ac.getState();
ROS_INFO("Action finished: %s",state.toString().c_str());
}
else
ROS_INFO("Action did not finish before the time out.");
}