Skip to content

Commit 9e326e0

Browse files
committed
Improved the accuracy of quick scene estimate
Add an ability to costumize the gravity compensation for small objects using ros param. Automatically load missing object models when these objects are detected
1 parent a2cc9bb commit 9e326e0

8 files changed

+194
-68
lines changed

include/physics_world_parameters.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
#define SCALING 1000
99
#define GRAVITY_MAGNITUDE 9.807
10-
#define GRAVITY_SCALE_COMPENSATION 2
11-
#define SCALED_GRAVITY_MAGNITUDE SCALING * GRAVITY_MAGNITUDE / GRAVITY_SCALE_COMPENSATION
10+
static int GRAVITY_SCALE_COMPENSATION = 3;
11+
static double SCALED_GRAVITY_MAGNITUDE = SCALING * GRAVITY_MAGNITUDE / GRAVITY_SCALE_COMPENSATION;
1212

1313
enum SimulationMode {
1414
// RUN THE SIMULATION UNTIL THE NUMBER OF SIMULATION STEP IS REACHED OR ALL OBJECT IS IN DEACTIVATED STATE

include/scene_data_forces.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define SCENE_PHYSICS_DATA_FORCES
33

44
#include <iostream>
5+
6+
#include <boost/filesystem.hpp>
57
#include <btBulletDynamicsCommon.h>
68

79
#include <pcl/point_types.h>
@@ -40,14 +42,17 @@ class FeedbackDataForcesGenerator
4042

4143
// Input sampled point cloud from the mesh
4244
void setModelCloud(const PointCloudXYZPtr mesh_surface_sampled_cloud, const std::string &model_name);
45+
bool setModelDirectory(const std::string &model_directory);
46+
bool setModelCloud(const std::string &model_name);
47+
4348
void setForcesParameter(const btScalar &forces_magnitude_per_point, const btScalar &max_point_distance_threshold);
4449
void resetCachedIcpResult();
4550
void removeCachedIcpResult(const std::string &object_id);
4651
void updateCachedIcpResultMap(const btRigidBody &object,
4752
const std::string &model_name);
4853
void manualSetCachedIcpResultMapFromPose(const btRigidBody &object,
4954
const std::string &model_name);
50-
double getIcpConfidenceResult(const std::string &model_name, const btTransform &object_pose) const;
55+
double getIcpConfidenceResult(const std::string &model_name, const btTransform &object_pose);
5156

5257
PointCloudXYZPtr getTransformedObjectCloud(const std::string &model_name, const btTransform &object_real_pose) const;
5358

@@ -80,6 +85,8 @@ class FeedbackDataForcesGenerator
8085
PointCloudXYZPtr getTransformedObjectCloud(const btTransform &object_pose,
8186
const std::string &model_name, btTransform &object_real_pose) const;
8287

88+
std::string model_directory_;
89+
8390
bool have_scene_data_;
8491
PointCloudXYZPtr scene_data_;
8592
pcl::KdTreeFLANN<pcl::PointXYZ> scene_data_tree_;

launch/ros_scene.launch

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@
1313
<arg name="debug" default="false"/>
1414
<arg name="load_table" default="true"/>
1515
<arg name="table_location" default="$(find sequential_scene_parsing)/mesh/table.pcd"/>
16-
<arg name="render_scene" default="true" />
16+
<arg name="render_scene" default="true"/>
1717
<arg name="objransac_model_directory" default="$(find sequential_scene_parsing)/mesh"/>
18-
<arg name="objransac_model_names" default="block,cube" />
18+
<arg name="objransac_model_names" default="block,cube"/>
1919

2020
<arg name="data_forces_magnitude" default="0.25"/>
2121
<arg name="data_forces_max_distance" default="0.015"/>
2222

2323
<arg name="best_hypothesis_only" default="false"/>
24+
<arg name="small_obj_g_comp" default="3"/>
2425

2526
<node pkg="sequential_scene_parsing" type="sequential_scene_ros" name="sequential_scene_ros"
2627
output="screen"
2728
>
2829
<!-- sequential_scene_ros common Node arg pass -->
30+
<param name="small_obj_g_comp" type="int" value="$(arg small_obj_g_comp)"/>
31+
2932
<param name="background_pcl2_topic" type="str" value="$(arg background_pcl2_topic)" />
3033
<param name="scene_pcl2_topic" type="str" value="$(arg scene_pcl2_topic)" />
3134

@@ -50,7 +53,6 @@
5053
<param name="objransac_model_directory" type="str" value="$(arg objransac_model_directory)"/>
5154
<param name="objransac_model_names" type="str" value="$(arg objransac_model_names)"/>
5255

53-
5456
<!-- objectDatabase -->
5557
<rosparam command="load" file="$(find sequential_scene_parsing)/mesh/object_property_database.yaml" />
5658

script/publish_groundtruth_hypotheses.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def __init__(self,folder_name):
8585
y_symmetries = 1, y_rotation = 360*deg_to_rad,
8686
z_symmetries = 1, z_rotation = 360*deg_to_rad)
8787

88+
self.object_id_by_frame_ = dict()
89+
objects_in_one_frame = []
8890
for row in groundtruth_tf_list:
8991
# print len(row)
9092
if len(row) == 10:
@@ -99,6 +101,7 @@ def __init__(self,folder_name):
99101
## NEED TO ADD THE TIME STAMP WHEN PUBLISHING
100102

101103
self.detected_object_in_frame.append((current_frame_list_of_objects,current_frame_tf_accumulator))
104+
self.object_id_by_frame_[current_frame] = objects_in_one_frame
102105
current_frame_tf_accumulator = []
103106
current_frame_list_of_objects = DetectedObjectList()
104107
current_frame = int(frame_num)
@@ -114,6 +117,9 @@ def __init__(self,folder_name):
114117

115118
det_object.id = "objects/%s/%s"%(object_type,obj_index)
116119
det_object.object_class = object_type
120+
121+
objects_in_one_frame.append(det_object.id)
122+
117123
if object_type in obj_symmetry_dict:
118124
det_object.symmetry = obj_symmetry_dict[object_type]
119125
else:
@@ -136,11 +142,11 @@ def __init__(self,folder_name):
136142
current_frame_list_of_objects.header.frame_id = ref_frame
137143

138144
self.detected_object_in_frame.append((current_frame_list_of_objects,current_frame_tf_accumulator))
145+
self.object_id_by_frame_[current_frame] = objects_in_one_frame
139146
current_frame_tf_accumulator = []
140147
current_frame_list_of_objects = DetectedObjectList()
141148
current_frame = int(frame_num)
142149

143-
144150
self.saved_cloud = list()
145151
cloud_dir = os.path.join(test_dir_path,'seg_cloud')
146152

@@ -245,15 +251,17 @@ def publish_detected_object_msgs(self,req):
245251
# print "Obj list published"
246252
rospy.sleep(0.3)
247253

248-
self.hypo_obj_pub.publish(self.hypothesis_generator(current_frame_tf_accumulator))
254+
# self.hypo_obj_pub.publish(self.hypothesis_generator(current_frame_tf_accumulator))
249255
# print "all data published"
250256
self.seq += 1
251257
return []
252258

253259
def evaluate_scene_result(self,data):
254260
obj_list_to_publish, current_frame_tf_accumulator = self.detected_object_in_frame[self.frame_to_publish]
255-
for detected_object in obj_list_to_publish.objects:
256-
object_id = detected_object.id
261+
available_objects = self.object_id_by_frame_[self.frame_to_publish]
262+
for detected_object in available_objects: # obj_list_to_publish.objects:
263+
# object_id = detected_object.id
264+
object_id = detected_object
257265
result_id = 'scene/'+object_id
258266
transform = [-1]*7
259267
self.listener.waitForTransform(object_id,result_id,rospy.Time(), rospy.Duration(1.0))

src/ros_sequential_scene_parsing.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ void RosSceneHypothesisAssessor::setNodeHandle(const ros::NodeHandle &nh)
6464
nh.param("data_forces_max_distance",data_forces_max_distance,0.01);
6565

6666
nh.param("best_hypothesis_only",best_hypothesis_only_,false);
67+
nh.param("small_obj_g_comp",GRAVITY_SCALE_COMPENSATION,3);
68+
SCALED_GRAVITY_MAGNITUDE = SCALING * GRAVITY_MAGNITUDE / GRAVITY_SCALE_COMPENSATION;
6769

6870
if (load_table){
6971
nh.param("table_location",background_location,std::string(""));

src/scene_data_forces.cpp

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,51 @@ FeedbackDataForcesGenerator::FeedbackDataForcesGenerator() :
2121
icp_.setMaximumIterations(max_icp_iteration_);
2222
}
2323

24+
bool FeedbackDataForcesGenerator::setModelDirectory(const std::string &model_directory)
25+
{
26+
namespace fs = boost::filesystem;
27+
fs::path directory_path(model_directory);
28+
if (fs::is_directory(directory_path))
29+
{
30+
model_directory_ = model_directory;
31+
return true;
32+
}
33+
else
34+
{
35+
std::cerr << "Error, object model directory: " << model_directory << " does not exist.\n";
36+
return false;
37+
}
38+
}
39+
40+
bool FeedbackDataForcesGenerator::setModelCloud(const std::string &model_name)
41+
{
42+
namespace fs = boost::filesystem;
43+
fs::path directory_path(model_directory_);
44+
fs::path model_path = directory_path / model_name;
45+
model_path.replace_extension(".pcd");
46+
47+
if (fs::exists(model_path))
48+
{
49+
pcl::PCDReader reader;
50+
pcl::PointCloud<pcl::PointXYZ>::Ptr surface_cloud(new pcl::PointCloud<pcl::PointXYZ>());
51+
if (reader.read(model_path.string(),*surface_cloud) == 0)
52+
{
53+
this->setModelCloud(surface_cloud, model_name);
54+
std::cerr << "Model point cloud loaded successfully\n";
55+
return true;
56+
}
57+
else
58+
{
59+
std::cerr << "Failed to load " << model_name << " model point cloud\n";
60+
}
61+
}
62+
else
63+
{
64+
std::cerr << "Error: '" << model_path << "' does not exist.\n";
65+
}
66+
return false;
67+
}
68+
2469
void FeedbackDataForcesGenerator::setFeedbackForceMode(int mode)
2570
{
2671
force_data_model_ = mode;
@@ -97,19 +142,22 @@ void FeedbackDataForcesGenerator::updateCachedIcpResultMap(const PointCloudXYZPt
97142
icp_result_confidence_map_[object_id] = getIcpConfidenceResult(icp_result);
98143
}
99144

100-
double FeedbackDataForcesGenerator::getIcpConfidenceResult(const std::string &model_name, const btTransform &object_pose) const
145+
double FeedbackDataForcesGenerator::getIcpConfidenceResult(const std::string &model_name, const btTransform &object_pose)
101146
{
102147
btTransform dummy_transform;
103-
if (keyExistInConstantMap(model_name,model_cloud_map_))
104-
{
105-
PointCloudXYZPtr dummy = getTransformedObjectCloud(object_pose, model_name, dummy_transform);
106-
return getIcpConfidenceResult(dummy);
107-
}
108-
else
148+
if (!keyExistInConstantMap(model_name,model_cloud_map_))
109149
{
110150
std::cerr << "ERROR, model name '" << model_name << "' does not exist in the database.\n";
111-
return 0;
151+
std::cerr << "Attempting to load Unrecognized model\n";
152+
bool load_success = this->setModelCloud(model_name);
153+
if (!load_success)
154+
{
155+
return 0;
156+
}
112157
}
158+
159+
PointCloudXYZPtr dummy = getTransformedObjectCloud(object_pose, model_name, dummy_transform);
160+
return getIcpConfidenceResult(dummy);
113161
}
114162

115163
void FeedbackDataForcesGenerator::updateCachedIcpResultMap(const btRigidBody &object,

src/sequential_scene_hypothesis.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ bool SequentialSceneHypothesis::checkObjectReplaced(const std::string &model_nam
209209
{
210210
// use AABB to check if the original object volume has been occupied by something else
211211
// TODO: IMPLEMENT THIS!!
212+
// use bullet contactTest;
212213
return false;
213214
}
214215

@@ -246,32 +247,67 @@ std::map<std::string, AdditionalHypotheses> SequentialSceneHypothesis::generateO
246247

247248
std::map<std::string, std::string> &object_label_class_map = this->previous_scene_observation_.object_label_class_map_;
248249

250+
for (std::vector<std::string>::const_iterator it = change_in_scene.perturbed_objects_.begin();
251+
it != change_in_scene.perturbed_objects_.end(); ++it)
252+
{
253+
const std::string &object_id = *it;
254+
const vertex_t &prev_obj_vertex = prev_vertex_map[object_id];
255+
const btTransform &prev_transform = previous_best_scene_hypothesis.scene_support_graph_[prev_obj_vertex].object_pose_;
256+
257+
const vertex_t &cur_obj_vertex = cur_vertex_map[object_id];
258+
const std::size_t dist = current_best_data_scene_structure_.scene_support_graph_[cur_obj_vertex].distance_to_ground_;
259+
const btTransform &cur_transform = current_best_data_scene_structure_.scene_support_graph_[cur_obj_vertex].object_pose_;
260+
261+
const std::string &model_name = object_label_class_map[object_id];
262+
263+
std::cerr << object_id << std::endl;
264+
265+
double current_data_confidence = this->data_probability_check_->getIcpConfidenceResult(model_name, cur_transform);
266+
// use previous best pose if the confidence difference between current pose and previous pose is small
267+
if (current_data_confidence < 0.05 || this->judgeHypothesis(model_name,prev_transform,0.7*current_data_confidence))
268+
{
269+
std::cerr << "Retained previous pose\n";
270+
object_pose_by_dist[dist][object_id] = prev_transform;
271+
}
272+
else
273+
{
274+
std::cerr << "Use current pose\n";
275+
object_pose_by_dist[dist][object_id] = cur_transform;
276+
}
277+
}
278+
249279
for (std::vector<std::string>::const_iterator it = change_in_scene.support_retained_object_.begin();
250280
it != change_in_scene.support_retained_object_.end(); ++it)
251281
{
252282
// add the object pose by distance information for support retained objects
253283
const std::string &object_id = *it;
254284
const vertex_t &obj_vertex = prev_vertex_map[object_id];
255-
285+
256286
// the object_pose_by_dist starts at 0 (already excludes background)
257-
const std::size_t dist = previous_best_scene_hypothesis.scene_support_graph_[obj_vertex].distance_to_ground_ - 1;
287+
const std::size_t prev_dist = previous_best_scene_hypothesis.scene_support_graph_[obj_vertex].distance_to_ground_;
288+
const std::size_t dist = prev_dist > 1 && prev_dist <= object_pose_by_dist.size()
289+
? prev_dist - 1 : disconnected_object_dist;
290+
258291
const btTransform &prev_transform = previous_best_scene_hypothesis.scene_support_graph_[obj_vertex].object_pose_;
259292

260293
const std::string &model_name = object_label_class_map[object_id];
261294

262295
const vertex_t &cur_obj_vertex = cur_vertex_map[object_id];
263296
const btTransform &cur_transform = current_best_data_scene_structure_.scene_support_graph_[cur_obj_vertex].object_pose_;
297+
298+
std::cerr << object_id << std::endl;
264299

265300
double current_data_confidence = this->data_probability_check_->getIcpConfidenceResult(model_name, cur_transform);
266-
267301
// use previous best pose if the confidence difference between current pose and previous pose is small
268302
if (current_data_confidence < 0.05 || this->judgeHypothesis(model_name,prev_transform,0.7*current_data_confidence))
269303
{
270-
object_pose_by_dist[dist][object_id] = prev_transform;
304+
std::cerr << "Retained previous pose\n";
305+
object_pose_by_dist[dist][object_id] = prev_transform;
271306
}
272307
else
273308
{
274-
object_pose_by_dist[dist][object_id] = cur_transform;
309+
std::cerr << "Use current pose\n";
310+
object_pose_by_dist[dist][object_id] = cur_transform;
275311
}
276312

277313
// add the child information of this object and move the optimization order of the child to its proper distance
@@ -310,10 +346,12 @@ std::map<std::string, AdditionalHypotheses> SequentialSceneHypothesis::generateO
310346
else
311347
{
312348
std::cerr << "Warning, found inconsistency of object " << *obj_it << " in current scene graph\n";
349+
continue;
313350
}
314351
}
315352
object_childs_map[object_id] = obj_child_tf_supported;
316353
}
354+
317355
if (additional_perturbed.size() > 0) result.insert(additional_perturbed.begin(),additional_perturbed.end());
318356
if (additional_static.size() > 0) result.insert(additional_static.begin(),additional_static.end());
319357
if (additional_support_retained.size() > 0) result.insert(additional_support_retained.begin(),additional_support_retained.end());
@@ -332,6 +370,7 @@ std::map<std::string, AdditionalHypotheses> SequentialSceneHypothesis::generateO
332370
result[it->first] = AdditionalHypotheses(it->second.first, object_pose_hypotheses, ADD_OBJECT);
333371
}
334372
}
373+
335374
return result;
336375
}
337376

0 commit comments

Comments
 (0)