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)