I'm stuck with the following problem:
I have an occupancy grid based on information about the environment received from a camera plugged on my robot. Since the robot is supposed to move around in unknown territory, there is no "global costmap" in its original context. We use the information received from the camera as the "global costmap". Currently, the global costmap is configured as a static_layer that is linked to the base_link-frame (I need it to be a static_layer as it has multiple cost-values and only the static_layer with its "trinary_costmap"-parameter has the option to map intermediate cost_values range 0-255). Due to it is linked to the base_link-frame, it permanently moves along with the frame. But since the costmap is updated with a frequency of 2 occupancy grids per second, this permanent movement falsifies the costmap-information (since it's supposed to be a static map until the new occupancy grid gets published).
My idea was to create a new frame according to the ros tutorial for adding a new dynamic frame, which takes the current position of base_link and updates its position with a specific rate.
Therefore, my source-code looks like this:
int main(int argc, char** argv) {
ros::init(argc, argv, "path_segmentation_client"); // initialise ROS
ros::NodeHandle nh; // create NodeHandle for the node
ros::ServiceClient client = nh.serviceClient<path_detection_cnn::segmentation_to_occgrid>("segmentation_to_occgrid"); //create client for segmentation_to_occgrid-service
path_detection_cnn::segmentation_to_occgrid srv; //create service-instance
double rate; //Variable to store loop rate
nh.getParam("/path_segmentation_client/looprate", rate); //get loop-rate from parameters
ros::Rate r(rate); //apply loop-rate to ros
ros::Publisher map_pub = nh.advertise<nav_msgs::OccupancyGrid>("prediction_occ_grid",1000); //declare publisher for publishing occupancy grid
static tf2_ros::StaticTransformBroadcaster brs;
geometry_msgs::TransformStamped global_costmap_link;
global_costmap_link.header.stamp = ros::Time::now();
global_costmap_link.header.frame_id = "base_link";
global_costmap_link.child_frame_id = "global_costmap_link";
global_costmap_link.transform.translation.x = 0;
global_costmap_link.transform.translation.y = 0;
global_costmap_link.transform.translation.z = 0.0;
global_costmap_link.transform.rotation.x = 0;
global_costmap_link.transform.rotation.y = 0;
global_costmap_link.transform.rotation.z = 0;
global_costmap_link.transform.rotation.w = 1;
while(nh.ok()){
client.waitForExistence();
if (client.call(srv))
{
nav_msgs::OccupancyGrid occGrid = get_occupancy_grid(srv.response.topViewMsg); //convert topView to Occupancy Grid
map_pub.publish(occGrid); // publish occupancyGrid
brs.sendTransform(global_costmap_link); //update location of costmap_origin
r.sleep(); //sleep to keep loop rate
}
else
{
ROS_ERROR("Failed to call service segmentation_to_occgrid.");
}
}
return 0;
}
As you can see, I use a client-service-system to obtain data and convert it to an occupancy grid, creating a frame named "global_costmap_link" as a child of base_link and publishing the frame and the occupancy grid within the same rate. Doing so, the new "global_costmap_link"-frame unfortunately also keeps moving along with the base_link-frame instead of remaining at the position it was published and only move to the new position of base_link when it is re-published according to the rate.
Does anyone know how to fix this? Or does anyone have another approach on how to configure my costmap in a way that it moves along with the base_link-frame but delayed according to the given rate?
For more information, here is my global_costmap_param.yaml:
global_costmap:
global_frame: base_link
map_topic: "prediction_occ_grid"
update_frequency: 2.0
publish_frequency: 2.0
rolling_window: false
always_send_full_costmap: true
/move_base/global_costmap/static_layer/trinary_costmap: false
height: 26.9
width: 36.4
mode: scale
plugins:
- {name: static_layer, type: "costmap_2d::StaticLayer"}
I use the costmap2d-library on ROS Melodic.