Vanetza
 
Loading...
Searching...
No Matches
limeric_budget.cpp
1#include "duty_cycle_permit.hpp"
2#include "limeric_budget.hpp"
3#include <vanetza/common/runtime.hpp>
4#include <chrono>
5#include <cmath>
6
7namespace vanetza
8{
9namespace dcc
10{
11
12namespace
13{
14constexpr Clock::duration min_interval = std::chrono::milliseconds(25);
15constexpr Clock::duration max_interval = std::chrono::seconds(1);
16} // namespace
17
18LimericBudget::LimericBudget(const DutyCyclePermit& dcp, const Runtime& rt) :
19 m_duty_cycle_permit(dcp), m_runtime(rt),
20 m_interval(min_interval), m_tx_start(Clock::time_point::min()),
21 m_tx_on(Clock::duration::zero())
22{
23 update();
24}
25
26Clock::duration LimericBudget::delay()
27{
28 Clock::duration delay = Clock::duration::max();
29 if (m_runtime.now() >= m_tx_start + m_interval) {
30 delay = Clock::duration::zero();
31 } else {
32 delay = m_tx_start + m_interval - m_runtime.now();
33 }
34 return delay;
35}
36
37Clock::duration LimericBudget::interval()
38{
39 return m_interval;
40}
41
42void LimericBudget::notify(Clock::duration tx_on)
43{
44 m_tx_start = m_runtime.now();
45 m_tx_on = tx_on;
46
47 using std::chrono::duration_cast;
48 const auto duty_cycle = m_duty_cycle_permit.permitted_duty_cycle();
49 const auto interval = duration_cast<Clock::duration>(tx_on / duty_cycle.value());
50 m_interval = clamp_interval(interval);
51}
52
53void LimericBudget::update()
54{
55 using std::chrono::duration_cast;
56 using FloatingPointDuration = std::chrono::duration<double, Clock::period>;
57 const FloatingPointDuration delay = m_tx_start + m_interval - m_runtime.now();
58 const double duty_cycle = m_duty_cycle_permit.permitted_duty_cycle().value();
59
60 if (duty_cycle > 0.0) {
61 if (delay.count() > 0.0) {
62 // Apply equation B.2 of TS 102 687 v1.2.1 if gate is closed at the moment
63 const FloatingPointDuration interval = (m_tx_on / duty_cycle) * (delay / m_interval);
64 m_interval = clamp_interval(duration_cast<Clock::duration>(interval) + m_runtime.now() - m_tx_start);
65 } else {
66 // use equation B.1 otherwise
67 const FloatingPointDuration interval = m_tx_on / duty_cycle;
68 m_interval = clamp_interval(duration_cast<Clock::duration>(interval));
69 }
70 } else {
71 // bail out with maximum interval if duty cycle is not positive
72 m_interval = max_interval;
73 }
74}
75
76Clock::duration LimericBudget::clamp_interval(Clock::duration interval) const
77{
78 return std::min(std::max(interval, min_interval), max_interval);
79}
80
81} // namespace dcc
82} // namespace vanetza