/**
* @file tests/pdevs/models.hpp
* @author The PARADEVS Development Team
* See the AUTHORS or Authors.txt file
*/
/*
* PARADEVS - the multimodeling and simulation environment
* This file is a part of the PARADEVS environment
*
* Copyright (C) 2013-2015 ULCO http://www.univ-litoral.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef TESTS_PDEVS_MODELS_HPP
#define TESTS_PDEVS_MODELS_HPP 1
#include
#include
#include
#include
#define DELAY 100
namespace paradevs { namespace tests { namespace pdevs {
void delay()
{
for (unsigned int i = 0; i < DELAY; ++i) {
std::vector < int > v;
for (unsigned int j = 1000; j > 0; --j) {
v.push_back(j);
}
std::sort(v.begin(), v.end());
}
}
struct data
{
double x;
double y;
data() : x(0), y(0)
{ }
data(double _x, double _y) : x(_x), y(_y)
{ }
};
class A :
public paradevs::pdevs::Dynamics < common::DoubleTime >
{
public:
A(const std::string& name, const common::NoParameters& parameters) :
paradevs::pdevs::Dynamics < common::DoubleTime >(name, parameters)
{ }
virtual ~A()
{ }
void dint(typename common::DoubleTime::type t)
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_INT);
common::Trace < common::DoubleTime >::trace().flush();
#endif
delay();
++_value.x;
--_value.y;
std::cout << t << ": " << get_name() << " => dint -> "
<< _value.x << " " << _value.y << std::endl;
if (_phase == SEND) {
_phase = WAIT;
}
}
void dext(typename common::DoubleTime::type t,
typename common::DoubleTime::type /* e */,
const common::Bag < common::DoubleTime >& msgs)
{
#ifndef WITH_TRACE
(void)t;
(void)msgs;
#endif
for (common::Bag < common::DoubleTime >::const_iterator it =
msgs.begin(); it != msgs.end(); ++it) {
std::cout << t << ": " << get_name()
<< " => " << it->get_content().get_content < double >()
<< std::endl;
}
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_EXT)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
_phase = SEND;
}
void dconf(typename common::DoubleTime::type t,
typename common::DoubleTime::type /* e */,
const common::Bag < common::DoubleTime >& msgs)
{
#ifndef WITH_TRACE
(void)t;
(void)msgs;
#endif
std::cout << t << ": " << get_name() << " => " << msgs.to_string()
<< std::endl;
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_CONF)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
}
typename common::DoubleTime::type start(typename common::DoubleTime::type t)
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::START);
common::Trace < common::DoubleTime >::trace().flush();
#endif
_phase = WAIT;
return 0;
}
typename common::DoubleTime::type ta(
typename common::DoubleTime::type t) const
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::TA);
common::Trace < common::DoubleTime >::trace().flush();
#endif
if (_phase == WAIT) {
return 1;
} else {
return 0;
}
}
common::Bag < common::DoubleTime > lambda(
typename common::DoubleTime::type t) const
{
#ifndef WITH_TRACE
(void)t;
#endif
common::Bag < common::DoubleTime > msgs;
msgs.push_back(
common::ExternalEvent < common::DoubleTime >(
"out", common::Value(_value)));
std::cout << t << ": " << get_name() << " => lambda" << std::endl;
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::LAMBDA)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
return msgs;
}
void observation(std::ostream& /* file */) const
{ }
private:
enum Phase { WAIT, SEND };
Phase _phase;
data _value;
};
class B :
public paradevs::pdevs::Dynamics < common::DoubleTime >
{
public:
B(const std::string& name, const common::NoParameters& parameters) :
paradevs::pdevs::Dynamics < common::DoubleTime >(name, parameters),
_value(0)
{ }
virtual ~B()
{ }
void dint(typename common::DoubleTime::type t)
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_INT);
common::Trace < common::DoubleTime >::trace().flush();
#endif
delay();
++_value;
std::cout << t << ": " << get_name() << " => dint -> "
<< _value << std::endl;
if (_phase == SEND) {
_phase = WAIT;
}
}
void dext(typename common::DoubleTime::type t,
typename common::DoubleTime::type /* e */,
const common::Bag < common::DoubleTime >& msgs)
{
#ifndef WITH_TRACE
(void)t;
(void)msgs;
#endif
for (common::Bag < common::DoubleTime >::const_iterator it =
msgs.begin(); it != msgs.end(); ++it) {
std::cout << t << ": " << get_name()
<< " => " << it->get_content().get_content < data >().x
<< " " << it->get_content().get_content < data >().y
<< std::endl;
}
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_EXT)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
_phase = SEND;
}
void dconf(typename common::DoubleTime::type t,
typename common::DoubleTime::type /* e */,
const common::Bag < common::DoubleTime >& msgs)
{
#ifndef WITH_TRACE
(void)t;
(void)msgs;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::DELTA_CONF)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
}
typename common::DoubleTime::type start(typename common::DoubleTime::type t)
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::START);
common::Trace < common::DoubleTime >::trace().flush();
#endif
_phase = WAIT;
return std::numeric_limits < double >::max();
}
typename common::DoubleTime::type ta(
typename common::DoubleTime::type t) const
{
#ifndef WITH_TRACE
(void)t;
#endif
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::TA);
common::Trace < common::DoubleTime >::trace().flush();
#endif
if (_phase == WAIT) {
return std::numeric_limits < double >::max();
} else {
return 0;
}
}
common::Bag < common::DoubleTime > lambda(
typename common::DoubleTime::type t) const
{
#ifndef WITH_TRACE
(void)t;
#endif
common::Bag < common::DoubleTime > msgs;
std::cout << t << ": " << get_name() << " => lambda" << std::endl;
msgs.push_back(common::ExternalEvent <
common::DoubleTime >(
"out", common::Value(_value)));
#ifdef WITH_TRACE
common::Trace < common::DoubleTime >::trace()
<< common::TraceElement < common::DoubleTime >(
get_name(), t,
common::LAMBDA)
<< "messages = " << msgs.to_string();
common::Trace < common::DoubleTime >::trace().flush();
#endif
return msgs;
}
void observation(std::ostream& /* file */) const
{ }
private:
enum Phase { WAIT, SEND };
Phase _phase;
double _value;
};
class TwoStateModel :
public paradevs::pdevs::Dynamics < common::DoubleTime >
{
public:
TwoStateModel(const std::string& name,
const common::NoParameters& parameters) :
paradevs::pdevs::Dynamics < common::DoubleTime >(name, parameters)
{ }
virtual ~TwoStateModel()
{ }
void dint(typename common::DoubleTime::type t)
{
if (_phase == S1) {
_phase = S2;
} else if (_phase == S2) {
_phase = S1;
}
_last_time = t;
}
typename common::DoubleTime::type start(
typename common::DoubleTime::type t)
{
_phase = S1;
_last_time = t;
return ta(t);
}
typename common::DoubleTime::type ta(
typename common::DoubleTime::type /* t */) const
{
if (_phase == S1) {
return 5;
} else {
return 6;
}
}
common::Bag < common::DoubleTime > lambda(
typename common::DoubleTime::type t) const
{
std::cout << (t - _last_time) << std::endl;
return common::Bag < common::DoubleTime >();
}
private:
enum Phase { S1, S2 };
Phase _phase;
typename common::DoubleTime::type _last_time;
};
class ThreeStateModel :
public paradevs::pdevs::Dynamics < common::DoubleTime >
{
public:
ThreeStateModel(const std::string& name,
const common::NoParameters& parameters) :
paradevs::pdevs::Dynamics < common::DoubleTime >(name, parameters)
{ }
virtual ~ThreeStateModel()
{ }
void compute()
{
for (unsigned int i = 0; i < heights.size(); ++i) {
if (heights[i] != -1 and heights[i] < 10) {
heights[i] += speeds[i] * scales[i];
}
}
}
void display() const
{
for (std::vector < double >::const_iterator it = heights.begin();
it != heights.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
void display_full() const
{
unsigned int i = 1;
for (std::vector < double >::const_iterator it = heights.begin();
it != heights.end(); ++it, ++i) {
if (*it > 10) {
std::cout << "S" << i;
}
}
std::cout << std::endl;
}
bool full() const
{
unsigned int n = 0;
for (std::vector < double >::const_iterator it = heights.begin();
it != heights.end(); ++it) {
if (*it > 10) {
++n;
}
}
return n > 0;
}
bool full_N() const
{
unsigned int n = 0;
for (std::vector < double >::const_iterator it = heights.begin();
it != heights.end(); ++it) {
if (*it == -1) {
++n;
}
}
return n >= 2;
}
void mark_full(typename common::DoubleTime::type t)
{
for (std::vector < double >::iterator it = heights.begin();
it != heights.end(); ++it) {
if (*it > 10) {
*it = -1;
_last_time = t;
}
}
}
void raz()
{
for (std::vector < double >::iterator it = heights.begin();
it != heights.end(); ++it) {
if (*it == -1) {
*it = 0;
}
}
}
void dint(typename common::DoubleTime::type t)
{
mark_full(t);
if (full_N()) {
raz();
}
compute();
}
typename common::DoubleTime::type start(
typename common::DoubleTime::type t)
{
heights = { 0, 0, 0, 0, 0 };
speeds = { 0.21, 0.3, 0.7, 0.56, 0.14 };
scales = { 1, 1, 1, 1, 1 };
_last_time = t;
return 0;
}
typename common::DoubleTime::type ta(
typename common::DoubleTime::type /* t */) const
{ return 1; }
common::Bag < common::DoubleTime > lambda(
typename common::DoubleTime::type t) const
{
if (full()) {
std::cout << (t - _last_time) << " ";
// display_full();
}
return common::Bag < common::DoubleTime >();
}
private:
std::vector < double > heights;
std::vector < double > speeds;
std::vector < double > scales;
typename common::DoubleTime::type _last_time;
};
} } } // namespace paradevs tests pdevs
#endif