void ViewerTest::SetViewer(OpenRAVE::EnvironmentBasePtr &penv, const std::string &viewername) { OpenRAVE::ViewerBasePtr viewer = OpenRAVE::RaveCreateViewer(penv, viewername); BOOST_ASSERT(!!viewer); // attach it to the environment: penv->Add(viewer); // finally call the viewer's infinite loop (this is why a separate thread is needed) bool showgui = true; viewer->main(showgui); }
// this method is copied from OctomapServer.cpp and modified void OctomapInterface::insertScan(const tf::Point& sensorOriginTf, const PCLPointCloud& ground, const PCLPointCloud& nonground){ octomap::point3d sensorOrigin = octomap::pointTfToOctomap(sensorOriginTf); if (!m_octree->coordToKeyChecked(sensorOrigin, m_updateBBXMin) || !m_octree->coordToKeyChecked(sensorOrigin, m_updateBBXMax)) { ROS_ERROR_STREAM("Could not generate Key for origin "<<sensorOrigin); } // // add mask information to the point cloud // OpenRAVE::EnvironmentBasePtr penv = GetEnv(); // create a vector of masked bodies std::vector<OpenRAVE::KinBodyPtr > maskedBodies; { boost::mutex::scoped_lock(m_maskedObjectsMutex); for (std::vector<std::string >::const_iterator o_it = m_maskedObjects.begin(); o_it != m_maskedObjects.end(); o_it++) { KinBodyPtr pbody = penv->GetKinBody(*o_it); if (pbody.get() != NULL) { maskedBodies.push_back( pbody ); } } } int numBodies = maskedBodies.size(); // instead of direct scan insertion, compute update to filter ground: octomap::KeySet free_cells, occupied_cells; // insert ground points only as free: for (PCLPointCloud::const_iterator it = ground.begin(); it != ground.end(); ++it){ octomap::point3d point(it->x, it->y, it->z); // maxrange check if ((m_maxRange > 0.0) && ((point - sensorOrigin).norm() > m_maxRange) ) { point = sensorOrigin + (point - sensorOrigin).normalized() * m_maxRange; } // only clear space (ground points) if (m_octree->computeRayKeys(sensorOrigin, point, m_keyRay)){ free_cells.insert(m_keyRay.begin(), m_keyRay.end()); } octomap::OcTreeKey endKey; if (m_octree->coordToKeyChecked(point, endKey)){ updateMinKey(endKey, m_updateBBXMin); updateMaxKey(endKey, m_updateBBXMax); } else{ ROS_ERROR_STREAM("Could not generate Key for endpoint "<<point); } } penv->Add(m_sphere, true); OpenRAVE::Transform tr; // all other points: free on ray, occupied on endpoint: for (PCLPointCloud::const_iterator it = nonground.begin(); it != nonground.end(); ++it){ octomap::point3d point(it->x, it->y, it->z); tr.trans.x = it->x; tr.trans.y = it->y; tr.trans.z = it->z; m_sphere->SetTransform(tr); bool maskedHit = false; for (int b_idx = 0; b_idx < numBodies; b_idx++) { if (penv->CheckCollision(maskedBodies[b_idx], m_sphere)) { maskedHit = true; break; } } if (maskedHit) { // free cells if (m_octree->computeRayKeys(sensorOrigin, point, m_keyRay)){ free_cells.insert(m_keyRay.begin(), m_keyRay.end()); } } else if ((m_maxRange < 0.0) || ((point - sensorOrigin).norm() <= m_maxRange) ) { // maxrange check // free cells if (m_octree->computeRayKeys(sensorOrigin, point, m_keyRay)){ free_cells.insert(m_keyRay.begin(), m_keyRay.end()); } // occupied endpoint octomap::OcTreeKey key; if (m_octree->coordToKeyChecked(point, key)){ occupied_cells.insert(key); updateMinKey(key, m_updateBBXMin); updateMaxKey(key, m_updateBBXMax); } } else {// ray longer than maxrange:; octomap::point3d new_end = sensorOrigin + (point - sensorOrigin).normalized() * m_maxRange; if (m_octree->computeRayKeys(sensorOrigin, new_end, m_keyRay)){ free_cells.insert(m_keyRay.begin(), m_keyRay.end()); octomap::OcTreeKey endKey; if (m_octree->coordToKeyChecked(new_end, endKey)){ updateMinKey(endKey, m_updateBBXMin); updateMaxKey(endKey, m_updateBBXMax); } else{ ROS_ERROR_STREAM("Could not generate Key for endpoint "<<new_end); } } } } penv->Remove(m_sphere); // mark free cells only if not seen occupied in this cloud for(octomap::KeySet::iterator it = free_cells.begin(), end=free_cells.end(); it!= end; ++it){ if (occupied_cells.find(*it) == occupied_cells.end()){ m_octree->updateNode(*it, false); } } // now mark all occupied cells: for (octomap::KeySet::iterator it = occupied_cells.begin(), end=free_cells.end(); it!= end; it++) { m_octree->updateNode(*it, true); } // TODO: eval lazy+updateInner vs. proper insertion // non-lazy by default (updateInnerOccupancy() too slow for large maps) //m_octree->updateInnerOccupancy(); octomap::point3d minPt, maxPt; ROS_DEBUG_STREAM("Bounding box keys (before): " << m_updateBBXMin[0] << " " <<m_updateBBXMin[1] << " " << m_updateBBXMin[2] << " / " <<m_updateBBXMax[0] << " "<<m_updateBBXMax[1] << " "<< m_updateBBXMax[2]); // TODO: snap max / min keys to larger voxels by m_maxTreeDepth // if (m_maxTreeDepth < 16) // { // OcTreeKey tmpMin = getIndexKey(m_updateBBXMin, m_maxTreeDepth); // this should give us the first key at depth m_maxTreeDepth that is smaller or equal to m_updateBBXMin (i.e. lower left in 2D grid coordinates) // OcTreeKey tmpMax = getIndexKey(m_updateBBXMax, m_maxTreeDepth); // see above, now add something to find upper right // tmpMax[0]+= m_octree->getNodeSize( m_maxTreeDepth ) - 1; // tmpMax[1]+= m_octree->getNodeSize( m_maxTreeDepth ) - 1; // tmpMax[2]+= m_octree->getNodeSize( m_maxTreeDepth ) - 1; // m_updateBBXMin = tmpMin; // m_updateBBXMax = tmpMax; // } // TODO: we could also limit the bbx to be within the map bounds here (see publishing check) minPt = m_octree->keyToCoord(m_updateBBXMin); maxPt = m_octree->keyToCoord(m_updateBBXMax); ROS_DEBUG_STREAM("Updated area bounding box: "<< minPt << " - "<<maxPt); ROS_DEBUG_STREAM("Bounding box keys (after): " << m_updateBBXMin[0] << " " <<m_updateBBXMin[1] << " " << m_updateBBXMin[2] << " / " <<m_updateBBXMax[0] << " "<<m_updateBBXMax[1] << " "<< m_updateBBXMax[2]); if (m_compressMap) m_octree->prune(); }
TEST_F(FeatureConstraintsTest, constrainConfiguration) { // setting up environment and robot OpenRAVE::RaveInitialize(); OpenRAVE::EnvironmentBasePtr env = OpenRAVE::RaveCreateEnvironment(); OpenRAVE::RobotBasePtr herb = env->ReadRobotXMLFile("robots/herb2_padded_nosensors.robot.xml"); env->Add(herb); OpenRAVE::RobotBase::ManipulatorPtr right_arm; std::vector<OpenRAVE::RobotBase::ManipulatorPtr> herb_manipulators = herb->GetManipulators(); for (unsigned int i=0; i<herb_manipulators.size(); i++) { if(herb_manipulators[i] && (herb_manipulators[i]->GetName().compare("right_wam") == 0)) { right_arm = herb_manipulators[i]; } } herb->SetActiveManipulator(right_arm); herb->SetActiveDOFs(right_arm->GetArmIndices()); // putting the bottle in the robot's right hand OpenRAVE::KinBodyPtr bottle_body = OpenRAVE::RaveCreateKinBody(env, ""); ASSERT_TRUE(env->ReadKinBodyURI(bottle_body, "objects/household/fuze_bottle.kinbody.xml")); bottle_body->SetName("bottle"); env->Add(bottle_body); OpenRAVE::geometry::RaveTransformMatrix<OpenRAVE::dReal> m; m.rotfrommat(-0.86354026, 0.50427591, 0.00200643, -0.25814712, -0.44547139, 0.85727201, 0.43319543, 0.73977094, 0.51485985); m.trans.x = 1.10322189; m.trans.y = -0.24693695; m.trans.z = 0.87205762; bottle_body->SetTransform(OpenRAVE::Transform(m)); OpenRAVE::Transform bottle_transform1 = bottle_body->GetTransform(); ASSERT_TRUE(herb->Grab(bottle_body)); // adding a flying pan OpenRAVE::KinBodyPtr pan_body = OpenRAVE::RaveCreateKinBody(env, ""); ASSERT_TRUE(env->ReadKinBodyURI(pan_body, "objects/household/pan.kinbody.xml")); pan_body->SetName("pan"); env->Add(pan_body); m.rotfrommat(2.89632833e-03, 9.99995806e-01, 1.19208782e-07, -9.99995806e-01, 2.89632833e-03, -1.18864027e-07, -1.19208797e-07, -1.18864013e-07, 1.00000000e+00); m.trans.x = 0.58; m.trans.y = -0.02; m.trans.z = 0.33; pan_body->SetTransform(OpenRAVE::Transform(m)); // giving constraints access to environment and robot RobotPtr robot = RobotPtr(new Robot(herb)); EnvironmentPtr environment = EnvironmentPtr(new Environment(env)); constraints.setRobot(robot); constraints.setEnvironment(environment); // first test constraints.calculateConstraintValues(); EXPECT_FALSE(constraints.areConstraintsFulfilled()); // moving robot and bottle to new start configuration std::vector<double> new_config; new_config.push_back(2.0); new_config.push_back(1.0); new_config.push_back(-0.8); new_config.push_back(1.0); new_config.push_back(-1.0); new_config.push_back(0.0); new_config.push_back(0.0); robot->setJointValues(new_config); constraints.setJointValues(robot->getJointValues()); constraints.calculateConstraintValues(); // test we've really moved OpenRAVE::Transform bottle_transform2 = bottle_body->GetTransform(); ASSERT_GT((bottle_transform1.trans - bottle_transform2.trans).lengthsqr3(), 0.1); ASSERT_GT((bottle_transform1.rot - bottle_transform2.rot).lengthsqr4(), 0.1); // actual projection test ASSERT_EQ(robot->getDOF(), constraints.getJointValues().size()); std::cout << "\nprior to constraining:\n"; std::vector<double> tmp = constraints.getTaskValues(); for(unsigned int i=0; i<tmp.size(); i++) { std::cout << tmp[i] << " "; } constraints.constrainCurrentConfiguration(); std::cout << "\npost to constraining:\n"; tmp = constraints.getTaskValues(); for(unsigned int i=0; i<tmp.size(); i++) { std::cout << tmp[i] << " "; } std::cout << "\n"; EXPECT_TRUE(constraints.areConstraintsFulfilled()); OpenRAVE::RaveDestroy(); }