#pragma once #include #include #include #include #include #include #include #include #include "cereal/messaging/messaging.h" #include "tools/cabana/dbc/dbcmanager.h" #include "tools/cabana/util.h" struct CanData { void compute(const MessageId &msg_id, const uint8_t *dat, const int size, double current_sec, double playback_speed, const std::vector &mask, double in_freq = 0); double ts = 0.; uint32_t count = 0; double freq = 0; std::vector dat; std::vector colors; struct ByteLastChange { double ts; int delta; int same_delta_counter; bool suppressed; std::array bit_change_counts; }; std::vector last_changes; double last_freq_update_ts = 0; }; struct CanEvent { uint8_t src; uint32_t address; uint64_t mono_time; uint8_t size; uint8_t dat[]; }; struct CompareCanEvent { constexpr bool operator()(const CanEvent *const e, uint64_t ts) const { return e->mono_time < ts; } constexpr bool operator()(uint64_t ts, const CanEvent *const e) const { return ts < e->mono_time; } }; struct BusConfig { int can_speed_kbps = 500; int data_speed_kbps = 2000; bool can_fd = false; }; typedef std::unordered_map> MessageEventsMap; class AbstractStream : public QObject { Q_OBJECT public: AbstractStream(QObject *parent); virtual ~AbstractStream() {} virtual void start() = 0; virtual bool liveStreaming() const { return true; } virtual void seekTo(double ts) {} virtual QString routeName() const = 0; virtual QString carFingerprint() const { return ""; } virtual QDateTime beginDateTime() const { return {}; } virtual double routeStartTime() const { return 0; } virtual double currentSec() const = 0; virtual double totalSeconds() const { return lastEventMonoTime() / 1e9 - routeStartTime(); } virtual void setSpeed(float speed) {} virtual double getSpeed() { return 1; } virtual bool isPaused() const { return false; } virtual void pause(bool pause) {} inline const std::unordered_map &lastMessages() const { return last_msgs; } inline const MessageEventsMap &eventsMap() const { return events_; } inline const std::vector &allEvents() const { return all_events_; } const CanData &lastMessage(const MessageId &id); const std::vector &events(const MessageId &id) const; size_t suppressHighlighted(); void clearSuppressed(); void suppressDefinedSignals(bool suppress); signals: void paused(); void resume(); void seekedTo(double sec); void streamStarted(); void eventsMerged(const MessageEventsMap &events_map); void msgsReceived(const std::set *new_msgs, bool has_new_ids); void sourcesUpdated(const SourceSet &s); void privateUpdateLastMsgsSignal(); public: SourceSet sources; protected: void mergeEvents(const std::vector &events); const CanEvent *newEvent(uint64_t mono_time, const cereal::CanData::Reader &c); void updateEvent(const MessageId &id, double sec, const uint8_t *data, uint8_t size); uint64_t lastEventMonoTime() const { return lastest_event_ts; } std::vector all_events_; uint64_t lastest_event_ts = 0; private: void updateLastMessages(); void updateLastMsgsTo(double sec); void updateMasks(); MessageEventsMap events_; std::unordered_map last_msgs; std::unique_ptr event_buffer_; // Members accessed in multiple threads. (mutex protected) std::mutex mutex_; std::set new_msgs_; std::unordered_map messages_; std::unordered_map> masks_; }; class AbstractOpenStreamWidget : public QWidget { public: AbstractOpenStreamWidget(AbstractStream **stream, QWidget *parent = nullptr) : stream(stream), QWidget(parent) {} virtual bool open() = 0; virtual QString title() = 0; protected: AbstractStream **stream = nullptr; }; class DummyStream : public AbstractStream { Q_OBJECT public: DummyStream(QObject *parent) : AbstractStream(parent) {} QString routeName() const override { return tr("No Stream"); } void start() override { emit streamStarted(); } double currentSec() const override { return 0; } }; class StreamNotifier : public QObject { Q_OBJECT public: StreamNotifier(QObject *parent = nullptr) : QObject(parent) {} static StreamNotifier* instance(); signals: void streamStarted(); void changingStream(); }; // A global pointer referring to the unique AbstractStream object extern AbstractStream *can;