Skip to content

Commit cad733b

Browse files
committed
feat: revise object time range logic
1 parent 21ffb1a commit cad733b

File tree

4 files changed

+73
-50
lines changed

4 files changed

+73
-50
lines changed

perception/multi_object_tracker/config/input_channels.param.yaml

+12-12
Original file line numberDiff line numberDiff line change
@@ -3,79 +3,79 @@
33
input_channels:
44
detected_objects:
55
topic: "/perception/object_recognition/detection/objects"
6-
expected_frequency: 10.0
6+
expected_interval: 0.1
77
optional:
88
name: "detected_objects"
99
short_name: "all"
1010
# LIDAR - rule-based
1111
lidar_clustering:
1212
topic: "/perception/object_recognition/detection/clustering/objects"
13-
expected_frequency: 10.0
13+
expected_interval: 0.1
1414
optional:
1515
name: "clustering"
1616
short_name: "Lcl"
1717
# LIDAR - DNN
1818
lidar_centerpoint:
1919
topic: "/perception/object_recognition/detection/centerpoint/objects"
20-
expected_frequency: 10.0
20+
expected_interval: 0.1
2121
optional:
2222
name: "centerpoint"
2323
short_name: "Lcp"
2424
lidar_centerpoint_validated:
2525
topic: "/perception/object_recognition/detection/centerpoint/validation/objects"
26-
expected_frequency: 10.0
26+
expected_interval: 0.1
2727
optional:
2828
name: "centerpoint"
2929
short_name: "Lcp"
3030
lidar_apollo:
3131
topic: "/perception/object_recognition/detection/apollo/objects"
32-
expected_frequency: 10.0
32+
expected_interval: 0.1
3333
optional:
3434
name: "apollo"
3535
short_name: "Lap"
3636
lidar_apollo_validated:
3737
topic: "/perception/object_recognition/detection/apollo/validation/objects"
38-
expected_frequency: 10.0
38+
expected_interval: 0.1
3939
optional:
4040
name: "apollo"
4141
short_name: "Lap"
4242
# LIDAR-CAMERA - DNN
4343
lidar_pointpainitng:
4444
topic: "/perception/object_recognition/detection/pointpainting/objects"
45-
expected_frequency: 10.0
45+
expected_interval: 0.1
4646
optional:
4747
name: "pointpainting"
4848
short_name: "Lpp"
4949
lidar_pointpainting_validated:
5050
topic: "/perception/object_recognition/detection/pointpainting/validation/objects"
51-
expected_frequency: 10.0
51+
expected_interval: 0.1
5252
optional:
5353
name: "pointpainting"
5454
short_name: "Lpp"
5555
# CAMERA-LIDAR
5656
camera_lidar_fusion:
5757
topic: "/perception/object_recognition/detection/clustering/camera_lidar_fusion/objects"
58-
expected_frequency: 10.0
58+
expected_interval: 0.1
5959
optional:
6060
name: "camera_lidar_fusion"
6161
short_name: "CLf"
6262
# CAMERA-LIDAR+TRACKER
6363
detection_by_tracker:
6464
topic: "/perception/object_recognition/detection/detection_by_tracker/objects"
65-
expected_frequency: 10.0
65+
expected_interval: 0.1
6666
optional:
6767
name: "detection_by_tracker"
6868
short_name: "dbT"
6969
# RADAR
7070
radar:
7171
topic: "/sensing/radar/detected_objects"
72-
expected_frequency: 30.0
72+
expected_interval: 0.0333
7373
optional:
7474
name: "radar"
7575
short_name: "R"
7676
radar_far:
7777
topic: "/perception/object_recognition/detection/radar/far_objects"
78-
expected_frequency: 30.0
78+
expected_interval: 0.0333
7979
optional:
8080
name: "radar_far"
8181
short_name: "Rf"

perception/multi_object_tracker/include/multi_object_tracker/processor/input_manager.hpp

+13-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct InputChannel
3636
std::string input_topic; // topic name of the detection, e.g. "/detection/lidar"
3737
std::string long_name = "Detected Object"; // full name of the detection
3838
std::string short_name = "DET"; // abbreviation of the name
39-
double expected_rate = 10.0; // [Hz]
39+
double expected_interval = 0.1; // [s]
4040
double expected_latency = 0.2; // [s]
4141
};
4242

@@ -77,6 +77,11 @@ class InputStream
7777
interval_mean = interval_mean_;
7878
interval_var = interval_var_;
7979
}
80+
void getLatencyStatistics(double & latency_mean, double & latency_var) const
81+
{
82+
latency_mean = latency_mean_;
83+
latency_var = latency_var_;
84+
}
8085
bool getTimestamps(
8186
rclcpp::Time & latest_measurement_time, rclcpp::Time & latest_message_time) const;
8287
rclcpp::Time getLatestMeasurementTime() const { return latest_measurement_time_; }
@@ -95,7 +100,7 @@ class InputStream
95100
std::function<void(const uint &)> func_trigger_;
96101

97102
bool is_time_initialized_{false};
98-
double expected_rate_;
103+
double expected_interval_;
99104
double latency_mean_;
100105
double latency_var_;
101106
double interval_mean_;
@@ -133,8 +138,12 @@ class InputManager
133138

134139
std::function<void()> func_trigger_;
135140
uint target_stream_idx_{0};
136-
double target_latency_{0.2};
137-
double target_latency_band_{0.14};
141+
double target_stream_latency_{0.2}; // [s]
142+
double target_stream_latency_std_{0.04}; // [s]
143+
double target_stream_interval_{0.1}; // [s]
144+
double target_stream_interval_std_{0.02}; // [s]
145+
double target_latency_{0.2}; // [s]
146+
double target_latency_band_{1.0}; // [s]
138147
};
139148

140149
} // namespace multi_object_tracker

perception/multi_object_tracker/src/multi_object_tracker_core.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ MultiObjectTracker::MultiObjectTracker(const rclcpp::NodeOptions & node_options)
9292
std::vector<std::string> input_topic_names;
9393
std::vector<std::string> input_names_long;
9494
std::vector<std::string> input_names_short;
95-
std::vector<double> input_expected_rates;
95+
std::vector<double> input_expected_intervals;
9696

9797
if (selected_input_channels.empty()) {
9898
RCLCPP_ERROR(this->get_logger(), "No input topics are specified.");
@@ -106,10 +106,10 @@ MultiObjectTracker::MultiObjectTracker(const rclcpp::NodeOptions & node_options)
106106
input_topic_names.push_back(input_topic_name);
107107

108108
// required parameter, but can set a default value
109-
const double default_expected_rate = 10.0;
110-
const double expected_rate = declare_parameter<double>(
111-
"input_channels." + selected_input_channel + ".expected_rate", default_expected_rate);
112-
input_expected_rates.push_back(expected_rate);
109+
const double default_expected_interval = 0.1; // [s]
110+
const double expected_interval = declare_parameter<double>(
111+
"input_channels." + selected_input_channel + ".expected_interval", default_expected_interval);
112+
input_expected_intervals.push_back(expected_interval);
113113

114114
// optional parameters
115115
const std::string default_name = selected_input_channel;
@@ -130,7 +130,7 @@ MultiObjectTracker::MultiObjectTracker(const rclcpp::NodeOptions & node_options)
130130
input_channels_[i].input_topic = input_topic_names[i];
131131
input_channels_[i].long_name = input_names_long[i];
132132
input_channels_[i].short_name = input_names_short[i];
133-
input_channels_[i].expected_rate = input_expected_rates[i];
133+
input_channels_[i].expected_interval = input_expected_intervals[i];
134134
}
135135

136136
// Initialize input manager

perception/multi_object_tracker/src/processor/input_manager.cpp

+42-28
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ void InputStream::init(const InputChannel & input_channel)
3131
input_topic_ = input_channel.input_topic;
3232
long_name_ = input_channel.long_name;
3333
short_name_ = input_channel.short_name;
34+
expected_interval_ = input_channel.expected_interval; // [s]
3435

3536
// Initialize queue
3637
objects_que_.clear();
3738

3839
// Initialize latency statistics
39-
expected_rate_ = input_channel.expected_rate; // [Hz]
4040
latency_mean_ = input_channel.expected_latency; // [s]
4141
latency_var_ = 0.0;
42-
interval_mean_ = 1 / expected_rate_;
42+
interval_mean_ = expected_interval_; // [s] (initial value)
4343
interval_var_ = 0.0;
4444

4545
latest_measurement_time_ = node_.now();
@@ -84,13 +84,11 @@ void InputStream::updateTimingStatus(const rclcpp::Time & now, const rclcpp::Tim
8484

8585
// Calculate interval, Update interval statistics
8686
if (is_time_initialized_) {
87-
bool is_interval_regular = true;
8887
const double interval = (now - latest_message_time_).seconds();
89-
// check if it is outlier
90-
if (interval > 1.5 * interval_mean_ || interval < 0.5 * interval_mean_) {
91-
// no update for the time statistics
92-
is_interval_regular = false;
93-
}
88+
// Check if the interval is regular
89+
// The interval is considered regular if it is within 0.5 and 1.5 times the expected interval
90+
bool is_interval_regular =
91+
interval > 0.5 * expected_interval_ && interval < 1.5 * expected_interval_;
9492

9593
if (is_interval_regular) {
9694
interval_mean_ = (1.0 - gain) * interval_mean_ + gain * interval;
@@ -189,17 +187,33 @@ void InputManager::getObjectTimeInterval(
189187
const rclcpp::Time & now, rclcpp::Time & object_latest_time,
190188
rclcpp::Time & object_oldest_time) const
191189
{
192-
object_latest_time = now - rclcpp::Duration::from_seconds(target_latency_);
193-
object_oldest_time = now - rclcpp::Duration::from_seconds(target_latency_ + target_latency_band_);
194-
195-
// try to include the latest message of the target stream
190+
object_latest_time =
191+
now - rclcpp::Duration::from_seconds(
192+
target_stream_latency_ -
193+
0.1 * target_stream_latency_std_); // object_latest_time with 0.1 sigma safety margin
194+
// check the target stream can be included in the object time interval
196195
if (input_streams_.at(target_stream_idx_)->isTimeInitialized()) {
197196
rclcpp::Time latest_measurement_time =
198197
input_streams_.at(target_stream_idx_)->getLatestMeasurementTime();
198+
// if the object_latest_time is newer than the next expected message time, set it older
199+
// than the next expected message time
200+
rclcpp::Time next_expected_message_time =
201+
latest_measurement_time +
202+
rclcpp::Duration::from_seconds(
203+
target_stream_interval_ -
204+
1.0 *
205+
target_stream_interval_std_); // next expected message time with 1 sigma safety margin
206+
object_latest_time = object_latest_time > next_expected_message_time
207+
? next_expected_message_time
208+
: object_latest_time;
209+
210+
// if the object_latest_time is older than the latest measurement time, set it as the latest
211+
// object time
199212
object_latest_time =
200-
object_latest_time > latest_measurement_time ? object_latest_time : latest_measurement_time;
213+
object_latest_time < latest_measurement_time ? latest_measurement_time : object_latest_time;
201214
}
202215

216+
object_oldest_time = object_latest_time - rclcpp::Duration::from_seconds(1.0);
203217
// if the object_oldest_time is older than the latest object time, set it to the latest object
204218
// time
205219
object_oldest_time =
@@ -209,21 +223,24 @@ void InputManager::getObjectTimeInterval(
209223
void InputManager::optimizeTimings()
210224
{
211225
double max_latency_mean = 0.0;
212-
uint stream_selected_idx = 0;
213-
double selected_idx_latency_std = 0.0;
214-
double selected_idx_interval = 0.0;
226+
uint selected_stream_idx = 0;
227+
double selected_stream_latency_std = 0.1;
228+
double selected_stream_interval = 0.1;
229+
double selected_stream_interval_std = 0.01;
215230

216231
{
217232
// ANALYSIS: Get the streams statistics
233+
// select the stream that has the maximum latency
218234
double latency_mean, latency_var, interval_mean, interval_var;
219235
for (const auto & input_stream : input_streams_) {
220236
if (!input_stream->isTimeInitialized()) continue;
221237
input_stream->getTimeStatistics(latency_mean, latency_var, interval_mean, interval_var);
222238
if (latency_mean > max_latency_mean) {
223239
max_latency_mean = latency_mean;
224-
selected_idx_latency_std = std::sqrt(latency_var);
225-
stream_selected_idx = input_stream->getIndex();
226-
selected_idx_interval = interval_mean;
240+
selected_stream_idx = input_stream->getIndex();
241+
selected_stream_latency_std = std::sqrt(latency_var);
242+
selected_stream_interval = interval_mean;
243+
selected_stream_interval_std = std::sqrt(interval_var);
227244
}
228245

229246
/* DEBUG */
@@ -244,15 +261,12 @@ void InputManager::optimizeTimings()
244261

245262
// Set the target stream index, which has the maximum latency
246263
// trigger will be called next time
247-
target_stream_idx_ = stream_selected_idx;
248-
target_latency_ = max_latency_mean - selected_idx_latency_std;
249-
target_latency_band_ = 2 * selected_idx_latency_std + selected_idx_interval;
250-
251-
/* DEBUG */
252-
RCLCPP_INFO(
253-
node_.get_logger(), "InputManager::getObjects Target stream: %s, target latency: %f, band: %f",
254-
input_streams_.at(target_stream_idx_)->getLongName().c_str(), target_latency_,
255-
target_latency_band_);
264+
// if no stream is initialized, the target stream index will be 0 and wait for the initialization
265+
target_stream_idx_ = selected_stream_idx;
266+
target_stream_latency_ = max_latency_mean;
267+
target_stream_latency_std_ = selected_stream_latency_std;
268+
target_stream_interval_ = selected_stream_interval;
269+
target_stream_interval_std_ = selected_stream_interval_std;
256270
}
257271

258272
bool InputManager::getObjects(const rclcpp::Time & now, ObjectsList & objects_list)

0 commit comments

Comments
 (0)