File: tracker.hpp

package info (click to toggle)
sight 25.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 42,184 kB
  • sloc: cpp: 289,476; xml: 17,257; ansic: 9,878; python: 1,379; sh: 144; makefile: 33
file content (225 lines) | stat: -rw-r--r-- 7,348 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/************************************************************************
 *
 * Copyright (C) 2014-2025 IRCAD France
 * Copyright (C) 2014-2019 IHU Strasbourg
 *
 * This file is part of Sight.
 *
 * Sight is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Sight is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
 *
 ***********************************************************************/

#pragma once

#include <sight/service/config.hpp>

#include <core/clock.hpp>

#include <data/color.hpp>
#include <data/frame_tl.hpp>

#include <service/base.hpp>

namespace sight::service
{

/// Tracking quality, the lowest values are, better tracking is.
enum class tracking_quality_t : std::uint8_t
{
    tracked = 0,             ///< fully tracked.
    partially_out_of_volume, ///< partially out of volume.
    error_on_detection,      ///< other errors that affects detection.
    untracked                ///< untracked.
};

// Structure to deal with sensors.
struct SIGHT_SERVICE_CLASS_API sensor_t
{
    std::string name;                      // name of the tool
    std::string tracked_color {"#FFFFFF"}; // tracked color
    bool optional {false};                 // Requires the sensor to be plugged
    std::size_t tl_index {0};              // index on the timeline

    tracking_quality_t current_tracking_quality {tracking_quality_t::untracked}; // tracking quality
    std::string current_status;                                                  // current status
                                                                                 // (tracked/missing/...)

    // signal names
    std::string detected_sig_name;
    std::string undetected_sig_name;
    std::string error_in_detection_sig_name;
    std::string error_status_changed_sig_name;
    std::string change_color_sig_name;

    //------------------------------------------------------------------------------

    virtual ~sensor_t() = default;

    //------------------------------------------------------------------------------

    [[nodiscard]] virtual std::string to_string() const
    {
        std::stringstream ss;

        ss << "- name: '" << this->name << "'" << std::endl;
        ss << "- tracked_color: '" << this->tracked_color << "'" << std::endl;
        ss << "- optional: '" << this->optional << "'" << std::endl;
        ss << "- tl_index: '" << this->tl_index << "'" << std::endl;

        return ss.str();
    }

    // for debug purposes.
    friend std::ostream& operator<<(std::ostream& _os, const sensor_t& _s)
    {
        _os << _s.to_string();
        return _os;
    }
};

/**
 * @brief  This interface defines Tracker service API.
 *
 * The sub-classes must implements the method 'tracking(timestamp)' that is called by 'track' slot.
 *
 * If 'dropObj' is enabled, the sub-class 'tracking' method is called with the last timestamp in the timeline if the
 * received timestamp is greater than the last processed timestamp.
 *
 * @section Slots Slots
 * - \b track(core::clock::type  timestamp) : performs the tracking, does nothing if the tracking is
 *   not started.
 * - \b start_tracking() : start the tracking
 * - \b stop_tracking() : stop the tracking
 *
 * @subsection Input Input
 * - \b timeline : timeline used to retrieve the tracked objects
 * @subsection Configuration Configuration
 * - \b dropObj(optional, default=true) : defines if the tracker should drop few objects from the timeline (and always
 *   get the last one) or not.
 */
template<typename T>
class SIGHT_SERVICE_CLASS_API tracker : public service::base
{
public:

    SIGHT_DECLARE_SERVICE(tracker, service::base);

    using void_t = sight::core::com::signal<void ()>;

    struct signals
    {
        using void_t = sight::core::com::signal<void ()>;
        using bool_t = sight::core::com::signal<void (bool)>;

        using data_color_t = sight::data::color::sptr;
        using color_t      = sight::core::com::signal<void (data_color_t)>;
        using tracking_t   = sight::core::com::signal<void ()>;

        static inline const sight::core::com::signals::key_t TRACKING_STARTED = "tracking_started";
        static inline const sight::core::com::signals::key_t TRACKING_STOPPED = "tracking_stopped";
    };

    struct slots
    {
        using key_t = sight::core::com::slots::key_t;

        static inline const key_t START_TRACKING = "start_tracking";
        static inline const key_t STOP_TRACKING  = "stop_tracking";
    };

    struct color_codes
    {
        static inline const std::string GREEN  = "#00FF00";
        static inline const std::string ORANGE = "#FFA500";
        static inline const std::string RED    = "#FF0000";
    };

    static const core::com::slots::key_t TRACK_SLOT;

    static constexpr std::string_view TIMELINE_INPUT = "timeline";
    static constexpr std::string_view FRAME_INOUT    = "frame";

    /// Defines the auto-connection between the timeline and the 'track' slot
    service::connections_t auto_connections() const override;

    /// Return true if the tracking is started.
    bool is_tracking() const
    {
        return m_is_tracking;
    }

    /// Enable/Disable drop
    void enable_drop(bool _enable)
    {
        m_drop_obj = _enable;
    }

    /// Return true if tracker drop frames
    bool is_dropping() const
    {
        return m_drop_obj;
    }

protected:

    std::vector<T> m_sensors;

    ///@brief tracker constructor. Do nothing.
    tracker();

    ///@brief tracker destructor. Do nothing.
    ~tracker() override = default;

    virtual void setup_tool(
        const boost::property_tree::ptree& _config,
        T& _tool,
        std::size_t _index = 0
    );

    void configuring() override;
    void configuring(const config_t& _config) override;

    /**
     * @brief This method calls tracking.
     * If m_dropObj is true, tracking is called only if the given timestamp is greater than m_lastTimestamp.
     * @warning If tracking is stopped, this method does nothing.
     * @note You should connect this method to the input timeline
     */
    virtual void track(core::clock::type _timestamp);

    /// start the tracking
    virtual void start_tracking();

    /// stop the tracking
    virtual void stop_tracking();

    /**
     * @brief process the tracking
     * @param[in,out] _timestamp the timestamp of the processes object of the timeline
     */
    SIGHT_SERVICE_API virtual void tracking(core::clock::type& _timestamp) = 0;

    /// timestamp of the last tracking
    core::clock::type m_last_timestamp {0};

    /// If true, only last object is retrieved
    bool m_drop_obj {true};

    /// If false, the trackMethod does nothing
    std::atomic_bool m_is_tracking {false};

    sight::data::ptr<sight::data::frame_tl, sight::data::access::in> m_timeline {this, TIMELINE_INPUT};
};

} // namespace sight::service