564{
  565  static constexpr mot::Visitor make_track_visitor{
  566    [](const mot::CtrvDetection & d, const mot::Uuid & u) {
  567      return Track{mot::make_track<mot::CtrvTrack>(d, u)};
 
  568    },
  569    [](const mot::CtraDetection & d, const mot::Uuid & u) {
  570      return Track{mot::make_track<mot::CtraTrack>(d, u)};
 
  571    },
  572    [](const auto &) {
  573      
  574      throw std::runtime_error("cannot make track from given detection");
  575    },
  576  };
  577 
  579    RCLCPP_DEBUG(
  580      get_logger(), 
"List of tracks is empty. Converting detections to tentative tracks");
 
  581 
  582    
  583    
  584    RCLCPP_DEBUG_STREAM(
  586    const auto clusters{mot::cluster_detections(
detections_, 0.75)};
 
  587    for (const auto & cluster : clusters) {
  588      const auto detection{std::cbegin(cluster.get_detections())->second};
  589      const auto uuid_str{mot::get_uuid(detection).value()};
  590      
  591      
  592      const mot::Uuid new_uuid{
  594        uuid_str.substr(std::size(uuid_str) - 4, 4)};
  596        std::visit(make_track_visitor, detection, std::variant<mot::Uuid>(new_uuid)));
  597    }
  598    RCLCPP_DEBUG_STREAM(
  599      get_logger(), 
"Track size after detection clustering: " 
  601    track_list_pub_->publish(carma_cooperative_perception_interfaces::msg::TrackList{});
 
  602 
  605    return;
  606  }
  607 
  608  const units::time::second_t current_time{this->now().seconds()};
  609  RCLCPP_DEBUG_STREAM(
  611 
  613 
  615  RCLCPP_DEBUG_STREAM(
  616    get_logger(), 
"Track size after prediction: " << predicted_tracks.size());
 
  617  auto scores{
  618    mot::score_tracks_and_detections(predicted_tracks, 
detections_, SemanticDistance2dScore{})};
 
  619 
  620  
  621  
  622  mot::prune_track_and_detection_scores_if(scores, [](const auto & score) { return score > 1.0; });
  623 
  624  const auto associations{
  625    mot::associate_detections_to_tracks(scores, mot::gnn_association_visitor)};
  626 
  628  RCLCPP_DEBUG_STREAM(
  630  std::unordered_map<mot::Uuid, Detection> detection_map;
  632    detection_map[mot::get_uuid(detection)] = detection;
  633  }
  634 
  635  const mot::HasAssociation has_association{associations};
  637    if (has_association(track)) {
  638      const auto detection_uuids{associations.at(get_uuid(track))};
  639      const auto first_detection{detection_map[detection_uuids.at(0)]};
  640      const auto fused_track{
  641        std::visit(mot::covariance_intersection_visitor, track, first_detection)};
  643      RCLCPP_DEBUG_STREAM(
  644        get_logger(), 
"Updating track: " << mot::get_uuid(track).value());
 
  645    }
  646  }
  647 
  648  
  649  
  650  std::vector<Detection> unassociated_detections;
  651  for (const auto & [uuid, detection] : detection_map) {
  652    if (!has_association(detection)) {
  653      unassociated_detections.push_back(detection);
  654    }
  655  }
  656  RCLCPP_DEBUG_STREAM(
  657    get_logger(), 
"Unassociated detection size: " << unassociated_detections.size());
 
  658 
  659  
  660  
  661  
  662  auto remove_start{std::remove_if(
  663    std::begin(unassociated_detections), std::end(unassociated_detections),
  664    [&scores](const auto & detection) {
  665      const auto uuid{mot::get_uuid(detection)};
  666      auto min_score{std::numeric_limits<float>::infinity()};
  667      for (const auto & [uuid_pair, score] : scores) {
  668        if (uuid_pair.second == uuid) {
  669          min_score = std::min(min_score, score);
  670        }
  671      }
  672 
  673      
  674      
  675      return min_score < 1.0;
  676    })};
  677 
  678  unassociated_detections.erase(remove_start, std::end(unassociated_detections));
  679 
  680  RCLCPP_DEBUG_STREAM(
  681    get_logger(), 
"Unassociated detection size after removal: " 
  682    << unassociated_detections.size());
  683 
  684  
  685  
  686  const auto clusters{mot::cluster_detections(unassociated_detections, 0.75, MetricSe2{})};
  687  for (const auto & cluster : clusters) {
  688    const auto detection{std::cbegin(cluster.get_detections())->second};
  689    const auto uuid_str{mot::get_uuid(detection).value()};
  690    
  691    
  692    const mot::Uuid new_uuid{
  694      uuid_str.substr(std::size(uuid_str) - 4, 4)};
  696      std::visit(make_track_visitor, detection, std::variant<mot::Uuid>(new_uuid)));
  697  }
  698 
  699  RCLCPP_DEBUG_STREAM(
  700    get_logger(), 
"Track size after adding unassociated detections: " 
  702 
  703  carma_cooperative_perception_interfaces::msg::TrackList track_list;
  704  for (
const auto & track : 
track_manager_.get_confirmed_tracks()) {
 
  705    track_list.tracks.push_back(
to_ros_msg(track));
 
  706  }
  707 
  708  RCLCPP_DEBUG_STREAM(
  709    get_logger(), 
"Confirmed Track size after converting to ROS message: " 
  710    << track_list.tracks.size());
  712 
  715}
rclcpp_lifecycle::LifecyclePublisher< carma_cooperative_perception_interfaces::msg::TrackList >::SharedPtr track_list_pub_
std::size_t lifetime_generated_track_count_
multiple_object_tracking::FixedThresholdTrackManager< Track > track_manager_
std::vector< Detection > detections_
std::unordered_map< multiple_object_tracking::Uuid, std::size_t > uuid_index_map_
rclcpp::Logger get_logger() const
static auto temporally_align_detections(std::vector< Detection > &detections, units::time::second_t end_time) -> void
auto to_string(const UtmZone &zone) -> std::string
static auto predict_track_states(std::vector< Track > tracks, units::time::second_t end_time)
std::variant< multiple_object_tracking::CtrvTrack, multiple_object_tracking::CtraTrack > Track
static auto to_ros_msg(const mot::CtraTrack &track)