Ejemplo n.º 1
0
 void open_usb() {
     ROS_INFO("Connecting to %s...", port.c_str());
     ros::Time start = ros::Time::now();
     double notify_every = 10.0;
     double check_every = 0.25;
     std::string last_msg;
     while (ros::ok()) {
         try {
             ser->Open(port.c_str());
             ROS_INFO("Connected to %s", port.c_str());
             break;
         } catch (USBSerial::Exception &e) {
             last_msg = e.what();
         }
         ros::Duration(check_every).sleep();
         double dur = (ros::Time::now() - start).toSec();
         if (dur > notify_every) {
             ROS_WARN_THROTTLE(notify_every,
                               "Haven't connected to %s in %.2f seconds."
                                       "  Last error=\n%s",
                               port.c_str(), dur, last_msg.c_str());
         }
         publishTf();
     }
 }
bool Node::update()
{
  // get pose from tf
  if (p_use_tf_pose_start_estimate_) {
    tf::StampedTransform odom_pose;
    try {
      getTransformListener().waitForTransform(p_odom_frame_, p_base_frame_, scan_.getStamp(), ros::Duration(1.0));
      getTransformListener().lookupTransform(p_odom_frame_, p_base_frame_, scan_.getStamp(), odom_pose);

      matcher_->setTransform(map_odom_transform_ * odom_pose);
    } catch(tf::TransformException& e) {
      ROS_ERROR("Could not get pose from tf: %s", e.what());
      return false;
    }
  }

  // match scan
  if (!map_->empty()) {
#ifdef USE_HECTOR_TIMING
    hector_diagnostics::TimingSection section("scan matcher");
#endif
    matcher_->computeCovarianceIf(pose_with_covariance_publisher_ && pose_with_covariance_publisher_.getNumSubscribers() > 0);
    matcher_->match(*map_, scan_);
    if (!matcher_->valid()) return false;
  }

  // update map
  float_t position_difference, orientation_difference;
  matcher_->getPoseDifference(last_map_update_pose_, position_difference, orientation_difference);
  if (map_->empty() || position_difference > p_map_update_translational_threshold_ || orientation_difference > p_map_update_angular_threshold_) {
#ifdef USE_HECTOR_TIMING
    hector_diagnostics::TimingSection section("map update");
#endif
    // ros::WallTime _map_update_start = ros::WallTime::now();
      map_->insert(scan_, matcher_->getTransform());
    // ROS_DEBUG("Map update took %f seconds.", (ros::WallTime::now() - _map_update_start).toSec());

    last_map_update_pose_ = matcher_->getTransform();
    last_map_update_time_ = scan_.getStamp();
  }

  // publish pose
  publishPose();

  // publish tf
  if (p_pub_map_odom_transform_) publishTf();

  // publish timing
#ifdef USE_HECTOR_TIMING
    timing_publisher_.publish(hector_diagnostics::TimingAggregator::Instance()->update(matcher_->getStamp()));
#endif

  return true;
}
Ejemplo n.º 3
0
void VisualOdometry::RGBDCallback(
  const ImageMsg::ConstPtr& rgb_msg,
  const ImageMsg::ConstPtr& depth_msg,
  const CameraInfoMsg::ConstPtr& info_msg)
{
  ros::WallTime start = ros::WallTime::now();

  // **** initialize ***************************************************

  if (!initialized_)
  {
    initialized_ = getBaseToCameraTf(rgb_msg->header);
    init_time_ = rgb_msg->header.stamp;
    if (!initialized_) return;

    motion_estimation_.setBaseToCameraTf(eigenAffineFromTf(b2c_));
  }

  // **** create frame *************************************************

  ros::WallTime start_frame = ros::WallTime::now();
  rgbdtools::RGBDFrame frame;
  createRGBDFrameFromROSMessages(rgb_msg, depth_msg, info_msg, frame); 
  ros::WallTime end_frame = ros::WallTime::now();

  // **** find features ************************************************

  ros::WallTime start_features = ros::WallTime::now();
  feature_detector_->findFeatures(frame);
  ros::WallTime end_features = ros::WallTime::now();

  // **** registration *************************************************
  
  ros::WallTime start_reg = ros::WallTime::now();
  AffineTransform m = motion_estimation_.getMotionEstimation(frame);
  tf::Transform motion = tfFromEigenAffine(m);
  f2b_ = motion * f2b_;
  ros::WallTime end_reg = ros::WallTime::now();

  // **** publish outputs **********************************************
  
  if (publish_tf_)    publishTf(rgb_msg->header);
  if (publish_odom_)  publishOdom(rgb_msg->header);
  if (publish_path_)  publishPath(rgb_msg->header);
  if (publish_pose_)  publishPoseStamped(rgb_msg->header);
  
  if (publish_feature_cloud_) publishFeatureCloud(frame);
  if (publish_feature_cov_) publishFeatureCovariances(frame);
  
  if (publish_model_cloud_) publishModelCloud();
  if (publish_model_cov_)   publishModelCovariances();

  // **** print diagnostics *******************************************

  ros::WallTime end = ros::WallTime::now();

  frame_count_++;
  
  int n_features = frame.keypoints.size();
  int n_valid_features = frame.n_valid_keypoints;
  int n_model_pts = motion_estimation_.getModelSize();

  double d_frame    = 1000.0 * (end_frame    - start_frame   ).toSec();
  double d_features = 1000.0 * (end_features - start_features).toSec();
  double d_reg      = 1000.0 * (end_reg      - start_reg     ).toSec();
  double d_total    = 1000.0 * (end          - start         ).toSec();

  diagnostics(n_features, n_valid_features, n_model_pts,
              d_frame, d_features, d_reg, d_total);
}
Ejemplo n.º 4
0
//**************************************************************************************************************************getMotion()
void PSMpositionNode::getMotion(const sensor_msgs::LaserScan& scan,  std::vector <depthPoint> *depthLine)
{
    ROS_DEBUG("Received kinectLine");

    // **** attmempt to match the two scans

    // PM scan matcher is used in the following way:
    // The reference scan (prevPMScan_) always has a pose of 0
    // The new scan (currPMScan) has a pose equal to the movement
    // of the laser in the world frame since the last scan (btTransform change)
    // The computed correction is then propagated using the tf machinery
    if (!initialized_)
    {
        initialized_ = initialize(scan);
        if (initialized_) ROS_INFO("Matcher Horizontal initialized");
        return;
    }

    prevPMScan_->rx = 0;
    prevPMScan_->ry = 0;
    prevPMScan_->th = 0;

    btTransform currWorldToBase;
    btTransform change;
    change.setIdentity();

    // what odometry model to use
    if (useTfOdometry_)
    {
        // get the current position of the base in the world frame
        // if no transofrm is available, we'll use the last known transform

        getCurrentEstimatedPose(currWorldToBase, scan);
        change = laserToBase_ * prevWorldToBase_.inverse() * currWorldToBase * baseToLaser_;
    }
    else if (useImuOdometry_)
    {
        imuMutex_.lock();
        double dTheta = currImuAngle_ - prevImuAngle_;
        prevImuAngle_ = currImuAngle_;
        change.getRotation().setRPY(0.0, 0.0, dTheta);
        imuMutex_.unlock();
    }

    PMScan * currPMScan = new PMScan(scan.ranges.size());

    rosToPMScan(scan, change, currPMScan);


    try
    {
        matcher_.pm_psm(prevPMScan_, currPMScan);
    }
    catch(int err)
    {
        ROS_WARN("Error in scan matching");
        delete prevPMScan_;
        prevPMScan_ = currPMScan;
        return;
    };

    // **** calculate change in position

    // rotate by -90 degrees, since polar scan matcher assumes different laser frame
    // and scale down by 100
    double dx =  currPMScan->ry / ROS_TO_PM;
    double dy = -currPMScan->rx / ROS_TO_PM;
    double da =  currPMScan->th;

    // change = scan match result for how much laser moved between scans,
    // in the world frame
    change.setOrigin(btVector3(dx, dy, 0.0));
    btQuaternion q;
    q.setRPY(0, 0, da);
    change.setRotation(q);


    // **** publish the new estimated pose as a tf
    if(take_vicon == true) {
        prevWorldToBase_.setOrigin(btVector3(pos_vicon[0],pos_vicon[1], pos_vicon[2]));
        btQuaternion vicon_q(quat_vicon.x(),quat_vicon.y(),quat_vicon.z(),quat_vicon.w());
        prevWorldToBase_.setRotation(vicon_q);
        prevWorldToBase_.setIdentity();
        take_vicon=false;
    }

    currWorldToBase = prevWorldToBase_ * baseToLaser_ * change * laserToBase_;

    heightLine = ransac(depthLine);

    frameP_ = worldFrame_;

    if (publishTf_  ) publishTf  (currWorldToBase, scan.header.stamp);

    if (publishPose_) publishPose(currWorldToBase, scan.header.stamp, frameP_, heightLine);

    // **** swap old and new

    delete prevPMScan_;
    prevPMScan_      = currPMScan;
    prevWorldToBase_ = currWorldToBase;

}
Ejemplo n.º 5
0
void PSMpositionNode::getMotion_can(const sensor_msgs::LaserScan& scan,  std::vector <depthPoint> *depthLine)//*********************************************getMotion_can()
{
    ROS_DEBUG("Received scan");


    // **** if this is the first scan, initialize and leave the function here

    if (!initialized_can)
    {
        initialized_can = initializeCan(scan);
        if (initialized_can) ROS_INFO("Matcher initialized");
        return;
    }

    // **** attmempt to match the two scans

    // CSM is used in the following way:
    // The reference scan (prevLDPcan_) always has a pose of 0
    // The new scan (currLDPScan) has a pose equal to the movement
    // of the laser in the world frame since the last scan (btTransform change)
    // The computed correction is then propagated using the tf machinery

    prevLDPScan_->odometry[0] = 0;
    prevLDPScan_->odometry[1] = 0;
    prevLDPScan_->odometry[2] = 0;

    prevLDPScan_->estimate[0] = 0;
    prevLDPScan_->estimate[1] = 0;
    prevLDPScan_->estimate[2] = 0;

    prevLDPScan_->true_pose[0] = 0;
    prevLDPScan_->true_pose[1] = 0;
    prevLDPScan_->true_pose[2] = 0;

    btTransform currWorldToBase;
    btTransform change;
    change.setIdentity();

    // what odometry model to use
    if (useTfOdometry_)
    {
        // get the current position of the base in the world frame
        // if no transofrm is available, we'll use the last known transform

        getCurrentEstimatedPose(currWorldToBase, scan);
        change = laserToBase_ * prevWorldToBase_.inverse() * currWorldToBase * baseToLaser_;
    }
    else if (useImuOdometry_)
    {
        imuMutex_.lock();
        double dTheta = currImuAngle_ - prevImuAngle_;
        prevImuAngle_ = currImuAngle_;
        change.getRotation().setRPY(0.0, 0.0, dTheta);
        imuMutex_.unlock();
    }

    geometry_msgs::Pose2D p;
    tfToPose2D(change, p);
    LDP currLDPScan = rosToLDPScan(scan, p);

    input_.laser_ref  = prevLDPScan_;
    input_.laser_sens = currLDPScan;
    input_.first_guess[0] = 0;
    input_.first_guess[1] = 0;
    input_.first_guess[2] = 0;

    sm_icp(&input_, &output_);

    if (!output_.valid)
    {
        ROS_WARN("Error in scan matching");
        ld_free(prevLDPScan_);
        prevLDPScan_ = currLDPScan;
        return;
    }

    // **** calculate change in position

    double dx = output_.x[0];
    double dy = output_.x[1];
    double da = output_.x[2];

    // change = scan match result for how much laser moved between scans,
    // in the world frame
    change.setOrigin(btVector3(dx, dy, 0.0));
    btQuaternion q;
    q.setRPY(0, 0, da);
    change.setRotation(q);

    frameP_ = worldFrame_;
    heightLine = ransac(depthLine);
    // **** publish the new estimated pose as a tf

    if(take_vicon == true) {
        prevWorldToBase_.setOrigin(btVector3(pos_vicon[0],pos_vicon[1], pos_vicon[2]));
        btQuaternion vicon_q(quat_vicon.x(),quat_vicon.y(),quat_vicon.z(),quat_vicon.w());
        prevWorldToBase_.setRotation(vicon_q);
    }

    currWorldToBase = prevWorldToBase_ * baseToLaser_ * change * laserToBase_;

    if (publishTf_  ) publishTf  (currWorldToBase, scan.header.stamp);
    if (publishPose_) publishPose(currWorldToBase, scan.header.stamp, frameP_, heightLine);

    // **** swap old and new

    ld_free(prevLDPScan_);
    prevLDPScan_ = currLDPScan;
    prevWorldToBase_ = currWorldToBase;

    // **** timing information - needed for profiling only

}
Ejemplo n.º 6
0
void StaticPoseNode::callbackSync(const sensor_msgs::CameraInfoConstPtr &msg) {
    publishTf(msg->header.stamp);
}