Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TerrainSimplification and TerrainSimplificationRos packages #5

Open
wants to merge 64 commits into
base: master
Choose a base branch
from

Conversation

oliwiermelon
Copy link

@oliwiermelon oliwiermelon commented Jan 17, 2021

Hi @benoit-robotics,
Can you please review the code of both TerrainSimplification and TerrainSimplificationRos packages.
Instructions on how to run the application are in the README.

@benoit-robotics
Copy link

I will review it later this week


bool
TerrainSimplificationRos::readParameters() {
if (!ros_nh_.getParam("/terrain_simplification_ros_node/topic_elevation_map", topic_elevation_map_)){
Copy link

@benoit-robotics benoit-robotics Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getParam("topic_elevation_map") should work ? Same comment for all the getParam calls

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use ros::NodeHandle node_handle("~"); and the parameter is currently defined in the main .launch file. What method do you recommend? Overall, It is not the most useful as you cannot change the topic without restarting the node.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need to specify the name of the node

ros_nh_.getParam("topic_elevation_map", topic_elevation_map_)

double TerrainSimplificationRos::getTraversability(
const Eigen::Vector2d& location,
bool& is_inside) {
TerrainSimplification::getValueAtPosition("traversability", location, is_inside);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing return statement ?

k = cv::Mat::zeros(k_size_, k_size_, CV_64F);
k.row((int)(k_size_-1)/2) = cv::getGaussianKernel(k_size_, -1, CV_64F).t();
double yaw = getRobotYaw();
cv::warpAffine(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird formatting

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it is impossible to understand if it is in-line because of one of the inputs being cv::getRotationMatrix2D(). Should I:

  • keep it, or
  • have everything in a single line, or
  • put cv::getRotationMatrix2D()on a separate line, or
  • compute cv::getRotationMatrix2D() before cv::warpAffine()?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can keep it, or put the arguments in two or three lines


double
TerrainSimplification::getRobotYaw() {
mutex_state_.lock();
Copy link

@benoit-robotics benoit-robotics Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of locking and unlocking a mutex at the end of a method, you can use this : http://www.cplusplus.com/reference/mutex/lock_guard/


TerrainSimplification::TerrainSimplification ()
: thread_loop_(true),
thread_run_(&TerrainSimplification::run, this) {
Copy link

@benoit-robotics benoit-robotics Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I understand why you need to run the gridmap simplification in a new thread. Why don't you just simplify the gridmap in the main thread when a new gridmap is set ?

Copy link
Author

@oliwiermelon oliwiermelon Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the elevation map is very large (6 m x 6 m) but slow to update, this allows me to compute and publish a submap at any (achievable) rate. The main need arises as a result of the computation being dependent on the orientation of the robot. In addition, it gives me the ability to visualize it at a higher frequency (it is not limited by how long the filters take as I don't wait for them to be finished computing).

@mauricefallon
Copy link
Contributor

@oliwiermelon : could you put some visualisations from group meetings into this PR.
People in the Cerberus team might be interested in this capability.

Copy link
Member

@wxmerkt wxmerkt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few comments inline however the biggest changes are architectural:

  1. rosparams should be loaded in the launch file and not via a system call in the node
  2. to do timing/cron-job like, I don't think a service call node is the right solution unless this is explicitly required for integration - having a parameter publish_frequency or process_every_n would do the job

I'll take the rest up via DM in Slack

@@ -0,0 +1,7 @@
![A gif demonstrating the use of terrain simplification as a base-motion-constraint, shown at 5x speed.](https://github.com/ori-drs/plane_seg/blob/add-terrain-simplification/terrain_simplification/terrain-simplification_base-motion-constraint_5x-speed.gif)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These links will no longer work after this branch has been merged and deleted

@@ -0,0 +1,30 @@
# Description
See https://wiki.oxfordrobots.com/display/~oliwier/2021/01/07/Terrain+Simplification
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal link

@@ -0,0 +1,23 @@
#include "ros/ros.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use < and >

{
nh.param("/terrain_simplification_ros_service_caller/rate", rate, 10.);
ros_client_pub.call(req,res);
ros::Rate r(rate);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull this line out of the while

ros::ServiceClient ros_client_pub
= nh.serviceClient<std_srvs::Empty>("/terrain_simplification/pub");
std_srvs::Empty::Request req;
std_srvs::Empty::Response res;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sys_rtrn = system(cmd.c_str());
}
catch (std::exception& e) {
ROS_ERROR_STREAM("Wrong path to configuration (config) file!");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not concatenate e.what() to the message?

<depend>grid_map_filters</depend>
<depend>terrain_simplification</depend>
<exec_depend>rviz</exec_depend>
<exec_depend>rqt_bag</exec_depend>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you have this here. Ideally, we'd like to avoid heavy UI dependencies listed in the package.xml unless necessary (imagine installing this on a robot and running rosdep install --from-paths ./ -iry - this will pull in all of Qt etc.)

TerrainSimplificationRos::loadConfigFile() {
try {
// load standard config
std::string cmd = "rosparam load " + ros::package::getPath("terrain_simplification_ros") + "/config/config.yaml";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is odd (I have seen similar in original towr). Just use a rosparam load in the launch file instead?


// Gridmaps' parameters
Eigen::Vector2d map_size_; ///< size of the submap
int k_size_ = 51; ///< size of the kernel (for the directional Gaussian blur filter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly should be exposed as a rosparam since it may depend on the grid map resolution

```
These can be set and re-read using:
```
rosservice call /terrain_simplification/read
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you use this actively? Some of the information read-in via readParameters wont be changeable during runtime... since you already set up subscriptions etc. (which could be remapped instead)

wxmerkt and others added 18 commits February 24, 2021 11:33
Removes hard-coded assumptions about a 2cm elevation map grid resolution
…layer from map_simplified_wo_traversability
…rom to prevent the issue of the map being resized
…ilter_chain header

TODO: remove filter chain from TerrainSimplification
…ters_drs for inpainting

NOTE: pull changes in grid_map_filters_drs
TODO: remove filter_chain from TerrainSimplification
<depend>grid_map_core</depend>
<depend>grid_map_cv</depend>
<depend>grid_map_filters</depend>
<depend>grid_map_filters_drs</depend>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this is a private repository. I understand this PR has been stale for a while and we need to clean it up at some point - but adding a private dependency for a public repository won't work. One way is to move the runtime config + launch file to the user repository and not use it by default in the config included here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree; I admit, I have not thought about it.

If we do what you suggest, can a filter from grid_map_filters_drs still be loaded by filter_chain even if the repository is not added as a dependency? If so, I am happy to include the specific config.yaml and .launch files in e.g. RHECALL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my knowledge, yes (the dependencies need to be at the level of the package that has the launch file / config), the point of using pluginlib is to be able to split packages and load plugins (here filters) dynamically

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will proceed as you suggested.

Something to bear in mind is that we will need to revisit the same problem when we make RHECALL publicly available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's cross that bridge when we get to it :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants