59 : TclClass(
"Module/UW/RANGING_TOKENBUS")
67 create(
int argc,
const char *
const *argv)
75#define DEBUG(level, text) \
79 std::cout << NOW << " UwRangingTokenBus(" << node_id << "): " << text << std::endl; \
86 dist_num(n_nodes * (n_nodes - 1) / 2),
96 bind(
"epsilon", (
double *)&
epsilon);
97 bind(
"max_tt", (
double *)&
max_tt);
106 for (
size_t ni = 0; ni <
n_nodes; ni++)
108 for (
size_t nj = ni + 1; nj <
n_nodes; nj++)
117 for (
size_t ni = 0; ni <
n_nodes; ni++)
120 for (
size_t n = ni + 2; n < ni +
n_nodes; n++)
147 hdr_cmn *ch = HDR_CMN(p);
148 hdr_mac *mach = HDR_MAC(p);
150 int dest_mac = mach->macDA();
151 int pkt_token_id = tbh->
tokenId();
152 int pkt_node_id =
NMOD(pkt_token_id);
153 DEBUG(10,
" Phy2MacEndRx(); pkt token_id : " << pkt_token_id <<
" macSA: " << mach->macSA() <<
" macDA: " << mach->macDA())
162 DEBUG(3,
"Phy2MacEndRx() dropping pkt with errors")
165 else {incrErrorPktsRx();}
178 DEBUG(4,
" received a ping with pkt_token_id: " << pkt_token_id <<
" from ID " <<
NMOD(pkt_token_id - 1))
189 for (
size_t i = 0; i < (tbrh->
times()).size(); i++)
191 if(tbrh->
times()[i] >= 0) {
201 <<
" and times_mat[" <<
NMOD(pkt_node_id - 1) <<
"] = ")
204 std::cout <<
times_mat.at(
NMOD(pkt_token_id-1)).at(i) <<
" ";
206 std::cout << std::endl;
220 DEBUG(4,
"Received the token")
223 else if (pkt_node_id <
node_id)
232 DEBUG(0,
" received a pkt with invalid token id")
239 else if ((dest_mac != addr) && (dest_mac != BCAST_ADDR))
255 else {incrErrorPktsRx();}
256 DEBUG(0,
" discard packet rx while tx; pkt token_id : " << pkt_token_id <<
" macSA: " << mach->macSA() <<
" macDA: " << mach->macDA())
265 DEBUG(0,
" attempt to send token without owning it ")
269 Packet *p = Packet::alloc();
270 hdr_cmn *ch = HDR_CMN(p);
271 hdr_mac *mach = HDR_MAC(p);
275 mach->set(MF_CONTROL, addr, BCAST_ADDR);
276 mach->macDA() = BCAST_ADDR;
288 (tbrh->
times()).push_back((-1.));
309 DEBUG(4,
" sending TOKEN to node: " <<
NMOD(token_id) <<
" tokenid: " << token_id <<
" token hold: " << tbrh->
token_hold() <<
" from mac " << mach->macSA() <<
" to mach " << mach->macDA())
310 DEBUG(10,
"pkt size: "<<ch->size() <<
" tx duration: "<< Mac2PhyTxDuration(p))
317 std::vector<double> y;
318 auto x_full = std::vector<std::vector<double>>(
dist_num);
319 auto dist_mask = std::vector<bool>(
dist_num,
false);
321 size_t i_valid_eq = 0;
322 for (
size_t n = 0; n <
n_nodes; n++)
324 for (
size_t t = 0; t <
n_nodes - 1; t++)
329 for (
size_t coeff = 0; coeff <
dist_num; coeff++)
331 (x_full[coeff]).push_back(
x_mat[i_eq][coeff]);
332 if (
x_mat[i_eq][coeff])
334 dist_mask[coeff] =
true;
344 size_t count_valid_dist = 0;
345 for (
size_t i = 0; i <
dist_num; i++)
353 std::vector<std::vector<double>> a;
354 for (
size_t i = 0; i <
dist_num; i++)
358 a.push_back(x_full[i]);
362 if (count_valid_dist <= y.size())
364 auto solution = std::vector<double>(count_valid_dist, -1.0);
370 for (
size_t i = 0, j = 0; i <
dist_num; i++)
372 if (dist_mask[i] && solution[j] >= 0.0 && solution[j] <=
max_tt)
382 DEBUG(0,
" nnleast_squares() TIMEOUT! keeping old distances vector")
386 DEBUG(0,
" nnleast_squares() ERROR! keeping old distances vector")
394 Tcl &tcl = Tcl::instance();
397 if (strcasecmp(argv[1],
"calc_distances") == 0)
405 if (strcasecmp(argv[1],
"get_distance") == 0)
407 int n1 = atoi(argv[2]);
408 int n2 = atoi(argv[3]);
409 if (n1 >= 0 && n1 < n_nodes && n2 >= 0 && n2 <
n_nodes)
412 tcl.resultf(
"%.17f",0.);
Class that represent the binding of the protocol with tcl.
TclObject * create(int argc, const char *const *argv)
Creates the TCL object needed for the tcl language interpretation.
UwRangingTokenBusModuleClass()
Constructor of the UwRangingTokenBusModule class.
Class that represents a TokenBus Node.
const int dist_num
num of distances: will be initialized to n_nodes*(n_nodes-1)/2
std::vector< std::vector< double > > times_mat
vector of shape [n_nodes][n_nodes-1] holds the travel times: the first index is the node_id which has...
int id_last_range
node id from which I received the last ranging pkt
virtual void computeDist()
compute the linear regression and updates the distances vector
double max_tt
max travel time between nodes in seconds, used to discard bad nnleast_squares() results
virtual bool validToken(Packet *p) const override
Assert if the received token id is valid, i.e it follows the monotonic progression taking in account ...
virtual ~UwRangingTokenBus()
Destructor of the TokenBus class.
std::vector< double > distances
vector of shape [D], contains the one way travel times between nodes to be transformed to distances b...
std::vector< std::vector< int > > dist_map
of size [n_nodes][n_nodes] maps(nodeX,nodeY) -> distance
double time_last_range
time of last ping reception (or transmission)
std::vector< std::vector< int > > times_age
vector of shape [n_nodes][n_nodes-1] holds the age of a time (slot number in which the time was calcu...
virtual void sendToken(int next_id) override
Passes the token to the next node.
std::vector< std::vector< double > > x_mat
of size [2D][D] it's the sparse matrix with the equations coefficients (-1,0,1)
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
virtual void Phy2MacEndRx(Packet *p) override
Method called when the Phy Layer finish to receive a Packet.
UwRangingTokenBus()
Default constructor of the TokenBus class.
double epsilon
difference between virtually equal distances can result in small negative numbers due to floating poi...
Class that represents a TokenBus Node.
UWTokenBus_STATUS rtx_status
double min_token_hold_time
if the node has en empty queue when it receive the token, it waits this time before passing the token
int debug
Debug variable: 0 for no info.
TimerBusIdle bus_idle_timer
token_pass_timer is scheduled when a node pass the token, it's cancelled when activity from the follo...
int n_nodes
number of nodes in the ring
virtual int normId(int id) const
virtual void Mac2PhyStartTx(Packet *p)
Method called when the Mac Layer start to transmit a Packet.
virtual int command(int argc, const char *const *argv) override
TCL command interpreter.
constexpr int NMOD(int n)
given any int returns the corresponding node id via modulo operations
double bus_idle_timeout
base timeout for the namesake timer should be (slot_time+max_token_hold_time)
double token_rx_time
time of token reception
TimerTokenPass token_pass_timer
int last_token_id_heard
last token id heard on the bus
bool got_token
set if node is currently holding the token
int last_token_id_owned
last token id owned
int node_id
id of the node (0 to n_nodes-1)
virtual void txData()
Starts transmitting the packets from the queue.
virtual bool validToken(Packet *p) const
Assert if the received token id is valid, i.e it follows the monotonic progression taking in account ...
LeastSqResult nnLeastSquares(std::vector< std::vector< double > > a, std::vector< double > b, std::vector< double > &x, double *resid=nullptr)
Least Squares Linear Regressor solves the least squares problem A * X = B, X>=0.
Header of the token bus protocol.
size_t getSize() const
Returns the size of this header.
tokenid_t & tokenId()
Returns a reference to the token_id variable.
Header of the token bus protocol.
std::vector< uwrange_time_t > & times()
Returns a reference to the travel times array.
size_t getSize() const
Returns the size of this header.
bool & token_resend()
Returns a reference to token_resend_.
uwrange_time_t & token_hold()
Returns a reference to token_hold_ value.
UwRangingTokenBusModuleClass class_module_uwranging_tokenbus
packet_t PT_UWRANGING_TOKENBUS
Provides the definition of the class UwRangingTokenBus.
packet_t PT_UWRANGING_TOKENBUS
Common structures and variables in the protocol.
#define HDR_UWRANGING_TOKENBUS(p)
alias defined to access the TOKEN BUS HEADER
#define DEBUG(level, text)
#define HDR_TOKENBUS(p)
alias defined to access the TOKEN BUS HEADER