Files
salmanoff/include/user/stimulusProducer.h
T

117 lines
3.1 KiB
C++
Raw Normal View History

2025-11-14 19:50:51 -04:00
#ifndef _STIMULUS_PRODUCER_H
#define _STIMULUS_PRODUCER_H
2025-10-25 18:56:30 -04:00
2025-11-06 15:03:26 -04:00
#include <boostAsioLinkageFix.h>
2025-10-25 18:56:30 -04:00
#include <vector>
#include <memory>
#include <cstdint>
#include <atomic>
#include <mutex>
#include <functional>
#include <iostream>
#include <chrono>
#include <config.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <spinLock.h>
2025-10-25 19:42:48 -04:00
#include "deviceAttachmentSpec.h"
2025-10-25 18:56:30 -04:00
namespace smo {
namespace stim_buff {
2025-11-14 23:19:32 -04:00
// Forward declaration
class StimulusBuffer;
2025-10-25 18:56:30 -04:00
/**
2025-11-14 19:50:51 -04:00
* StimulusProducer manages a collection of stimulus frames with simultaneity stamps.
2025-10-25 18:56:30 -04:00
*
2025-11-14 19:50:51 -04:00
* This producer is designed to hold stimulus frames that have been assembled
2025-10-25 18:56:30 -04:00
* from raw sensor data (e.g., Livox Avia point cloud data) and are ready
* for processing by the mind layer.
*
2025-11-14 19:50:51 -04:00
* The producer provides thread-safe operations for adding frames, retrieving
* frames, and managing the producer state.
2025-10-25 18:56:30 -04:00
*/
2025-11-14 19:50:51 -04:00
class StimulusProducer
2025-10-25 18:56:30 -04:00
{
public:
2025-11-14 19:50:51 -04:00
explicit StimulusProducer(
const std::shared_ptr<device::DeviceAttachmentSpec>
&deviceAttachmentSpec,
2025-11-04 00:49:15 -04:00
boost::asio::io_service& ioService_)
: deviceAttachmentSpec(deviceAttachmentSpec),
2025-11-04 00:49:15 -04:00
ioService(ioService_),
shouldContinue(false), timer(ioService),
nDeferrals(0)
2025-10-25 23:04:12 -04:00
{}
2025-11-14 19:50:51 -04:00
virtual ~StimulusProducer() = default;
2025-10-25 18:56:30 -04:00
// Non-copyable, movable
2025-11-14 19:50:51 -04:00
StimulusProducer(const StimulusProducer&) = delete;
StimulusProducer& operator=(const StimulusProducer&) = delete;
StimulusProducer(StimulusProducer&&) = default;
StimulusProducer& operator=(StimulusProducer&&) = default;
2025-10-25 18:56:30 -04:00
// Control methods
2025-11-01 22:03:28 -04:00
virtual void start()
{
2025-11-14 19:50:51 -04:00
std::cout << __func__ << ": Starting stimulus producer for device "
<< deviceAttachmentSpec->deviceSelector << std::endl;
shouldContinue = true;
nDeferrals = 0;
scheduleNextTimeout();
}
2025-11-01 22:03:28 -04:00
virtual void stop();
void allowNextStimulusFrame()
{ frameAssemblyRateLimiter.release(); }
virtual std::shared_ptr<StimulusBuffer> getAttachedStimulusBuffer(
2025-11-14 23:19:32 -04:00
const std::shared_ptr<device::DeviceAttachmentSpec>& spec) const;
virtual std::shared_ptr<StimulusBuffer> getOrCreateAttachedStimulusBuffer(
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
int histbuffMs) = 0;
// Check if any attached buffer has the specified qualeIfaceApi
bool hasBufferWithQualeIfaceApi(const std::string& qualeIfaceApi) const;
protected:
SpinLock frameAssemblyRateLimiter;
// Virtual functions for derived classes to override
virtual int getStopDelayMs() const
{
return CONFIG_STIMBUFF_FRAME_PERIOD_MS;
}
virtual void stimFrameProductionTimesliceInd() = 0;
private:
void onTimeout(const boost::system::error_code& error);
2025-10-25 23:04:12 -04:00
public:
std::shared_ptr<device::DeviceAttachmentSpec> deviceAttachmentSpec;
2025-11-14 23:19:32 -04:00
std::vector<std::shared_ptr<StimulusBuffer>> attachedStimulusBuffers;
private:
boost::asio::io_service& ioService;
protected:
SpinLock shouldContinueLock;
bool shouldContinue;
private:
boost::asio::deadline_timer timer;
size_t nDeferrals;
std::chrono::high_resolution_clock::time_point deferralStartTime;
void scheduleNextTimeout(int delayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS);
};
2025-10-25 18:56:30 -04:00
} // namespace stim_buff
} // namespace smo
2025-11-14 19:50:51 -04:00
#endif // _STIMULUS_PRODUCER_H