replay: use lockstep scheduler

This commit is contained in:
Beat Küng
2020-06-18 17:21:05 +02:00
committed by Daniel Agar
parent 71dcf8d619
commit 157ef43e28
8 changed files with 64 additions and 63 deletions
@@ -16,5 +16,4 @@ param set SDLOG_DIRS_MAX 7
replay tryapplyparams replay tryapplyparams
ekf2 start -r ekf2 start -r
logger start -f -t -b 1000 -p vehicle_attitude logger start -f -t -b 1000 -p vehicle_attitude
sleep 0.2
replay start replay start
+5 -2
View File
@@ -240,8 +240,11 @@ then
fi fi
dataman start dataman start
replay tryapplyparams # only start the simulator if not in replay mode, as both control the lockstep time
simulator start -c $simulator_tcp_port if ! replay tryapplyparams
then
simulator start -c $simulator_tcp_port
fi
tone_alarm start tone_alarm start
rc_update start rc_update start
sensors start sensors start
+1 -5
View File
@@ -99,9 +99,5 @@ set(REPLAY_FILE "$ENV{replay}")
if(REPLAY_FILE) if(REPLAY_FILE)
message(STATUS "Building with uorb publisher rules support") message(STATUS "Building with uorb publisher rules support")
add_definitions(-DORB_USE_PUBLISHER_RULES) add_definitions(-DORB_USE_PUBLISHER_RULES)
message(STATUS "Building without lockstep for replay")
set(ENABLE_LOCKSTEP_SCHEDULER no)
else()
set(ENABLE_LOCKSTEP_SCHEDULER yes)
endif() endif()
set(ENABLE_LOCKSTEP_SCHEDULER yes)
+1 -2
View File
@@ -20,5 +20,4 @@ px4_add_board(
message(STATUS "Building with uorb publisher rules support") message(STATUS "Building with uorb publisher rules support")
add_definitions(-DORB_USE_PUBLISHER_RULES) add_definitions(-DORB_USE_PUBLISHER_RULES)
message(STATUS "Building without lockstep for replay") set(ENABLE_LOCKSTEP_SCHEDULER yes)
set(ENABLE_LOCKSTEP_SCHEDULER no)
+38 -10
View File
@@ -67,10 +67,10 @@
#define PARAMS_OVERRIDE_FILE PX4_ROOTFSDIR "/replay_params.txt" #define PARAMS_OVERRIDE_FILE PX4_ROOTFSDIR "/replay_params.txt"
using namespace std; using namespace std;
using namespace time_literals;
namespace px4 namespace px4
{ {
class Replay;
char *Replay::_replay_file = nullptr; char *Replay::_replay_file = nullptr;
@@ -750,6 +750,13 @@ Replay::run()
return; return;
} }
_speed_factor = 1.f;
const char *speedup = getenv("PX4_SIM_SPEED_FACTOR");
if (speedup) {
_speed_factor = atof(speedup);
}
onEnterMainLoop(); onEnterMainLoop();
_replay_start_time = hrt_absolute_time(); _replay_start_time = hrt_absolute_time();
@@ -767,9 +774,7 @@ Replay::run()
return; return;
} }
//we update the timestamps from the file by a constant offset to match const uint64_t timestamp_offset = getTimestampOffset();
//the current replay time
const uint64_t timestamp_offset = _replay_start_time - _file_start_time;
uint32_t nr_published_messages = 0; uint32_t nr_published_messages = 0;
streampos last_additional_message_pos = _data_section_start; streampos last_additional_message_pos = _data_section_start;
@@ -849,13 +854,23 @@ Replay::run()
if (!should_exit()) { if (!should_exit()) {
PX4_INFO("Replay done (published %u msgs, %.3lf s)", nr_published_messages, PX4_INFO("Replay done (published %u msgs, %.3lf s)", nr_published_messages,
(double)hrt_elapsed_time(&_replay_start_time) / 1.e6); (double)hrt_elapsed_time(&_replay_start_time) / 1.e6);
//TODO: add parameter -q?
replay_file.close();
px4_shutdown_request();
} }
onExitMainLoop(); onExitMainLoop();
if (!should_exit()) {
replay_file.close();
px4_shutdown_request();
// we need to ensure the shutdown logic gets updated and eventually triggers shutdown
hrt_abstime t = hrt_absolute_time();
for (int i = 0; i < 1000; ++i) {
struct timespec ts;
abstime_to_ts(&ts, t);
px4_clock_settime(CLOCK_MONOTONIC, &ts);
t += 10_ms;
}
}
} }
void void
@@ -884,7 +899,20 @@ Replay::handleTopicDelay(uint64_t next_file_time, uint64_t timestamp_offset)
// if some topics have a timestamp smaller than the log file start, publish them immediately // if some topics have a timestamp smaller than the log file start, publish them immediately
if (cur_time < publish_timestamp && next_file_time > _file_start_time) { if (cur_time < publish_timestamp && next_file_time > _file_start_time) {
px4_usleep(publish_timestamp - cur_time); if (_speed_factor > FLT_EPSILON) {
// avoid many small usleep calls
_accumulated_delay += (publish_timestamp - cur_time) / _speed_factor;
if (_accumulated_delay > 3000) {
system_usleep(_accumulated_delay);
_accumulated_delay = 0.f;
}
}
// adjust the lockstep time to the publication time
struct timespec ts;
abstime_to_ts(&ts, publish_timestamp);
px4_clock_settime(CLOCK_MONOTONIC, &ts);
} }
return publish_timestamp; return publish_timestamp;
@@ -987,7 +1015,7 @@ Replay::applyParams(bool quiet)
{ {
if (!isSetup()) { if (!isSetup()) {
if (quiet) { if (quiet) {
return 0; return -1;
} }
PX4_ERR("no log file given (via env variable %s)", replay::ENV_FILENAME); PX4_ERR("no log file given (via env variable %s)", replay::ENV_FILENAME);
+11
View File
@@ -206,9 +206,18 @@ protected:
*/ */
bool nextDataMessage(std::ifstream &file, Subscription &subscription, int msg_id); bool nextDataMessage(std::ifstream &file, Subscription &subscription, int msg_id);
virtual uint64_t getTimestampOffset()
{
//we update the timestamps from the file by a constant offset to match
//the current replay time
return _replay_start_time - _file_start_time;
}
std::vector<Subscription *> _subscriptions; std::vector<Subscription *> _subscriptions;
std::vector<uint8_t> _read_buffer; std::vector<uint8_t> _read_buffer;
float _speed_factor{1.f}; ///< from PX4_SIM_SPEED_FACTOR env variable (set to 0 to avoid usleep = unlimited rate)
private: private:
std::set<std::string> _overridden_params; std::set<std::string> _overridden_params;
std::map<std::string, std::string> _file_formats; ///< all formats we read from the file std::map<std::string, std::string> _file_formats; ///< all formats we read from the file
@@ -222,6 +231,8 @@ private:
int64_t _read_until_file_position = 1ULL << 60; ///< read limit if log contains appended data int64_t _read_until_file_position = 1ULL << 60; ///< read limit if log contains appended data
float _accumulated_delay{0.f};
bool readFileHeader(std::ifstream &file); bool readFileHeader(std::ifstream &file);
/** /**
+3 -37
View File
@@ -66,32 +66,8 @@ ReplayEkf2::handleTopicUpdate(Subscription &sub, void *data, std::ifstream &repl
return false; return false;
} }
px4_pollfd_struct_t fds[1]; // Wait for modules to process the data
fds[0].fd = _vehicle_attitude_sub; px4_lockstep_wait_for_components();
fds[0].events = POLLIN;
// wait for a response from the estimator
int pret = px4_poll(fds, 1, 1000);
// introduce some breaks to make sure the logger can keep up
if (++_topic_counter == 50) {
px4_usleep(1000);
_topic_counter = 0;
}
if (pret == 0) {
PX4_WARN("poll timeout");
} else if (pret < 0) {
PX4_ERR("poll failed (%i)", pret);
} else {
if (fds[0].revents & POLLIN) {
vehicle_attitude_s att;
// need to to an orb_copy so that poll will not return immediately
orb_copy(ORB_ID(vehicle_attitude), _vehicle_attitude_sub, &att);
}
}
return true; return true;
@@ -206,7 +182,7 @@ ReplayEkf2::findTimestampAndPublish(uint64_t timestamp, uint16_t msg_id, std::if
void void
ReplayEkf2::onEnterMainLoop() ReplayEkf2::onEnterMainLoop()
{ {
_vehicle_attitude_sub = orb_subscribe(ORB_ID(vehicle_attitude)); _speed_factor = 0.f; // iterate as fast as possible
} }
void void
@@ -233,16 +209,6 @@ ReplayEkf2::onExitMainLoop()
print_sensor_statistics(_vehicle_air_data_msg_id, "vehicle_air_data"); print_sensor_statistics(_vehicle_air_data_msg_id, "vehicle_air_data");
print_sensor_statistics(_vehicle_magnetometer_msg_id, "vehicle_magnetometer"); print_sensor_statistics(_vehicle_magnetometer_msg_id, "vehicle_magnetometer");
print_sensor_statistics(_vehicle_visual_odometry_msg_id, "vehicle_visual_odometry"); print_sensor_statistics(_vehicle_visual_odometry_msg_id, "vehicle_visual_odometry");
orb_unsubscribe(_vehicle_attitude_sub);
_vehicle_attitude_sub = -1;
}
uint64_t
ReplayEkf2::handleTopicDelay(uint64_t next_file_time, uint64_t timestamp_offset)
{
// no need for usleep
return next_file_time;
} }
} // namespace px4 } // namespace px4
+5 -6
View File
@@ -50,8 +50,6 @@ protected:
void onEnterMainLoop() override; void onEnterMainLoop() override;
void onExitMainLoop() override; void onExitMainLoop() override;
uint64_t handleTopicDelay(uint64_t next_file_time, uint64_t timestamp_offset) override;
/** /**
* handle ekf2 topic publication in ekf2 replay mode * handle ekf2 topic publication in ekf2 replay mode
* @param sub * @param sub
@@ -63,6 +61,11 @@ protected:
void onSubscriptionAdded(Subscription &sub, uint16_t msg_id) override; void onSubscriptionAdded(Subscription &sub, uint16_t msg_id) override;
uint64_t getTimestampOffset() override
{
// avoid offsetting timestamps as we use them to compare against the log
return 0;
}
private: private:
bool publishEkf2Topics(const ekf2_timestamps_s &ekf2_timestamps, std::ifstream &replay_file); bool publishEkf2Topics(const ekf2_timestamps_s &ekf2_timestamps, std::ifstream &replay_file);
@@ -76,8 +79,6 @@ private:
*/ */
bool findTimestampAndPublish(uint64_t timestamp, uint16_t msg_id, std::ifstream &replay_file); bool findTimestampAndPublish(uint64_t timestamp, uint16_t msg_id, std::ifstream &replay_file);
int _vehicle_attitude_sub = -1;
static constexpr uint16_t msg_id_invalid = 0xffff; static constexpr uint16_t msg_id_invalid = 0xffff;
uint16_t _airspeed_msg_id = msg_id_invalid; uint16_t _airspeed_msg_id = msg_id_invalid;
@@ -87,8 +88,6 @@ private:
uint16_t _vehicle_air_data_msg_id = msg_id_invalid; uint16_t _vehicle_air_data_msg_id = msg_id_invalid;
uint16_t _vehicle_magnetometer_msg_id = msg_id_invalid; uint16_t _vehicle_magnetometer_msg_id = msg_id_invalid;
uint16_t _vehicle_visual_odometry_msg_id = msg_id_invalid; uint16_t _vehicle_visual_odometry_msg_id = msg_id_invalid;
int _topic_counter = 0;
}; };
} //namespace px4 } //namespace px4