text:
/**
 * @file    rpi/src/System.hpp
 *
 * @brief   System main class headers
 *
 * Provides access to the distributed system.
 * Keeps track of current state and logs heuristics.
 *
 * @author  João Borrego
 *
 */

#ifndef SYSTEM_HPP
#define SYSTEM_HPP

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <ctime>
#include <vector>
#include <list>
#include <algorithm>
#include <chrono>
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include "debug.hpp"
#include "constants.hpp"
#include "communication.hpp"

/** Flag for obtaining lux values */
#define GET_LUX         0
/** Flag for obtaining duty cycle values */
#define GET_DUTY_CYCLE  1

/**
 * @brief      Class for entry.
 */
class Entry
{

public:

    /** Entry timestamp */
    unsigned long timestamp;
    /** Registered lux value */
    float lux;
    /** Registered duty cycle */
    float duty_cycle;
    /** Reference illuminance */
    float lux_reference;
    /** Comfort error */
    float c_err;
    /** Comfort variance */
    float c_var;

    /**
     * @brief      Constructs an entry.
     *
     * @param[in]  timestamp_      The timestamp
     * @param[in]  lux_            The lux
     * @param[in]  duty_cycle_     The duty cycle
     * @param[in]  lux_reference_  The lux reference
     * @param[in]  c_err_          The comfort error
     * @param[in]  c_var_          The comfort variance
     */
    Entry(
        unsigned long timestamp_,
        float lux_,
        float duty_cycle_,
        float lux_reference_,
        float c_err_,
        float c_var_)
        : timestamp(timestamp_),
          lux(lux_),
          duty_cycle(duty_cycle_),
          lux_reference(lux_reference_),
          c_err(c_err_),
          c_var(c_var_){}
};

/**
 * @brief      Class for system.
 */
class System
{

public:

    /** System shared pointer public type definition */
    typedef boost::shared_ptr< System > ptr;

private:

    /** Number of nodes in the system */
    size_t nodes_;
    /** Sampling period */
    float sample_period_;
    /** System initialisation timestamp */
    unsigned long start_;

    /* Direct measurements */

    /** Mutex for thread-safe data access */
    boost::shared_mutex mutex_;
    /** Registered log entries */
    std::vector < std::vector< Entry > > entries_;

    /** Illuminance lower bound for each desk */
    std::vector< float > lux_lower_bound_;
    /** External illuminance for each desk */
    std::vector< float > lux_external_;
    /** Current occupancy for each desk */
    std::vector< bool > occupancy_;

    /* Communication handles */

    /** I/O Service for synchronous Serial communications */
    boost::asio::io_service io_serial_;
    /** I/O Service for asynchronous I2C communications */
    boost::asio::io_service io_i2c_;

    /* Synchronous Serial connection for outgoing commands */
    boost::asio::serial_port serial_port_;
    /** Asynchronous I2C sniffer for incoming information */
    boost::asio::posix::stream_descriptor i2c_;
    /** I2C pipe file descriptor */
    int i2c_fd_;
    /** I2C receive buffer */
    uint8_t i2c_buffer_[RECV_BUFFER];

public:

    /**
     * @brief      Constructs a system.
     *
     * @param[in]  nodes   The number of nodes in the system
     * @param[in]  t_s     The period of the system information feed
     * @param[in]  serial  The Serial port identifier
     * @param[in]  i2c     The I2C packet stream FIFO path
     */
    System(
        size_t nodes,
        float t_s,
        const std::string & serial,
        const std::string & i2c)
        : nodes_(nodes),
          sample_period_(t_s),
          entries_(nodes * STREAM_FLAGS, std::vector < Entry >()),
          lux_lower_bound_(nodes),
          lux_external_(nodes),
          occupancy_(nodes),
          serial_port_(io_serial_),
          i2c_(io_i2c_)
    {
        start(serial, i2c);
    }

    /**
     * @brief      Obtains the number of milliseconds since last reset.
     *
     * @return     The number of milliseconds since last reset.
     */
    unsigned long millis(){
        auto now = std::chrono::system_clock::now();
        auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
        auto value = now_ms.time_since_epoch();
        unsigned long absolute = value.count();
        unsigned long relative = absolute - start_;
        return relative;
    }

    /**
     * @brief      Gets the number of nodes in the system.
     *
     * @return     The number of nodes in the system.
     */
    size_t getNodes();

    /**
     * @brief      Initialises System interfaces.
     *
     * @param[in]  serial  The Serial port name
     * @param[in]  i2c     The I2C packet stream FIFO
     */
    void start(const std::string & serial, const std::string & i2c);

    /**
     * @brief      Resets the system.
     *
     * Resets the physical system and clears logs.
     *
     */
    void reset();

    /**
     * @brief      Run I2C dedicated I/O service handle
     */
    void runI2C();

    /**
     * @brief      Run Serial dedicated I/O service handle
     */
    void runSerial();

    /**
     * @brief      Starts an I2C read.
     */
    void startRead();

    /**
     * @brief      Prepares an I2C read operation
     *
     * @param[in]  error              The error
     * @param[in]  bytes_transferred  The bytes transferred
     */
    void handleRead(const boost::system::error_code & error,
        size_t bytes_transferred);

    /**
     * @brief      Starts a write to Serial.
     *
     * @param[in]  msg   The message
     */
    void startWriteSerial(const std::string & msg);

    /**
     * @brief      Handles a write to Serial
     *
     * @param[in]  error              The error
     * @param[in]  bytes_transferred  The bytes transferred
     */
    void handleWriteSerial(const boost::system::error_code & error,
        size_t bytes_transferred);

    /**
     * @brief      Inserts an entry in the log.
     *
     * @param[in]  id             The identifier
     * @param[in]  timestamp      The timestamp
     * @param[in]  lux            The lux
     * @param[in]  duty_cycle     The duty cycle
     * @param[in]  lux_reference  The lux reference
     * @param[in]  c_err          The c error
     * @param[in]  c_var          The c variable
     */
    void insertEntry(
        size_t id,
        unsigned long timestamp,
        float lux,
        float duty_cycle,
        float lux_reference,
        float c_err,
        float c_var);

    /**
     * @brief      Saves entries to disk.
     */
    void saveEntries();

    /* Get */

    /**
     * @brief      Gets the latest entry.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The latest entry.
     */
    Entry *getLatestEntry(size_t id);

    /**
     * @brief      Gets the values of lux or duty cycle in a time period.
     *
     * @param[in]  id        The node identifier
     * @param[in]  start     The start
     * @param[in]  end       The end
     * @param[in]  var       The variable (LUX | DUTY_CYCLE)
     * @param      response  The output string with comma-separated values
     */
    void getValuesInPeriod(
        size_t id,
        unsigned long start,
        unsigned long end,
        char var,
        std::string & response);

    /**
     * @brief      Gets the latest lux value for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The lux.
     */
    float getLux(size_t id);

    /**
     * @brief      Gets the latest duty cycle for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The duty cycle.
     */
    float getDutyCycle(size_t id);

    /**
     * @brief      Gets the occupancy for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The occupancy.
     */
    bool getOccupancy(size_t id);

    /**
     * @brief      Gets the illuminance lower bound for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The lux lower bound.
     */
    float getLuxLowerBound(size_t id);

    /**
     * @brief      Gets the external illuminance for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The lux external.
     */
    float getLuxExternal(size_t id);

    /**
     * @brief      Gets the reference illuminance for a given desk.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The lux reference.
     */
    float getLuxReference(size_t id);

    /**
     * @brief      Gets the power for a given desk or the total power.
     *
     * @param[in]  id     The node identifier
     * @param[in]  total  Whether to calculate total power
     *
     * @return     The power.
     */
    float getPower(size_t id, bool total);

    /**
     * @brief      Computes the energy for a given node.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The energy.
     */
    float energyNode(size_t id);

    /**
     * @brief      Gets the energy for a given desk or total energy.
     *
     * @param[in]  id     The node identifier
     * @param[in]  total  Whether to calculate total energy
     *
     * @return     The energy.
     */
    float getEnergy(size_t id, bool total);

    /**
     * @brief      Computes the comfort error for a given node.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The comfort error.
     */
    float comfortErrorNode(size_t id);

    /**
     * @brief      Gets the comfort error for a given desk or total comfort error.
     *
     * @param[in]  id     The node identifier
     * @param[in]  total  Whether to calculate total comfort error
     *
     * @return     The comfort error.
     */
    float getComfortError(size_t id, bool total);

    /**
     * @brief      Computes the comfort error for a given node.
     *
     * @param[in]  id    The node identifier
     *
     * @return     The comfort error.
     */
    float comfortVarianceNode(size_t id);

    /**
     * @brief      Gets the comfort variance for a given desk or total comfort variance.
     *
     * @param[in]  id     The node identifier
     * @param[in]  total  Whether to calculate total comfort variance
     *
     * @return     The comfort variance.
     */
    float getComfortVariance(size_t id, bool total);

    /**
     * @brief      Gets the time since last reset for a given node.
     *
     * @param[in]  id  The node identifier
     *
     * @return     The time since last reset.
     */
    unsigned long getTimestamp(size_t id);
};

#endif

max_stars_repo_name: jsbruglie/scdtr

max_issues_repo_name: jsbruglie/scdtr

max_forks_repo_name: jsbruglie/scdtr


text:
// Copyright 2015 Nikita Chudinov

#include "config.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

ConfigParser::ConfigParser(const std::string &config_file) {
    using boost::property_tree::ptree;
    ptree pt;

    read_json(config_file, pt);
    sleep_duration = pt.get("sleep_duration", 3600);
    path_list_file = pt.get("path_list_file", "path_list.json");

    std::string s = pt.get("log_severity", "warning");

    if (!s.compare("warning")) {
        log_severity = plog::warning;
    } else if (!s.compare("info")) {
        log_severity = plog::info;
    }

    log_filename = pt.get("log_filename", "integrity.log");
}

int ConfigParser::GetSleepDuration() const {
    return sleep_duration;
}

std::string ConfigParser::GetPathListFile() const {
    return path_list_file;
}

plog::Severity ConfigParser::GetLogSeverity() const {
    return log_severity;
}

std::string ConfigParser::GetLogFilename() const {
    return log_filename;
}

ext: cpp

max_stars_repo_name: Monory/file-integrity

max_issues_repo_name: Monory/file-integrity

max_forks_repo_name: Monory/file-integrity


text:
#include "sv/util/eigen.h"

#include <Eigen/Cholesky>

#include "sv/util/logging.h"

namespace sv {

void StableRotateBlockTopLeft(MatrixXdRef H,
                              VectorXdRef b,
                              int block_ind,
                              int block_size) {
  CHECK_EQ(H.rows(), b.size());
  CHECK_EQ(H.cols(), b.size());
  CHECK_GE(block_ind, 0);
  CHECK_GT(block_size, 0);
  CHECK_LT(block_ind * block_size, H.rows());

  if (block_ind == 0) return;
  const auto n = block_size;

  // Permute block of rows up gradually, also need to permute b
  for (int i = block_ind; i > 0; --i) {
    const auto r = i * block_size;
    // swap current rows with above rows
    H.middleRows(r, n).swap(H.middleRows(r - n, n));
    b.segment(r, n).swap(b.segment(r - n, n));
  }

  // Permute block of cols
  for (int j = block_ind; j > 0; --j) {
    const auto c = j * block_size;
    // swap current cols with left cols
    H.middleCols(c, n).swap(H.middleCols(c - n, n));
  }
}

void FillLowerTriangular(MatrixXdRef M) {
  CHECK_EQ(M.rows(), M.cols());
  M.triangularView<Eigen::Lower>() =
      M.triangularView<Eigen::Upper>().transpose();
}

void FillUpperTriangular(MatrixXdRef M) {
  CHECK_EQ(M.rows(), M.cols());
  M.triangularView<Eigen::Upper>() =
      M.triangularView<Eigen::Lower>().transpose();
}

void MakeSymmetric(MatrixXdRef M) {
  CHECK_EQ(M.rows(), M.cols());
  M += M.transpose().eval();
  M.array() /= 2.0;
}

void MargTopLeftBlock(const MatrixXdCRef& Hf,
                      const VectorXdCRef& bf,
                      MatrixXdRef Hm,
                      VectorXdRef bm,
                      int dim) {
  // Pre-condition
  // 1. Hf is square and match bsc and symmetric
  // 2. Hm is quare and match bpr
  const auto nf = bf.size();
  const auto nm = bm.size();
  CHECK_GT(dim, 0);
  CHECK_EQ(nm + dim, nf);
  CHECK_EQ(Hf.rows(), nf);
  CHECK_EQ(Hf.cols(), nf);
  CHECK_EQ(Hm.rows(), nm);
  CHECK_EQ(Hm.cols(), nm);
  CHECK_EQ(Hf, Hf.transpose()) << "\n" << Hf;

  // Hf                     bf
  // [ H00 H01 ] [ x0 ] = [ b0 ]
  // [ H10 H11 ] [ x1 ] = [ b1 ]
  // Hm = H11 - H10 * H00^-1 * H01
  // bm =  b1 - H10 * H00^-1 * b0
  const auto H01 = Hf.topRightCorner(dim, nm);
  const auto H10 = Hf.bottomLeftCorner(nm, dim);

  // Benchmark shows that simply inverse has similar speed as llt
  // However to account for rank-deficiency we use ldlt to inverse
  const auto H00_inv = Hf.topLeftCorner(dim, dim)
                           .selfadjointView<Eigen::Lower>()
                           .ldlt()
                           .solve(Eigen::MatrixXd::Identity(dim, dim))
                           .eval();

  Hm = Hf.bottomRightCorner(nm, nm);
  Hm.noalias() -= H10 * H00_inv * H01;

  const auto b0 = bf.head(dim);
  bm = bf.tail(nm);  // b1
  bm.noalias() -= H10 * (H00_inv * b0);

  // Make sure Hpr is symmetric
  MakeSymmetric(Hm);

  // Post-condition
  // 1. Hpr shape doesn't change
  // 2. Hpr is symmetric
  CHECK_EQ(Hm.rows(), nm);
  CHECK_EQ(Hm.cols(), nm);
  CHECK_EQ(Hm, Hm.transpose()) << "\n" << Hm;
}

}  // namespace sv


text:
//==================================================================================================
/*!
  @file

  @copyright 2017 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
**/
//==================================================================================================
#ifndef BOOST_SIMD_ALGORITHM_FIND_HPP_INCLUDED
#define BOOST_SIMD_ALGORITHM_FIND_HPP_INCLUDED

#include <boost/simd/range/segmented_aligned_range.hpp>
#include <boost/simd/detail/is_aligned.hpp>
#include <boost/simd/function/any.hpp>
#include <boost/simd/pack.hpp>
#include <algorithm>

namespace boost { namespace simd
{
  /*!
    @ingroup group-algo

    Returns an iterator to the first element in the range [first,last)
    for which the element equals val.
    If no such element is found, the function returns last.

    @param first  Beginning of the range of elements to find
    @param last   End of the range of elements to find
    @param val    Value to search for in the range.

    @par Requirement

      - @c first, @c last and @c out must be pointer to Vectorizable type.

      - @c val must be a scalar value convertible to the pointee type of first.

    @par Example:

       @snippet find.cpp find

    @par possible output:

       @snippet find.txt find

    @return An iterator to the first element in the range that compares equal to val.
            If no elements match, the function returns last.
  **/
  template<typename T, typename U>
  T const* find(T const* first, T const* last, U const & val)
  {
    auto pr = segmented_aligned_range(first,last);

    auto r = std::find(pr.head.begin(), pr.head.end(), val);
    if (r != pr.head.end()) return r;

    pack<T> v(val);
    auto rv = std::find_if( pr.body.begin(), pr.body.end()
                          , [&v](const pack<T>& x) { return any(v == x); }
                          );

    if (rv != pr.body.end())
    {
      pack<T> vv = *rv;
      auto z = std::find(vv.begin(), vv.end(), val);

      // If there is somethign ina vector, compute the scalar iterator to it
      return  pr.head.end()                                           //   base
            + std::distance(pr.body.begin(), rv)*pack<T>::static_size // + jump to vector
            + std::distance(vv.begin(), z);                           // + jump to element
    }

    return std::find(pr.tail.begin(), pr.tail.end(), val);
  }
} }

#endif

ext: hpp

max_stars_repo_name: SylvainCorlay/pythran

max_issues_repo_name: SylvainCorlay/pythran

max_forks_repo_name: SylvainCorlay/pythran


text:
// Copyright Paul A. Bristow 2016
// Copyright John Z. Maddock 2016

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or
//  copy at http ://www.boost.org/LICENSE_1_0.txt).

/*! \brief Graph showing use of Lambert W function to compute current
through a diode-connected transistor with preset series resistance.

\details T. C. Banwell and A. Jayakumar,
Exact analytical solution of current flow through diode with series resistance,
Electron Letters, 36(4):291-2 (2000).
DOI:  doi.org/10.1049/el:20000301

The current through a diode connected NPN bipolar junction transistor (BJT)
type 2N2222 (See https://en.wikipedia.org/wiki/2N2222 and
https://www.fairchildsemi.com/datasheets/PN/PN2222.pdf Datasheet)
was measured, for a voltage between 0.3 to 1 volt, see Fig 2 for a log plot, showing a knee visible at about 0.6 V.

The transistor parameter I sat was estimated to be 25 fA and the ideality factor = 1.0.
The intrinsic emitter resistance re was estimated from the rsat = 0 data to be 0.3 ohm.

The solid curves in Figure 2 are calculated using equation 5 with rsat included with re.

http://www3.imperial.ac.uk/pls/portallive/docs/1/7292572.PDF

*/

#include <boost/math/special_functions/lambert_w.hpp>
using boost::math::lambert_w0;
#include <boost/math/special_functions.hpp>
using boost::math::isfinite;
#include <boost/svg_plot/svg_2d_plot.hpp>
using namespace boost::svg;

#include <iostream>
// using std::cout;
// using std::endl;
#include <exception>
#include <stdexcept>
#include <string>
#include <array>
#include <vector>
#include <utility>
using std::pair;
#include <map>
using std::map;
#include <set>
using std::multiset;
#include <limits>
using std::numeric_limits;
#include <cmath> //

/*!
Compute thermal voltage as a function of temperature,
about 25 mV at room temperature.
https://en.wikipedia.org/wiki/Boltzmann_constant#Role_in_semiconductor_physics:_the_thermal_voltage

\param temperature Temperature (degrees Celsius).
*/
const double v_thermal(double temperature)
{
  BOOST_CONSTEXPR const double boltzmann_k = 1.38e-23; // joules/kelvin.
  BOOST_CONSTEXPR double charge_q = 1.6021766208e-19; // Charge of an electron (columb).
  double temp = +273; // Degrees C to K.
  return boltzmann_k * temp / charge_q;
} // v_thermal

  /*!
  Banwell & Jayakumar, equation 2, page 291.
  */
double i(double isat, double vd, double vt, double nu)
{
  double i = isat * (exp(vd / (nu * vt)) - 1);
  return i;
} //

  /*!
  Banwell & Jayakumar, Equation 4, page 291.
  i current flow = isat
  v voltage source.
  isat reverse saturation current in equation 4.
  (might implement equation 4 instead of simpler equation 5?).
  vd voltage drop = v - i* rs  (equation 1).
  vt  thermal voltage, 0.0257025 = 25 mV.
  nu junction ideality factor (default = unity), also known as the emission coefficient.
  re intrinsic emitter resistance, estimated to be 0.3 ohm from low current.
  rsat reverse saturation current

  \param v Voltage V to compute current I(V).
  \param vt Thermal voltage, for example 0.0257025 = 25 mV, computed from boltzmann_k * temp / charge_q;
  \param rsat Resistance in series with the diode.
  \param re Intrinsic emitter resistance (estimated to be 0.3 ohm from the Rs = 0 data)
  \param isat Reverse saturation current (See equation 2).
  \param nu Ideality factor (default = unity).

  \returns I amp as function of V volt.
  */

//[lambert_w_diode_graph_2
double iv(double v, double vt, double rsat, double re, double isat, double nu = 1.)
{
  // V thermal 0.0257025 = 25 mV
  // was double i = (nu * vt/r) * lambert_w((i0 * r) / (nu * vt)); equ 5.

  rsat = rsat + re;
  double i = nu * vt / rsat;
 // std::cout << "nu * vt / rsat = " << i << std::endl; // 0.000103223

  double x = isat * rsat / (nu * vt);
//  std::cout << "isat * rsat / (nu * vt) = " << x << std::endl;

  double eterm = (v + isat * rsat) / (nu * vt);
 // std::cout << "(v + isat * rsat) / (nu * vt) = " << eterm << std::endl;

  double e = exp(eterm);
//  std::cout << "exp(eterm) = " << e << std::endl;

  double w0 = lambert_w0(x * e);
//  std::cout << "w0 = " << w0 << std::endl;
  return i * w0 - isat;
} // double iv

//] [\lambert_w_diode_graph_2]

std::array<double, 5> rss = { 0., 2.18, 10., 51., 249 };  // series resistance (ohm).
std::array<double, 7> vds = { 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 };  // Diode voltage.
std::array<double, 7> lni = { -19.65, -15.75, -11.86, -7.97, -4.08, -0.0195, 3.6 }; // ln(current).

int main()
{
  try
  {
    std::cout << "Lambert W diode current example." << std::endl;

//[lambert_w_diode_graph_1
    double nu = 1.0; // Assumed ideal.
    double vt = v_thermal(25); // v thermal, Shockley equation, expect about 25 mV at room temperature.
    double boltzmann_k = 1.38e-23; // joules/kelvin
    double temp = 273 + 25;
    double charge_q = 1.6e-19; // column
    vt = boltzmann_k * temp / charge_q;
    std::cout << "V thermal " << vt << std::endl; // V thermal 0.0257025 = 25 mV
    double rsat = 0.;
    double isat = 25.e-15; //  25 fA;
    std::cout << "Isat = " << isat << std::endl;
    double re = 0.3;  // Estimated from slope of straight section of graph (equation 6).
    double v = 0.9;
    double icalc = iv(v, vt, 249., re, isat);
    std::cout << "voltage = " << v << ", current = " << icalc << ", " << log(icalc) << std::endl; // voltage = 0.9, current = 0.00108485, -6.82631
//] [/lambert_w_diode_graph_1]

    // Plot a few measured data points.
    std::map<const double, double> zero_data;  // Extrapolated from slope of measurements with no external resistor.
    zero_data[0.3] = -19.65;
    zero_data[0.4] = -15.75;
    zero_data[0.5] = -11.86;
    zero_data[0.6] = -7.97;
    zero_data[0.7] = -4.08;
    zero_data[0.8] = -0.0195;
    zero_data[0.9] =  3.9;

    std::map<const double, double>  measured_zero_data; // No external series resistor.
    measured_zero_data[0.3] = -19.65;
    measured_zero_data[0.4] = -15.75;
    measured_zero_data[0.5] = -11.86;
    measured_zero_data[0.6] = -7.97;
    measured_zero_data[0.7] = -4.2;
    measured_zero_data[0.72] = -3.5;
    measured_zero_data[0.74] = -2.8;
    measured_zero_data[0.76] = -2.3;
    measured_zero_data[0.78] = -2.0;
    // Measured from Fig 2 as raw data not available.

    double step = 0.1;
    for (int i = 0; i < vds.size(); i++)
    {
      zero_data[vds[i]] = lni[i];
      std::cout << lni[i] << "  " << vds[i] << std::endl;
    }
    step = 0.01;

    std::map<const double, double> data_2;
    for (double v = 0.3; v < 1.; v += step)
    {
      double current = iv(v, vt, 2., re, isat);
      data_2[v] = log(current);
      // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
    }
    std::map<const double, double> data_10;
    for (double v = 0.3; v < 1.; v += step)
    {
      double current = iv(v, vt, 10., re, isat);
      data_10[v] = log(current);
    //  std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
    }
    std::map<const double, double> data_51;
    for (double v = 0.3; v < 1.; v += step)
    {
      double current = iv(v, vt, 51., re, isat);
      data_51[v] = log(current);
     // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
    }
    std::map<const double, double> data_249;
    for (double v = 0.3; v < 1.; v += step)
    {
      double current = iv(v, vt, 249., re, isat);
      data_249[v] = log(current);
      // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
    }

    svg_2d_plot data_plot;

    data_plot.title("Diode current versus voltage")
      .x_size(400)
      .y_size(300)
      .legend_on(true)
      .legend_lines(true)
      .x_label("voltage (V)")
      .y_label("log(current) (A)")
      //.x_label_on(true)
      //.y_label_on(true)
      //.xy_values_on(false)
      .x_range(0.25, 1.)
      .y_range(-20., +4.)
      .x_major_interval(0.1)
      .y_major_interval(4)
      .x_major_grid_on(true)
      .y_major_grid_on(true)
      //.x_values_on(true)
      //.y_values_on(true)
      .y_values_rotation(horizontal)
      //.plot_window_on(true)
      .x_values_precision(3)
      .y_values_precision(3)
      .coord_precision(4) // Needed to avoid stepping on curves.
      .copyright_holder("Paul A. Bristow")
      .copyright_date("2016")
      //.background_border_color(black);
      ;

    // ₀ = subscript zero.
    data_plot.plot(zero_data, "I₀(V)").fill_color(lightgray).shape(none).size(3).line_on(true).line_width(0.5);
    data_plot.plot(measured_zero_data, "Rs=0 Ω").fill_color(lightgray).shape(square).size(3).line_on(true).line_width(0.5);
    data_plot.plot(data_2, "Rs=2 Ω").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
    data_plot.plot(data_10, "Rs=10 Ω").line_color(purple).shape(none).line_on(true).bezier_on(false).line_width(1);
    data_plot.plot(data_51, "Rs=51 Ω").line_color(green).shape(none).line_on(true).line_width(1);
    data_plot.plot(data_249, "Rs=249 Ω").line_color(red).shape(none).line_on(true).line_width(1);
    data_plot.write("./diode_iv_plot");

    // bezier_on(true);
  }
  catch (std::exception& ex)
  {
    std::cout << ex.what() << std::endl;
  }

}  // int main()

   /*

   //[lambert_w_output_1
   Output:
   Lambert W diode current example.
   V thermal 0.0257025
   Isat = 2.5e-14
   voltage = 0.9, current = 0.00108485, -6.82631
   -19.65  0.3
   -15.75  0.4
   -11.86  0.5
   -7.97  0.6
   -4.08  0.7
   -0.0195  0.8
   3.6  0.9

   //] [/lambert_w_output_1]
   */

max_issues_repo_name: qingkouwei/mediaones


text:
//
// Copyright Jason Rice 2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef NBDL_WEBSOCKET_CONNECTION_HPP
#define NBDL_WEBSOCKET_CONNECTION_HPP

#include <nbdl/async_enqueue.hpp>
#include <nbdl/catch.hpp>
#include <nbdl/concept/Endpoint.hpp>
#include <nbdl/endpoint_handler.hpp>
#include <nbdl/promise.hpp>
#include <nbdl/run_async_loop.hpp>
#include <nbdl/tap.hpp>
#include <nbdl/websocket/detail/message_reader.hpp>
#include <nbdl/websocket/detail/message_sender.hpp>
#include <nbdl/websocket/event.hpp>

#include <boost/asio.hpp>
#include <boost/callable_traits/return_type.hpp>
#include <boost/hana/map.hpp>
#include <boost/mp11/utility.hpp>
#include <memory>
#include <type_traits>

namespace nbdl::websocket::detail
{
  namespace asio = boost::asio;
  using asio::ip::tcp;
  namespace hana = boost::hana;

  enum struct control_frame_kind
  {
    NONE
  , CLOSE
  , PONG
  };

  template <typename Payload>
  struct control_frame
  {
    control_frame_kind kind = control_frame_kind::NONE;
    Payload payload = {};

    bool is_close()
    {
      return kind == control_frame_kind::CLOSE;
    }

    template <typename X>
    void to_close(X&& x)
    {
      kind    = control_frame_kind::CLOSE;
      payload = std::forward<X>(x);
    }

    template <typename X>
    void to_pong(X&& x)
    {
      if (kind != control_frame_kind::CLOSE)
      {
        kind    = control_frame_kind::PONG;
        payload = std::forward<X>(x);
      }
    }
  };

  template <typename Derived, typename RawImpl>
  using coalesce_derived_t = boost::mp11::mp_if_c<std::is_void<Derived>::value, RawImpl, Derived>;

  struct endpoint_impl_tag { };

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived_ = void>
  struct endpoint_impl
    : std::enable_shared_from_this<coalesce_derived_t<Derived_, endpoint_impl<Queue
                                                                            , Handler
                                                                            , SendMessageImpl
                                                                            , Derived_>>>
  {
    using hana_tag = endpoint_impl_tag;
    using value_type = typename Queue::value_type;
    using Payload = value_type;
    using Derived = coalesce_derived_t<Derived_, endpoint_impl>;

    inline Derived& self()
    {
      return static_cast<Derived&>(*this);
    }

    template <typename Q, typename H, typename InitFn>
    endpoint_impl(tcp::socket&& s, Q&& queue_, H&& handler_, InitFn&& init)
      : socket(std::move(s))
      , pending_control_frame()
      , handler(std::forward<H>(handler_))
      , reader(detail::make_message_reader(
          hana::type_c<Payload>
        , socket
        , make_reader_handler(handler)
        ))
      , sender(socket)
      , send_queue(std::forward<Q>(queue_))
      , is_send_queue_running(false)
      , is_started(false)
      , is_stopped(false)
      , is_close_received(false)
    {
      init(self(), socket, handler);
    }

    endpoint_impl(endpoint_impl const&) = delete;

    void send_message(Payload const&);
    void send_close();
    void start_messaging();
    bool stop();

  private:
    void start_send_queue();
    bool is_sending_close();
    void mark_is_close_received();
    auto make_reader_handler(Handler&);

    template <typename Key, typename ...Args>
    void call_handler(Key, Args&& ...);

    tcp::socket socket;
    detail::control_frame<Payload> pending_control_frame;
    Handler handler;

    using ReaderHandler = decltype(
      (std::declval<endpoint_impl>().*
       std::declval<decltype(&endpoint_impl::make_reader_handler)>())(handler)
    );

    detail::message_reader<Payload, ReaderHandler> reader;
    detail::message_sender<Payload> sender;
    Queue send_queue;
    bool is_send_queue_running : 1;
    bool is_started : 1;
    bool is_stopped : 1;
    bool is_close_received : 1;
  };

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::send_message(Payload const& p)
  {
    auto shared_this = this->shared_from_this();

    nbdl::run_async(
      hana::make_tuple(
        nbdl::promise([this, shared_this](auto& resolver, Payload const& payload)
        {
          nbdl::async_enqueue(resolver, send_queue, payload);
        })
      , [this]()
        {
          (void(this));
          start_send_queue();
        }
      )
    , p
    );
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::send_close()
  {
    // TODO Use error codes defined in
    // RFC 6455 7.4.1
    pending_control_frame.to_close(Payload{});
    start_send_queue();
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::start_messaging()
  {
    if (not is_started && not is_stopped)
    {
      is_started = true;

      reader.keep_reading(this->shared_from_this());

      if (send_queue.size() > 0)
      {
        start_send_queue();
      }
    }
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::start_send_queue()
  {
    if (       is_send_queue_running
            or is_stopped
        or not is_started)
    {
      return;
    }

    auto shared_this = this->shared_from_this();
    is_send_queue_running = true;

    // run_async_loop until queue is empty
    nbdl::run_async_loop(hana::make_tuple(
      nbdl::promise([this, shared_this](auto& resolver)
      {
        (void(this));
        if (is_sending_close())
        {
          sender.data.payload = pending_control_frame.payload;
          nbdl::run_async(hana::make_tuple(
            nbdl::promise([&](auto& resolver_)
            {
              detail::send_close(resolver_, sender);
              // keep is_send_queue_running == true to prevent more messages
              // after sending the close frame
              resolver.terminate();
            })
          , [&](auto& /*sender*/)
            {
              if (is_close_received)
              {
                call_handler(endpoint_event::close);
              }
            }
          , nbdl::catch_([&](std::error_code error_code)
            {
              resolver.reject(error_code);
            })
          ));
        }
        else
        {
          // keep sending
          resolver.resolve();
        }
      })
    , nbdl::promise([this](auto& resolver)
      {
        (void(this));
        if (send_queue.size() > 0)
        {
          sender.data.payload = send_queue.front();
          SendMessageImpl{}(resolver, sender);
        }
        else
        {
          is_send_queue_running = false;
          resolver.terminate();
        }
      })
    , [this](auto&& ...)
      {
        (void(this));
        if (send_queue.size() > 0)
        {
          // pop after the message was sent without error
          send_queue.pop();
        }
      }
    , nbdl::catch_([this](boost::system::error_code error)
      {
        (void(this));
        is_send_queue_running = false;

        if ( is_sending_close()
         && (asio::error::eof == error || asio::error::connection_reset == error)
           )
        {
          //expected socket close
          call_handler(endpoint_event::close);
        }
        else
        {
          call_handler(hana::type_c<std::error_code>, error);
        }
      })
    , nbdl::catch_([this](auto&& error)
      {
        (void(this));
        is_send_queue_running = false;
        call_handler(hana::typeid_(error), std::forward<decltype(error)>(error));
      })
    ));
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  bool endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::is_sending_close()
  {
    return pending_control_frame.is_close();
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::mark_is_close_received()
  {
    is_close_received = true;
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  auto endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::make_reader_handler(Handler&)
  {
    namespace read_event = detail::read_event;

    return hana::make_map(
      hana::make_pair(read_event::message, [this](auto, auto& frame_ctx)
      {
        (void(this));
        // move from the payload object in the reader
        call_handler(endpoint_event::message, frame_ctx.payload);
      })
    , hana::make_pair(read_event::close, [this](auto, auto const&)
      {
        (void(this));
        mark_is_close_received();

        if (is_sending_close())
        {
          call_handler(endpoint_event::close);
        }
        else
        {
          send_close();
        }
      })
    , hana::make_pair(read_event::ping, [this](auto, auto const& frame_ctx)
      {
        (void(this));
        pending_control_frame.to_pong(std::move(frame_ctx.payload));
      })
    , hana::make_pair(read_event::pong, [](auto&& ...) { })
    , hana::make_pair(read_event::bad_input, [this](auto&& ...)
      {
        (void(this));
        call_handler(event::bad_request);
      })
    , hana::make_pair(hana::type_c<std::error_code>, [this](std::error_code error, auto const&)
      {
        (void(this));
        call_handler(hana::type_c<std::error_code>, error);
      })
    );
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  template <typename Key, typename ...Args>
  void endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::call_handler(Key key, Args&& ...args)
  {
    if (is_stopped)
    {
      return;
    }

    handler[key](self(), std::forward<Args>(args)...);
  }

  template <typename Queue, typename Handler, typename SendMessageImpl, typename Derived>
  bool endpoint_impl<Queue, Handler, SendMessageImpl, Derived>::stop()
  {
    is_stopped = true;
    try {
      socket.shutdown(tcp::socket::shutdown_both);
    } catch(...) {
      return false;
    }
    return true;
  }
}

namespace nbdl {
  // Endpoint

  template <>
  inline constexpr bool is_endpoint<nbdl::websocket::detail::endpoint_impl_tag> = true;
}

#endif

max_stars_repo_name: ricejasonf/nbdl

max_issues_repo_name: ricejasonf/nbdl

max_forks_repo_name: ricejasonf/nbdl


text:
#include "Uuid.h"

#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

namespace kc::core {

Uuid generateUuid() {
    using namespace boost;
    return lexical_cast<Uuid>(uuids::random_generator()());
}
}

max_stars_repo_name: nekoffski/libkc

max_issues_repo_name: nekoffski/libkc

max_forks_repo_name: nekoffski/libkc


text:
/**
 * Copyright (c) 2020 libnuls developers (see AUTHORS)
 *
 * This file is part of libnuls.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <nuls/system/sdk/address.hpp>

#include <algorithm>
#include <cstdint>
#include <string>
#include <utility>
#include <boost/program_options.hpp>
#include <nuls/system/formats/base_32.hpp>
#include <nuls/system/formats/base_58.hpp>
#include <nuls/system/math/checksum.hpp>
#include <nuls/system/math/elliptic_curve.hpp>
#include <nuls/system/math/hash.hpp>
#include <nuls/system/wallet/ec_private.hpp>
#include <nuls/system/wallet/ec_public.hpp>

namespace libnuls {
namespace system {
namespace sdk {

using namespace nuls::system::machine;

const std::string address::mainnet_prefix = "NULS";
const std::string address::testnet_prefix = "tNULS";
const std::string LENGTHPREFIX[] =  {"", "a", "b", "c", "d", "e"};

address::address(int chainId, std::string prefix, uint8_t addressType, short_hash hash160)
  : chainId(chainId), prefix(prefix), addressType(addressType), hash160(hash160)
{
    addressBytes[0] = (uint16_t)chainId | 0xff;
    addressBytes[1] = ((uint16_t)chainId >> 8)| 0xff;
    addressBytes[2] = addressType;
    std::copy(hash160.begin(), hash160.end(), addressBytes.begin() + 3);
}
std::string address::to_string()
{
    std::string addstr;
    if (!prefix.empty())
    {
        addstr.append(prefix);
        addstr.append(LENGTHPREFIX[prefix.length()]);
    }
    byte_array<ADDRESS_LENGTH + 1> addressBytesWithXor;
    std::copy(addressBytes.begin(), addressBytes.end(), addressBytesWithXor.begin());
    addressBytesWithXor[ADDRESS_LENGTH] = get_xor(addressBytes);
    addstr.append(encode_base58(addressBytesWithXor));
    return addressStr;
}
uint8_t address::get_xor(byte_array<ADDRESS_LENGTH> body)
{
    uint8_t ret = 0;
    for (int i = 0; i < body.size(); i++)
    {
        ret ^= body[i];
    }
    return ret;
}

} // namespace sdk
} // namespace system
} // namespace libnuls

max_issues_repo_name: CCC-NULS/nuls-cplusplus-sdk

max_forks_repo_name: CCC-NULS/nuls-cplusplus-sdk


text:
#include "CommandAttack.h"
#include <boost/algorithm/string.hpp>
#include <iostream>

void CommandAttack::executeInHeartbeat(const std::string& username, const std::vector<std::string>& fullCommand) {
    auto& combatManager = characterManager.getCombatManager();
    auto& currentCombat = combatManager.getCombatWithPlayer(username);

    if(currentCombat.hasPlayer(username)){

        if(currentCombat.getRoundTime() <= 0){
            cerr << "round time 0, executing attack\n";
            auto attackValue = characterManager.getCharacterAttack(username);
            auto opponentName = currentCombat.getOpponent(username);
            characterManager.damageCharacter(opponentName, attackValue);
            onlineUserManager.addMessageToUser(username, "You attacked " + opponentName + " for " + std::to_string(attackValue) + ".\n");
            onlineUserManager.addMessageToUser(opponentName,
                    "You were attacked for " + std::to_string(attackValue) +
                    ".\nCurrent HP: " + std::to_string(characterManager.getCharacterHealth(opponentName)) + "\n");
        } else {
            cerr << "round time not expired, queuing attack\n";
            currentCombat.queueCommand(username, "attack");
        }

    } else { //player is not in a combat
        onlineUserManager.addMessageToUser(username, "You are not in combat with anyone!\n");
    }
}

std::vector<std::string> CommandAttack::reassembleCommand(std::string& fullCommand, bool& commandIsValid) {
    std::vector<std::string> processedCommand;

    //Format: attack
    boost::trim_if(fullCommand, boost::is_any_of(" \t"));

    //split by " " and compress all long spaces
    boost::split(processedCommand, fullCommand, boost::is_any_of(" \t"), boost::token_compress_on);
    commandIsValid = (processedCommand.size() == 1 || processedCommand.size() == 2);

    return processedCommand;
}


text: #include <boost/flyweight/hashed_factory_fwd.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#pragma warning(push, 0)
#include <SimpleAmqpClient/SimpleAmqpClient.h>
#pragma warning(pop)

#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#include <boost/lexical_cast.hpp>

#include <iostream>
#include <sstream>

using namespace std;

constexpr auto QUEUE_NAME = "rpc_queue";

class RpcClient
{
public:
  RpcClient()
    : m_channel(AmqpClient::Channel::Create())
    , m_callbackQueue(m_channel->DeclareQueue("", false, true, false, true))
    , m_consumerTag(m_channel->BasicConsume(
        m_callbackQueue, "", true, true, false))
  {
  }

  uint64_t fibonacci(uint16_t n)
  {
    ostringstream guid;
    guid << boost::uuids::random_generator()();

    auto requestMessage = AmqpClient::BasicMessage::Create();
    requestMessage->Body(to_string(n));
    requestMessage->ReplyTo(m_callbackQueue);
    requestMessage->CorrelationId(guid.str());
    requestMessage->DeliveryMode(AmqpClient::BasicMessage::dm_persistent);
    m_channel->BasicPublish("", QUEUE_NAME, requestMessage);

    AmqpClient::Envelope::ptr_t envelop;
    bool success = m_channel->BasicConsumeMessage(
      m_consumerTag, envelop, 1000);
    if (success)
    {
      return boost::lexical_cast<uint64_t>(envelop->Message()->Body());
    }
    else
    {
      return 0;
    }
  }

private:
  AmqpClient::Channel::ptr_t m_channel;
  string m_callbackQueue;
  string m_consumerTag;
};

int main(int argc, char* argv[])
{
  try
  {
    if (argc < 2)
    {
      cerr << "Usage: " << argv[0] << " <number>..." << endl;
      return -1;
    }

    RpcClient rpcClient;

    for (int i = 1; i < argc; ++i)
    {
      try
      {
        auto f = rpcClient.fibonacci(boost::lexical_cast<uint16_t>(argv[i]));
        cout << "Fibonacci(" << argv[i] << ") = ";
        if (f != 0)
        {
          cout << f << endl;
        }
        else
        {
          cout << "cannot be calculated!" << endl;
        }
      }
      catch (const boost::bad_lexical_cast& error)
      {
        cerr << error.what() << endl;
      }
    }
  }
  catch (const exception& error)
  {
    cerr << error.what() << endl;
  }

  return 0;
}

max_stars_repo_name: bobeff/rabbitmq-cpp-tutorials

max_issues_repo_name: bobeff/rabbitmq-cpp-tutorials

max_forks_repo_name: bobeff/rabbitmq-cpp-tutorials


text:
#include "storm/settings/ArgumentValidators.h"

#include <boost/algorithm/string/join.hpp>

#include <sys/stat.h>

#include "storm/settings/Argument.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/exceptions/IllegalArgumentException.h"
#include "storm/exceptions/IllegalArgumentValueException.h"
#include "storm/exceptions/IllegalFunctionCallException.h"

namespace storm {
    namespace settings {

        template <typename ValueType>
        RangeArgumentValidator<ValueType>::RangeArgumentValidator(boost::optional<ValueType> const& lower, boost::optional<ValueType> const& upper, bool lowerIncluded, bool upperIncluded) : lower(lower), upper(upper), lowerIncluded(lowerIncluded), upperIncluded(upperIncluded) {
            // Intentionally left empty.
        }

        template <typename ValueType>
        bool RangeArgumentValidator<ValueType>::isValid(ValueType const& value) {
            bool result = true;
            if (lower) {
                if (lowerIncluded) {
                    result &= value >= lower.get();
                } else {
                    result &= value > lower.get();
                }
            }
            if (upper) {
                if (upperIncluded) {
                    result &= value <= upper.get();
                } else {
                    result &= value < upper.get();
                }
            }
            return result;
        }

        template <typename ValueType>
        std::string RangeArgumentValidator<ValueType>::toString() const {
            std::stringstream stream;
            stream << "in ";
            if (lower) {
                if (lowerIncluded) {
                    stream << "[";
                } else {
                    stream << "(";
                }
                stream << lower.get();
            } else {
                stream << "(-inf";
            }
            stream << ", ";
            if (upper) {
                stream << upper.get();
                if (upperIncluded) {
                    stream << "]";
                } else {
                    stream << ")";
                }
            } else {
                stream << "+inf)";
            }

            return stream.str();
        }

        FileValidator::FileValidator(Mode mode) : mode(mode) {
            // Intentionally left empty.
        }

        bool FileValidator::isValid(std::string const& filename) {
            if (mode == Mode::Exists) {
                // First check existence as ifstream::good apparently also returns true for directories.
                struct stat info;
                stat(filename.c_str(), &info);
                STORM_LOG_THROW(info.st_mode & S_IFREG, storm::exceptions::IllegalArgumentValueException, "Unable to read from non-existing file '" << filename << "'.");

                // Now that we know it's a file, we can check its readability.
                std::ifstream istream(filename);
                STORM_LOG_THROW(istream.good(), storm::exceptions::IllegalArgumentValueException, "Unable to read from file '" << filename << "'.");

                return true;
            } else if (mode == Mode::Writable) {
                std::ofstream filestream(filename);
                STORM_LOG_THROW(filestream.is_open(), storm::exceptions::IllegalArgumentValueException , "Could not open file '" << filename << "' for writing.");
                filestream.close();
                std::remove(filename.c_str());

                return true;
            }
            return false;
        }

        std::string FileValidator::toString() const {
            if (mode == Mode::Exists) {
                return "existing file";
            } else {
                return "writable file";
            }
        }

        MultipleChoiceValidator::MultipleChoiceValidator(std::vector<std::string> const& legalValues) : legalValues(legalValues) {
            // Intentionally left empty.
        }

        bool MultipleChoiceValidator::isValid(std::string const& value) {
            for (auto const& legalValue : legalValues) {
                if (legalValue == value) {
                    return true;
                }
            }
            return false;
        }

        std::string MultipleChoiceValidator::toString() const {
            return "in {" + boost::join(legalValues, ", ") + "}";
        }

        std::shared_ptr<ArgumentValidator<int64_t>> ArgumentValidatorFactory::createIntegerRangeValidatorExcluding(int_fast64_t lowerBound, int_fast64_t upperBound) {
            return createRangeValidatorExcluding<int64_t>(lowerBound, upperBound);
        }

        std::shared_ptr<ArgumentValidator<uint64_t>> ArgumentValidatorFactory::createUnsignedRangeValidatorExcluding(uint64_t lowerBound, uint64_t upperBound) {
            return createRangeValidatorExcluding<uint64_t>(lowerBound, upperBound);
        }

        std::shared_ptr<ArgumentValidator<uint64_t>> ArgumentValidatorFactory::createUnsignedRangeValidatorIncluding(uint64_t lowerBound, uint64_t upperBound) {
            return createRangeValidatorIncluding<uint64_t>(lowerBound, upperBound);
        }

        std::shared_ptr<ArgumentValidator<double>> ArgumentValidatorFactory::createDoubleRangeValidatorExcluding(double lowerBound, double upperBound) {
            return createRangeValidatorExcluding<double>(lowerBound, upperBound);
        }

        std::shared_ptr<ArgumentValidator<double>> ArgumentValidatorFactory::createDoubleRangeValidatorIncluding(double lowerBound, double upperBound) {
            return createRangeValidatorIncluding<double>(lowerBound, upperBound);
        }

        std::shared_ptr<ArgumentValidator<int64_t>> ArgumentValidatorFactory::createIntegerGreaterValidator(int_fast64_t lowerBound) {
            return createGreaterValidator<int64_t>(lowerBound, false);
        }

        std::shared_ptr<ArgumentValidator<uint64_t>> ArgumentValidatorFactory::createUnsignedGreaterValidator(uint64_t lowerBound) {
            return createGreaterValidator<uint64_t>(lowerBound, false);
        }

        std::shared_ptr<ArgumentValidator<double>> ArgumentValidatorFactory::createDoubleGreaterValidator(double lowerBound) {
            return createGreaterValidator<double>(lowerBound, false);
        }

        std::shared_ptr<ArgumentValidator<int64_t>> ArgumentValidatorFactory::createIntegerGreaterEqualValidator(int_fast64_t lowerBound) {
            return createGreaterValidator<int64_t>(lowerBound, true);
        }

        std::shared_ptr<ArgumentValidator<uint64_t>> ArgumentValidatorFactory::createUnsignedGreaterEqualValidator(uint64_t lowerBound) {
            return createGreaterValidator<uint64_t>(lowerBound, true);
        }

        std::shared_ptr<ArgumentValidator<double>> ArgumentValidatorFactory::createDoubleGreaterEqualValidator(double lowerBound) {
            return createGreaterValidator<double>(lowerBound, true);
        }

        std::shared_ptr<ArgumentValidator<std::string>> ArgumentValidatorFactory::createExistingFileValidator() {
            return std::make_unique<FileValidator>(FileValidator::Mode::Exists);
        }

        std::shared_ptr<ArgumentValidator<std::string>> ArgumentValidatorFactory::createWritableFileValidator() {
            return std::make_unique<FileValidator>(FileValidator::Mode::Writable);
        }

        std::shared_ptr<ArgumentValidator<std::string>> ArgumentValidatorFactory::createMultipleChoiceValidator(std::vector<std::string> const& choices) {
            return std::make_unique<MultipleChoiceValidator>(choices);
        }

        template <typename ValueType>
        std::shared_ptr<ArgumentValidator<ValueType>> ArgumentValidatorFactory::createRangeValidatorExcluding(ValueType lowerBound, ValueType upperBound) {
            return std::make_unique<RangeArgumentValidator<ValueType>>(lowerBound, upperBound, false, false);
        }

        template <typename ValueType>
        std::shared_ptr<ArgumentValidator<ValueType>> ArgumentValidatorFactory::createRangeValidatorIncluding(ValueType lowerBound, ValueType upperBound) {
            return std::make_unique<RangeArgumentValidator<ValueType>>(lowerBound, upperBound, true, true);
        }

        template <typename ValueType>
        std::shared_ptr<ArgumentValidator<ValueType>> ArgumentValidatorFactory::createGreaterValidator(ValueType lowerBound, bool equalAllowed) {
            return std::make_unique<RangeArgumentValidator<ValueType>>(lowerBound, boost::none, equalAllowed, false);
        }

    }
}


text:
//
// Copyright yutopp 2015 - .
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once

#include <iostream>
#include <string>
#include <vector>

#include <boost/filesystem/path.hpp>
#include <boost/optional.hpp>

#include <sys/resource.h>

namespace awaho
{
    namespace fs = boost::filesystem;

    struct mount_point
    {
        fs::path host_path;
        fs::path guest_path;

        bool is_readonly;
        bool do_chown;
    };

    struct copy_point
    {
        fs::path host_path;
        fs::path guest_path;
    };

    struct limits_values_t
    {
        boost::optional<::rlim_t> core;     //
        boost::optional<::rlim_t> nofile;   // number
        boost::optional<::rlim_t> nproc;    // number
        boost::optional<::rlim_t> memlock;  // number
        boost::optional<::rlim_t> cputime;  // seconds
        boost::optional<::rlim_t> memory;   // bytes
        boost::optional<::rlim_t> fsize;    // bytes
    };

    struct pipe_redirect_t
    {
        int host_fd;
        int guest_fd;
    };

    struct container_options_t
    {
        fs::path host_containers_base_dir;

        fs::path in_container_start_path;       // Ex. "/home/some-user/"
        std::vector<mount_point> mount_points;
        std::vector<copy_point> copy_points;
        limits_values_t limits;

        std::size_t stack_size;
        std::vector<pipe_redirect_t> pipe_redirects;

        std::vector<std::string> commands;
        std::vector<std::string> envs;

        int result_output_fd;
        std::string result_output_type;
    };

    // printer
    std::ostream& operator<<( std::ostream& os, container_options_t const& opts );

} // namespace awaho

max_stars_repo_name: yutopp/awaho

max_issues_repo_name: yutopp/awaho

max_forks_repo_name: yutopp/awaho


text:
/* Protomodel - MIT License */

#include "protomodel/error.h"

#include <cxxopts.hpp>

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

#include <iostream>
#include <unordered_map>
#include <memory>
#include <string>
#include <vector>

#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
# define unlikely(X) __builtin_expect((X), 0)
# else
# define unlikely(X) (X)
#endif

using namespace protomodel;

namespace protomerge {

class Error : public std::exception
{
public:
  Error(const char *motive) : _motive{ motive } {}
  const char *what() const noexcept
  { return _motive; }

private:
  const char *const _motive;
};

struct Table
{
  const std::string name;
  const char *const table_start;
  const char *const table_end;
  const char *const inner_start;
  const char *const inner_end;
  const bool extends;
  mutable bool used;

  Table() = delete;

  explicit
  Table(const char *start, const char *end,
        const char *nstart, const char *nend,
        const char *tstart, const char *tend,
        bool does_extend) :
    name{ nstart, static_cast<size_t>(nend - nstart) },
    table_start{ start }, table_end{ end },
    inner_start{ tstart }, inner_end{ tend },
    extends{ does_extend }, used{ false }
  {}
};

class Parser
{
public:
  Parser(const std::string &file) :
    _mapping{ file.c_str(), boost::interprocess::read_only },
    _region{ _mapping, boost::interprocess::read_only },
    _start{ static_cast<const char *>(_region.get_address()) },
    _end{ _start + _region.get_size() },
    _p{ _start },
    _in_comments{ false }
  {}

private:
  void next(char token)
  {
    while (((*_p != token) && (! _in_comments)) || (_in_comments))
    {
      check_comments();
      _p++;
      check_eof();
    }
  }

  void skip_whitespaces()
  {
    while (isspace(*(_p++)))
    { check_eof(); }
  }

  bool check_comments()
  {
    if ((*_p == '/') && (*(++_p) == '/'))
    { _in_comments = true; }
    else if (*_p == '\n')
    { _in_comments = false; }
    return _in_comments;
  }

  void check_eof() const
  {
    if (unlikely(_p >= _end))
    { throw Error("Unexpected end of file"); }
  }

public:
  void parse()
  {
    for (;;)
    {
      if (! check_comments()) /* Returns true in comments */
      {
        if (0 == strncmp("table ", _p, 6)) /* Found 'table ' somewhere */
        {
          const bool extends =
            ((_p >= _start + 8u) && (0 == strncmp("@extend ", _p - 8u, 8u)));

          const char *const start = _p;

          _p += sizeof("table ") - 1; /* Go after table + space */

          skip_whitespaces();
          const char *const name_start = _p - 1; /* Start of the table name */
          next(' '); /* XXX Whitespace or start of comment */
          const char *const name_end = _p; /* End of the table name */
          _p++; /* Go after the whitespace */
          next('{'); _p++; /* Go after the initial { */
          const char *const inner_start = _p; /* Start of the table contents */
          next('}'); /* Go at the end of the table */
          const char *const inner_end = _p; /* Before the end of the table */
          _p += 2u; /* Go after the } */
          const char *const end = _p;

          /* Create the table */
          const auto table =
            std::make_shared<Table>(start, end, name_start, name_end,
                                    inner_start, inner_end, extends);
          _tables.push_back(table);
          _map.emplace(table->name, table);
        }
      }

      /* Move on... Maybe stop parsing as well. */
      _p++;
      if (unlikely(_p >= _end))
      { break; }
    }
  }

public:
  const std::vector<std::shared_ptr<Table>> tables() const noexcept
  { return _tables; }

  std::shared_ptr<Table> get_table(const std::string &name) const noexcept
  {
    const auto it = _map.find(name);
    if (unlikely(it == _map.end()))
    { return nullptr; }
    else
    { return it->second; }
  }

  const char *start() const noexcept
  { return _start; }

  const char *end() const noexcept
  { return _end; }

  size_t size() const noexcept
  { return static_cast<size_t>(_end - _start); }

private:
  boost::interprocess::file_mapping _mapping;
  boost::interprocess::mapped_region _region;

  const char *const _start;
  const char *const _end;
  const char *_p; /**< Pointer iterator */
  bool _in_comments;

  std::unordered_map<std::string, std::shared_ptr<Table>> _map;
  std::vector<std::shared_ptr<Table>> _tables;
};

static Status
merge(const std::vector<std::string> &files,
      FILE *output)
{
  assert(files.size() == 2);

  const std::string &base_file = files.at(0);
  const std::string &ext_file = files.at(1);

  Parser p_base{ base_file };
  p_base.parse();
  Parser p_ext{ ext_file };
  p_ext.parse();

  fprintf(output,
          "// Flatbuffers model generated by protomerge\n"
          "// Base Model.......: %s\n"
          "// Extension Model..: %s\n\n",
          base_file.c_str(), ext_file.c_str());

  const char *base_ptr = p_base.start();

#define WRITE(Ptr, Size) \
  ({ \
    const size_t size___ = static_cast<size_t>(Size); \
    fwrite((Ptr), sizeof(char), size___, output); \
    (Ptr) + size___; \
  })

  for (const std::shared_ptr<Table> &t : p_base.tables())
  {
    /* Write to the end of the base table */
    base_ptr = WRITE(base_ptr, t->inner_end - base_ptr);

    std::shared_ptr<Table> ext = p_ext.get_table(t->name);
    if (! ext) /* No extension table: stop for this table */
    { continue; }
    else if (! ext->extends)
    { return error("Table '" + ext->name + "' overrides an existing table"); }
    ext->used = true;

    fprintf(output, "\n  // Declared in %s:\n", ext_file.c_str());
    WRITE(ext->inner_start, ext->inner_end - ext->inner_start);
  }
  WRITE(base_ptr, p_base.end() - base_ptr);

  fprintf(output, "\n// Tables declared in %s:\n\n", ext_file.c_str());
  for (const std::shared_ptr<Table> &ext : p_ext.tables())
  {
    if (ext->extends)
    {
      if (! ext->used)
      {
        return error("Table '" + ext->name + "' is tagged '@extend' "
                     "but extends nothing");
      }
      continue;
    }
    WRITE(ext->table_start, ext->table_end - ext->table_start);
  }
  return Ok();
#undef WRITE
}

static Status
run(int argc,
    char **argv)
{
  std::vector<std::string> files;
  std::string output;

  cxxopts::Options options(
    "protomerge", "Merge two flatbuffers models by aggregating them");
  options.show_positional_help();
  options
    .positional_help("files...")
    .add_options()
    ("h,help", "Display this message")
    ("V,version", "Display protomerge's version")
    ("o,output", "Output of the merged model",
     cxxopts::value<std::string>(output))
    ("files", "Flatbuffers Interface Files",
     cxxopts::value<std::vector<std::string>>(files))
  ;
  options.parse_positional({"files"});

  auto result = options.parse(argc, argv);
  if (result.count("help"))
  {
    std::cout << options.help() << std::endl;
    return Ok();
  }
  else if (result.count("version"))
  {
    std::cout << "protomerge v" VERSION << std::endl;
    return Ok();
  }
  else if (output.empty())
  { return error("protomerge required the --output,-o option"); }
  else if (files.size() <= 1u)
  { return error("protomerge requires positional arguments (see --help)"); }
  else if (files.size() != 2u)
  { return error("for now, protomerge can only merge two files together"); }

  /* Open the output FILE descriptor. As a unique_ptr, to handle exceptions */
  std::unique_ptr<FILE, decltype(&fclose)> file{
    fopen(output.c_str(), "w"), fclose
  };
  if (! file)
  { return error("Failed to open file '" + output + "'"); }

  if (! merge(files, file.get()).check())
  { return error("Failed to merge flatbuffers interfaces"); }

  return Ok();
}

} /* namespace protomerge */

int
main(int argc,
     char **argv)
{
  try
  {
    return (protomerge::run(argc, argv).check()) ? EXIT_SUCCESS : EXIT_FAILURE;
  }
  catch (const boost::interprocess::interprocess_exception &e)
  {
    std::cerr << "ERROR: " << e.what() << std::endl;
  }
  catch (const cxxopts::missing_argument_exception &e)
  {
    std::cerr << "ERROR: " << e.what() << std::endl;
  }
  return EXIT_FAILURE;
}

max_stars_repo_name: jeanguyomarch/protomodel

max_issues_repo_name: jeanguyomarch/protomodel

max_forks_repo_name: jeanguyomarch/protomodel


text:
/********************************************************
  Stanford Driving Software
  Copyright (c) 2011 Stanford University
  All rights reserved.

  Redistribution and use in source and binary forms, with
  or without modification, are permitted provided that the
  following conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.
* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.
* The names of the contributors may not be used to endorse
  or promote products derived from this software
  without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  DAMAGE.
 ********************************************************/

#include <iostream>
#include <fstream>
#include <Eigen/Geometry>
#include <Eigen/LU>
#include <global.h>
#include <vlrException.h>

#include <controller.h>

using namespace std;
using namespace Eigen;

ofstream f_data("data.dat");

vlr::MPCController* mpc=NULL;

int main(int argc, char** argv) {
  ros::init(argc, argv, "controller");
  try {
    mpc = new vlr::MPCController;
  }
  catch(vlr::Ex<>& e) {
    std::cout << e.what() << std::endl;
  }

  try {
    mpc->run();
  }
  catch(vlr::Ex<>& e) {
    std::cout << e.what() << std::endl;
  }

  delete mpc;
  return 0;
}

namespace vlr {

MPCController::MPCController() : nh_("/driving"), received_applanix_pose_(false),
                                 received_can_status_(false), received_trajectory_(false),
                                 run_controller_(false) {

  getParam("controller/hz", p_hertz);
  getParam("controller/horizon", p_horizon);
  getParam("controller/torque_mode", p_torque_mode);
  getParam("controller/cost_lon", p_q_lon);
  getParam("controller/cost_lat", p_q_lat);
  getParam("controller/cost_theta", p_q_theta);
  getParam("controller/cost_vx", p_q_u);
  getParam("controller/cost_vy", p_q_v);
  getParam("controller/cost_theta_dot", p_q_theta_dot);
  getParam("controller/cost_accel", p_r_udot);
  getParam("controller/cost_steer", p_r_delta);
  getParam("controller/cost_delta_accel", p_rd_udot);
  getParam("controller/cost_delta_steer", p_rd_delta);
  getParam("controller/vel_smooth", p_vel_smooth);
  getParam("controller/int_decay", p_int_decay);
  getParam("controller/k_throttle", p_k_throttle);
  getParam("controller/d_throttle", p_d_throttle);
  getParam("controller/i_throttle", p_i_throttle);
  getParam("controller/ff_throttle", p_ff_throttle);
  getParam("controller/k_torque", p_k_torque);
  getParam("controller/d_torque", p_d_torque);
  getParam("controller/i_torque", p_i_torque);
  getParam("controller/ff_torque", p_ff_torque);
  getParam("controller/throttle_smooth", p_throttle_smooth);
  getParam("controller/torque_smooth", p_torque_smooth);

  getParam("controller/p_cte", p_p_cte);
  getParam("controller/d_cte", p_d_cte);
  getParam("controller/k_yawrate", p_k_yawrate);
  getParam("controller/k_aggressive", p_k_aggressive);
  getParam("controller/vel_int_cap", p_max_vel_int);
  getParam("controller/k_cruise_int", p_k_cruise_int);
  getParam("controller/k_accel", p_k_accel);
  getParam("controller/k_decel", p_k_decel);
  getParam("controller/kp_torque", p_kp_torque);
  getParam("controller/kd_torque", p_kd_torque);

  p_Q.setZero();
  p_R.setZero();
  p_R_delta.setZero();
  p_vs.set_passat_params();
  changeParams();
  des_states_.resize(NUM_STATES, p_horizon + 1);
  controls_.resize(NUM_CONTROLS, p_horizon);
  controls_.setZero();
  errors_.setZero();

  ctl_err_.setZero();
  ctl_err_vel_.setZero();
  ctl_err_int_.setZero();
  vel_err_int_ = 0;
  last_dtheta_ = 0;

  // initialize mosek
  //MSK_makeenv(&m_mosek_env, NULL, NULL, NULL, NULL);
  //MSK_linkfunctoenvstream(m_mosek_env, MSK_STREAM_LOG, NULL, printstr);
  //MSK_initenv(m_mosek_env);

  applanix_sub_   = nh_.subscribe("ApplanixPose", 5, &MPCController::applanixHandler, this);
  can_status_sub_ = nh_.subscribe("CanStatus", 5, &MPCController::canStatusHandler, this);
  trajectory_sub_ = nh_.subscribe("Trajectory2D", 5, &MPCController::trajectoryHandler, this);

  actuator_pub_  = nh_.advertise<driving_common::Actuator>("Actuator", 1);
  controller_target_pub_  = nh_.advertise<controller::ControllerTarget>("ControllerTarget", 1);
}

MPCController::~MPCController() {
}

void MPCController::run() {
  ros::Rate r(p_hertz);

  while (ros::ok()) {
    controlLoop();
    ros::spinOnce();
    r.sleep();
  }
}

  // parameter change callback
void MPCController::changeParams() {
  p_Q(0, 0) = p_q_lon;
  p_Q(1, 1) = p_q_lat;
  p_Q(2, 2) = p_q_theta;
  p_Q(3, 3) = p_q_u;
  p_Q(4, 4) = p_q_v;
  p_Q(5, 5) = p_q_theta_dot;

  p_R(0, 0) = p_r_udot;
  p_R(1, 1) = p_r_delta;
  p_R_delta(0, 0) = p_rd_udot;
  p_R_delta(1, 1) = p_rd_delta;
}

void MPCController::applanixHandler(const applanix::ApplanixPose& applanix_pose) {
  applanix_ = applanix_pose;
  received_applanix_pose_ = true;
}

void MPCController::canStatusHandler(const driving_common::CanStatus& can_status) {
  can_ = can_status;
  received_can_status_ = true;
}

void MPCController::trajectoryHandler(const driving_common::Trajectory2D& trajectory) {
  traj_ = trajectory;
  received_trajectory_ = true;
}

// main controller loop
void MPCController::controlLoop() {
  if (!received_applanix_pose_ || !received_can_status_ || !received_trajectory_) {return;}

    // if we haven't gotten anything for a while, reset
  if (traj_.point[0].t < applanix_.timestamp - 10.0) {
    controls_.setZero();
    throttle_torque_.setZero();
    ctl_err_.setZero();
    ctl_err_vel_.setZero();
    ctl_err_int_.setZero();
    vel_err_int_ = 0;
    last_dtheta_ = 0;
    received_applanix_pose_ = false;
    received_can_status_ = false;
    received_trajectory_ = false;
    cout << "No commands in a while, resetting controller..." << endl;
    return;
  }

  // compute desired control (delta, velocity)
  getState();
  getDesiredStates();
  //cout << errors_.transpose() << endl;

  // shift controls and run MPC
  Matrix<double, NUM_CONTROLS, 1> u_prev = controls_.col(0);
  Matrix<double, NUM_STATES, Dynamic> s_pred(NUM_STATES, p_horizon + 1);
  Matrix<double, NUM_STATES, 1> s;

  controls_.block(0, 0, NUM_CONTROLS, p_horizon - 1) = controls_.block(0, 1, NUM_CONTROLS, p_horizon - 1);

  for (int i = 0; i < 1; i++) {
    mpcLQR(state_, controls_, des_states_, u_prev, &controls_);
  }
  //laneFollow(state_, des_states_.col(0), &u_prev);
  //controls_.col(0) = u_prev;
  f_data << des_states_(0, 0) << " " << des_states_(0, 1) << " " << des_states_(0, 2) << " " << state_(0) << " " << state_(1) << " " << state_(2) << endl;

  if (!p_torque_mode) {
    double throttle = simulatorThrottle(state_(3, 0), state_(4, 0), state_(5, 0), controls_(0, 0), controls_(1, 0));
    double steering_angle = controls_(1, 0) * p_vs.param.steering_ratio;

    actuator_.steering_mode     = driving_common::Actuator::ANGLE_CONTROL;
    actuator_.steering_value    = steering_angle;
    actuator_.brake_pressure    = 30.0 * std::max(0.0, -throttle);
    actuator_.throttle_fraction = std::max(0.0, throttle);

    cout << throttle << " " << steering_angle << endl;

//    PassatActuatorAngleCommand(m_ipc, DGC_PASSAT_DIRECTION_FORWARD, steering_angle, 30.0 * max(0.0, -throttle), max(0.0, throttle));
  }
  else {
    getThrottleTorque();

    actuator_.steering_mode     = driving_common::Actuator::TORQUE_CONTROL;
    actuator_.steering_value    = throttle_torque_(1);
    actuator_.brake_pressure    = 30.0 * std::max(0.0, -throttle_torque_(0));
    actuator_.throttle_fraction = std::max(0.0, throttle_torque_(0));

    cout << "steering: " << controls_(1, 0) << " " << throttle_torque_(1) << endl;

//    PassatActuatorTorqueCommand(m_ipc, DGC_PASSAT_DIRECTION_FORWARD, throttle_torque_(1), 30.0 * max(0.0, -throttle_torque_(0)), max(0.0, throttle_torque_(0)));
  }

  actuator_.direction = driving_common::Actuator::DIRECTION_FORWARD;
  actuator_.timestamp = driving_common::Time::current();
  actuator_pub_.publish(actuator_);

    // publish errors
  controller_target_.target_velocity = des_states_(3, 0);
  controller_target_.target_steering_angle = controls_(1, 0) * p_vs.param.steering_ratio;
  controller_target_.cross_track_error = -sin(des_states_(2, 0)) * (state_(0) - des_states_(0, 0)) + cos(des_states_(2, 0)) * (state_(1) - des_states_(1, 0));
  controller_target_.heading_error = (state_(2) - des_states_(2, 0));
  controller_target_.timestamp = driving_common::Time::current();
  controller_target_pub_.publish(controller_target_);
}

// get current state of the car (really a delta state from desired state)
void MPCController::getState() {
  double imu_to_cg = DGC_PASSAT_IMU_TO_FA_DIST; //p_vs.param.imu_to_cg_dist;
  state_(0) = applanix_.smooth_x + cos(applanix_.yaw) * imu_to_cg;
  state_(1) = applanix_.smooth_y + sin(applanix_.yaw) * imu_to_cg;

  state_(2) = applanix_.yaw;
  state_(5) = applanix_.rate_yaw;

  double cos_th = cos(state_(2)), sin_th = sin(state_(2));
  double v_e = applanix_.vel_east - imu_to_cg * state_(5) * sin(state_(2));
  double v_n = applanix_.vel_north + imu_to_cg * state_(5) * cos(state_(2));

  state_(3) = cos_th * v_e + sin_th * v_n;
  state_(4) = -sin_th * v_e + cos_th * v_n;
}

// get desired states from trajecotry and controls using Newton's method
void MPCController::getDesiredStates() {
  double t = applanix_.timestamp, alpha;
  double ra_to_cg = DGC_PASSAT_WHEEL_BASE;
  int j = 0;

  // find all desired positions
//  driving_common::TrajectoryPoint2D *p1, *p2;
  double dt = 1.0 / p_hertz;
  for (int i = 0; i < p_horizon + 1; i++) {
    while (traj_.point[j + 1].t < t && j < (int)traj_.point.size() - 2)
      j++;
    driving_common::TrajectoryPoint2D& p1 = traj_.point[j];       // TODO: Check if copy is better than reference
    driving_common::TrajectoryPoint2D& p2 = traj_.point[j + 1];
    while (p2.theta - p1.theta > M_PI)
      p2.theta -= 2 * M_PI;
    while (p2.theta - p1.theta < -M_PI)
      p2.theta += 2 * M_PI;

    // integrate to create a smoothed trajectory
    alpha = (t - p1.t) / (p2.t - p1.t);
    if (alpha > 1) alpha = 1;
    if (alpha < 0) alpha = 0;

    des_states_(0, i) = (1 - alpha) * p1.x + alpha * p2.x;
    des_states_(1, i) = (1 - alpha) * p1.y + alpha * p2.y;
    des_states_(2, i) = (1 - alpha) * p1.theta + alpha * p2.theta;
    des_states_(0, i) += cos(des_states_(2, i)) * ra_to_cg;
    des_states_(1, i) += sin(des_states_(2, i)) * ra_to_cg;
    des_states_(3, i) = (1 - alpha) * p1.v + alpha * p2.v;
    des_states_(4, i) = 0.0;
    des_states_(5, i) = des_states_(3, i) * ((1 - alpha) * p1.kappa + alpha * p2.kappa);
    t += dt;
  }

  // normalize desired angles properly
  while (des_states_(2, 0) - state_(2) > M_PI)
    des_states_(2, 0) -= 2 * M_PI;
  while (des_states_(2, 0) - state_(2) < -M_PI)
    des_states_(2, 0) += 2 * M_PI;
  for (int i = 1; i < p_horizon + 1; i++) {
    while (des_states_(2, i) - des_states_(2, i - 1) > M_PI)
      des_states_(2, i) -= 2 * M_PI;
    while (des_states_(2, i) - des_states_(2, i - 1) < -M_PI)
      des_states_(2, i) += 2 * M_PI;
  }

  errors_ += 0.05 * (Rotation2D<double> (-state_(2)).toRotationMatrix() * (state_.block(0, 0, 2, 1) - des_states_.block(0, 0, 2, 1)) - errors_);
}

void MPCController::getThrottleTorque() {
  // integrate forward to see where velocity should be
  Matrix<double, NUM_STATES, 1> s;
  Matrix<double, NUM_CONTROLS, 1> err;

  simulateEuler(state_, controls_.col(0), &s);

  // compute errors, error derivatives (finite differences), a integrators
  err(0) = state_(3) - s(3);
  err(1) = (M_PI / 180) * can_.steering_angle / DGC_PASSAT_STEERING_RATIO - controls_(1, 0);
  ctl_err_vel_ = p_vel_smooth * ctl_err_vel_ + (1 - p_vel_smooth) * (err - ctl_err_) * p_hertz;
  ctl_err_int_ = ctl_err_int_ * p_int_decay + err;
  ctl_err_ = err;

  // apply control
  throttle_torque_(0) = p_throttle_smooth * throttle_torque_(0) + (1 - p_throttle_smooth) * (p_k_throttle * ctl_err_(0) + p_d_throttle * ctl_err_vel_(0)
      + p_i_throttle * ctl_err_int_(0) + p_ff_throttle * controls_(0, 0));

  throttle_torque_(1) = p_torque_smooth * throttle_torque_(1) + (1 - p_torque_smooth) * (p_k_torque * ctl_err_(1) + p_d_torque * ctl_err_vel_(1)
      + p_i_torque * ctl_err_int_(1) + p_ff_torque * controls_(1, 0));

}

// model predictive control using LQR for optimization
#define NUM_EXT_STATES (NUM_STATES+2*NUM_CONTROLS)

void MPCController::mpcLQR(const Matrix<double, NUM_STATES, 1> &s0, const Matrix<double, NUM_CONTROLS, Dynamic> &u0,
    const Matrix<double, NUM_STATES, Dynamic> &s_star, const Matrix<double, NUM_CONTROLS, 1> &u_prev, Matrix<double, NUM_CONTROLS, Dynamic> *u_out) {
  Matrix<double, NUM_STATES, NUM_STATES> A[p_horizon];
  Matrix<double, NUM_STATES, NUM_CONTROLS> B[p_horizon];
  Matrix<double, NUM_EXT_STATES, NUM_EXT_STATES> Ae, P, Q;
  Matrix<double, NUM_EXT_STATES, NUM_CONTROLS> Be;
  Matrix<double, NUM_CONTROLS, NUM_EXT_STATES> K[p_horizon];
  Matrix<double, NUM_CONTROLS, 1> g[p_horizon], u_opt;
  Matrix<double, NUM_STATES, Dynamic> s(NUM_STATES, p_horizon + 1);
  Matrix<double, NUM_EXT_STATES, 1> s_opt, q, ds;
  Matrix<double, NUM_STATES, 1> s_next;
  Matrix<double, NUM_CONTROLS, NUM_CONTROLS> Z;
  Matrix2d R;

  s.col(0) = s0;
  // initialize cost and dynamics matrices
  for (int i = 0; i < p_horizon; i++) {
    simulateRK4(s.col(i), u0.col(i), &s_next, &A[i], &B[i]);
    s.col(i + 1) = s_next;
  }

  // initialize extended dynamics matrices
  Ae.setZero();
  Ae.block(NUM_STATES + NUM_CONTROLS, NUM_STATES, NUM_CONTROLS, NUM_CONTROLS) = Matrix<double, NUM_CONTROLS, NUM_CONTROLS>::Identity();
  Be.setZero();
  Be.block(NUM_STATES, 0, NUM_CONTROLS, NUM_CONTROLS) = Matrix<double, NUM_CONTROLS, NUM_CONTROLS>::Identity();

  Q.setZero();
  Q.block(0, 0, NUM_STATES, NUM_STATES) = p_Q;
  R = Rotation2D<double> (s_star(2, p_horizon)).toRotationMatrix();
  Q.block(0, 0, 2, 2) = R.transpose() * p_Q.block(0, 0, 2, 2) * R;
  Q.block(NUM_STATES, NUM_STATES, NUM_CONTROLS, NUM_CONTROLS) = p_R_delta;
  Q.block(NUM_STATES + NUM_CONTROLS, NUM_STATES, NUM_CONTROLS, NUM_CONTROLS) = -p_R_delta;
  Q.block(NUM_STATES, NUM_STATES + NUM_CONTROLS, NUM_CONTROLS, NUM_CONTROLS) = -p_R_delta;
  Q.block(NUM_STATES + NUM_CONTROLS, NUM_STATES + NUM_CONTROLS, NUM_CONTROLS, NUM_CONTROLS) = p_R_delta;

  s_opt.block(0, 0, NUM_STATES, 1) = s_star.col(p_horizon) - s.col(p_horizon);
  s_opt.block(NUM_STATES, 0, NUM_CONTROLS, 1) = -u0.col(p_horizon - 1);
  s_opt.block(NUM_STATES + NUM_CONTROLS, 0, NUM_CONTROLS, 1) = -u0.col(p_horizon - 2);

  // Ricatti recursion
  P = Q;
  q = -Q * s_opt;
  for (int i = p_horizon - 1; i >= 0; i--) {
    R = Rotation2D<double> (s_star(2, i)).toRotationMatrix();
    Q.block(0, 0, 2, 2) = R.transpose() * p_Q.block(0, 0, 2, 2) * R;

    s_opt.block(0, 0, NUM_STATES, 1) = s_star.col(i) - s.col(i);
    if (i >= 1) {
      s_opt.block(NUM_STATES, 0, NUM_CONTROLS, 1) = -u0.col(i - 1);
    }
    else {
      s_opt.block(NUM_STATES, 0, NUM_CONTROLS, 1) = -u_prev;
    }
    if (i >= 2) {
      s_opt.block(NUM_STATES + NUM_CONTROLS, 0, NUM_CONTROLS, 1) = -u0.col(i - 2);
    }
    else {
      s_opt.block(NUM_STATES + NUM_CONTROLS, 0, NUM_CONTROLS, 1) = -u_prev;
    }
    u_opt = -u0.col(i);

    Ae.block(0, 0, NUM_STATES, NUM_STATES) = A[i];
    Be.block(0, 0, NUM_STATES, NUM_CONTROLS) = B[i];

    Z = (p_R + Be.transpose() * P * Be).inverse();
    K[i] = -Z * Be.transpose() * P * Ae;
    g[i] = -Z * (Be.transpose() * q - p_R * u_opt);
    P = Q + Ae.transpose() * P * Ae + Ae.transpose() * P * Be * K[i];
    P = 0.5 * (P + P.transpose());
    q = (Ae + Be * K[i]).transpose() * q - K[i].transpose() * p_R * u_opt - Q * s_opt;
  }

  // simulate forward
  s_next = s0;
  for (int i = 0; i < p_horizon; i++) {
    ds.block(0, 0, NUM_STATES, 1) = s_next - s.col(i);
    if (i >= 1) {
      ds.block(NUM_STATES, 0, NUM_CONTROLS, 1) = u_out->col(i - 1) - u0.col(i - 1);
    }
    else {
      ds.block(NUM_STATES, 0, NUM_CONTROLS, 1).setZero();
    }
    if (i >= 2) {
      ds.block(NUM_STATES + NUM_CONTROLS, 0, NUM_CONTROLS, 1) = u_out->col(i - 2) - u0.col(i - 2);
    }
    else {
      ds.block(NUM_STATES + NUM_CONTROLS, 0, NUM_CONTROLS, 1).setZero();
    }

    u_out->col(i) = u0.col(i) + K[i] * ds + g[i];
    (*u_out)(1, i) = max((*u_out)(1, i), -p_vs.param.max_wheel_angle);
    (*u_out)(1, i) = min((*u_out)(1, i), p_vs.param.max_wheel_angle);
    simulateRK4(s_next, u_out->col(i), &s_next);
  }
}

#define EPSILON 1e-5

// dynamics of the car (bicycle model with velocity/steering input)
void MPCController::dynamics(const Matrix<double, NUM_STATES, 1> &s, const Matrix<double, NUM_CONTROLS, 1> &u_, Matrix<double, NUM_STATES, 1> *s_dot, Matrix<
    double, NUM_STATES, NUM_STATES> *A, Matrix<double, NUM_STATES, NUM_CONTROLS> *B) {
  double u = s(3), v = s(4), cos_th = cos(s(2)), sin_th = sin(s(2));
  double th_dot = s(5), u_dot = u_(0);
  double del = u_(1), tan_del = tan(u_(1)), cos_del = cos(u_(1));
  double Fyf, Fyr, Ca = p_vs.param.tire_stiffness, m = p_vs.param.mass, a = p_vs.param.a, b = p_vs.param.b, I = p_vs.param.iz;

  // compute slip angles and lateral forces
  Fyf = -Ca * (atan2(v + th_dot * a, max(u, dgc::dgc_mph2ms(5))) - del);
  Fyr = -Ca * atan2(v - th_dot * b, max(u, dgc::dgc_mph2ms(5)));

  // compute derivatives
  (*s_dot)(0) = u * cos_th - v * sin_th;
  (*s_dot)(1) = u * sin_th + v * cos_th;
  (*s_dot)(2) = th_dot;

  (*s_dot)(3) = u_dot;
  (*s_dot)(4) = tan_del * (u_dot - th_dot * v) + (Fyf / cos_del + Fyr) / m - th_dot * u;
  (*s_dot)(5) = m * a / I * tan_del * (u_dot - th_dot * v) + a * Fyf / (I * cos_del) - b * Fyr / I;

  // compute Jacobians (numerically) if desired
  if (A != 0) {
    Matrix<double, NUM_STATES, 1> s2 = s;
    Matrix<double, NUM_STATES, 1> s_dot1, s_dot2;
    for (int i = 0; i < NUM_STATES; i++) {
      s2(i) += EPSILON;
      dynamics(s2, u_, &s_dot1, 0, 0);
      s2(i) -= 2 * EPSILON;
      dynamics(s2, u_, &s_dot2, 0, 0);
      s2(i) += EPSILON;
      A->col(i) = (s_dot1 - s_dot2) / (2 * EPSILON);
    }
  }

  if (B != 0) {
    Matrix<double, NUM_CONTROLS, 1> u2 = u_;
    Matrix<double, NUM_STATES, 1> s_dot1, s_dot2;
    for (int i = 0; i < NUM_CONTROLS; i++) {
      u2(i) += EPSILON;
      dynamics(s, u2, &s_dot1, 0, 0);
      u2(i) -= 2 * EPSILON;
      dynamics(s, u2, &s_dot2, 0, 0);
      u2(i) += EPSILON;
      B->col(i) = (s_dot1 - s_dot2) / (2 * EPSILON);
    }
  }
}

void MPCController::simulateEuler(const Matrix<double, NUM_STATES, 1> &s, const Matrix<double, NUM_CONTROLS, 1> &u, Matrix<double, NUM_STATES, 1> *s_next,
    Matrix<double, NUM_STATES, NUM_STATES> *A, Matrix<double, NUM_STATES, NUM_CONTROLS> *B) {
  Matrix<double, NUM_STATES, 1> s_dot;
  dynamics(s, u, &s_dot, A, B);
  (*s_next) = s + s_dot / p_hertz;

  if (A) {
    (*A) /= p_hertz;
    (*A) += Matrix<double, NUM_STATES, NUM_STATES>::Identity();
  }

  if (B) (*B) /= p_hertz;
}

void MPCController::simulateRK4(const Matrix<double, NUM_STATES, 1> &s, const Matrix<double, NUM_CONTROLS, 1> &u, Matrix<double, NUM_STATES, 1> *s_next,
    Matrix<double, NUM_STATES, NUM_STATES> *A, Matrix<double, NUM_STATES, NUM_CONTROLS> *B) {
  Matrix<double, NUM_STATES, 1> k1, k2, k3, k4;
  double dt = 1 / p_hertz;

  dynamics(s, u, &k1);
  dynamics(s + 0.5 * dt * k1, u, &k2);
  dynamics(s + 0.5 * dt * k2, u, &k3);
  dynamics(s + dt * k3, u, &k4);
  (*s_next) = s + dt * (k1 / 6.0 + k2 / 3.0 + k3 / 3.0 + k4 / 6.0);

  // compute Jacobians (numerically) if desired
  if (A != 0) {
    Matrix<double, NUM_STATES, 1> s2 = s;
    Matrix<double, NUM_STATES, 1> sn1, sn2;
    for (int i = 0; i < NUM_STATES; i++) {
      s2(i) += EPSILON;
      simulateRK4(s2, u, &sn1, 0, 0);
      s2(i) -= 2 * EPSILON;
      simulateRK4(s2, u, &sn2, 0, 0);
      s2(i) += EPSILON;
      A->col(i) = (sn1 - sn2) / (2 * EPSILON);
    }
  }

  if (B != 0) {
    Matrix<double, NUM_CONTROLS, 1> u2 = u;
    Matrix<double, NUM_STATES, 1> sn1, sn2;
    for (int i = 0; i < NUM_CONTROLS; i++) {
      u2(i) += EPSILON;
      simulateRK4(s, u2, &sn1, 0, 0);
      u2(i) -= 2 * EPSILON;
      simulateRK4(s, u2, &sn2, 0, 0);
      u2(i) += EPSILON;
      B->col(i) = (sn1 - sn2) / (2 * EPSILON);
    }
  }
}

// use simulator to convert change in velocity to "throttle"
double MPCController::simulatorThrottle(double u, double v, double th_dot, double u_dot, double del) {
  double Fyf, Fxf;
  double Ca = p_vs.param.tire_stiffness, m = p_vs.param.mass;

  Fyf = -Ca * (atan2(v + th_dot * p_vs.param.a, max(u, dgc::dgc_mph2ms(5))) - del);
  Fxf = (m * u_dot - m * th_dot * v + Fyf * sin(del)) / cos(del);

  if (Fxf > 0) {
    return Fxf / (m * p_vs.param.throttle_accel_coef);
  }
  else {
    return Fxf / (m * 100.0 * p_vs.param.brake_decel_coef);
  }
}

template <class T> void MPCController::getParam(std::string key, T& var) {
  if(!nh_.getParam(key, var)) {
    throw VLRException("Cannot read parameter " + key + std::string("."));
  }
}

} // namespace vlr


text:
/*
   Copyright 2012 Technical University of Denmark, DTU Compute.
   All rights reserved.

   This file is part of the Patmos simulator.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

      1. Redistributions of source code must retain the above copyright notice,
         this list of conditions and the following disclaimer.

      2. Redistributions in binary form must reproduce the above copyright
         notice, this list of conditions and the following disclaimer in the
         documentation and/or other materials provided with the distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
   NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   The views and conclusions contained in the software and documentation are
   those of the authors and should not be interpreted as representing official
   policies, either expressed or implied, of the copyright holder.
 */

//
// Implementation of data caches.
//
#include "data-cache.h"

#include "memory.h"
#include "exception.h"
#include "simulation-core.h"

#include <boost/format.hpp>

using namespace patmos;

template<bool LRU_REPLACEMENT>
unsigned int set_assoc_data_cache_t<LRU_REPLACEMENT>::
             get_block_address(uword_t address, uword_t size)
{
  // align to block addresses
  unsigned int block_address = (address / Num_block_bytes) *
				  Num_block_bytes;
  assert(block_address == (((address + size - 1) / Num_block_bytes) *
			    Num_block_bytes));

  return block_address;
}

template<bool LRU_REPLACEMENT>
set_assoc_data_cache_t<LRU_REPLACEMENT>::
set_assoc_data_cache_t(memory_t &memory, unsigned int associativity,
                       unsigned int num_blocks,
                       unsigned int num_block_bytes) :
    ideal_data_cache_t(memory), Num_blocks(num_blocks),
    Num_block_bytes(num_block_bytes),
    Associativity(associativity),
    Num_indexes(num_blocks / Associativity), Is_busy(false),
    Num_stall_cycles(0),
    Num_read_hits(0), Num_read_misses(0), Num_read_hit_bytes(0),
    Num_read_miss_bytes(0), Num_write_hits(0), Num_write_misses(0),
    Num_write_hit_bytes(0), Num_write_miss_bytes(0)
{
  assert(num_blocks % Associativity == 0);
  Content = new cache_tags_t[Num_indexes];

  // initialize tags
  for(unsigned int i = 0; i < Num_indexes; i++)
  {
    Content[i] = new cache_tag_t[Associativity];
    for(unsigned int j = 0; j < Associativity; j++)
    {
      Content[i][j].Is_valid = false;
    }
  }
}

template<bool LRU_REPLACEMENT>
set_assoc_data_cache_t<LRU_REPLACEMENT>::~set_assoc_data_cache_t()
{
  // free tag information.
  delete[] Content;
}

template<bool LRU_REPLACEMENT>
bool set_assoc_data_cache_t<LRU_REPLACEMENT>::
read(simulator_t &s, uword_t address, byte_t *value, uword_t size, bool is_fetch)
{
  // temporary buffer
  byte_t buf[Num_block_bytes];

  // get block address
  unsigned int block_address = get_block_address(address, size);

  if (address - block_address + size > Num_block_bytes) {
    // Either size too big or not properly aligned
    simulation_exception_t::unaligned(address);
  }

  // get tag information
  unsigned int entry_index = (block_address / Num_block_bytes)
			     % Num_indexes;
  cache_tags_t &tags(Content[entry_index]);

  // tag_index corresponds to age of the cache block; we have
  // (tag_index == Associativity) iff tag is not in the cache
  unsigned int tag_index = Associativity;

  // check if content is in the cache
  for(unsigned int i = 0; i < Associativity; i++)
  {
    if (tags[i].Is_valid && tags[i].Block_address == block_address)
    {
      tag_index = i;
      break;
    }
  }

  bool cache_hit = (tag_index < Associativity);

  // update cache state and read data
  if (cache_hit || Memory.read(s, block_address, buf, Num_block_bytes, is_fetch))
  {
    // update LRU ordering
    unsigned int last_index_changed;
    if (cache_hit)
      last_index_changed = tag_index;
    else
      last_index_changed = Associativity-1;

    // no update on cache hit for FIFO
    if (LRU_REPLACEMENT || ! cache_hit)
    {
      for(unsigned int i = last_index_changed; i != 0; i--)
      {
	tags[i] = tags[i -1];
      }

      // set tag information
      tags[0].Is_valid = 1;
      tags[0].Block_address = block_address;
    }

    // actually read data from memory without stalling
    // TODO we should keep the data in the cache and read it from
    // there to detect consistency problems with multi-cores.
    Memory.read_peek(s, address, value, size, is_fetch);

    // update statistics
    if (cache_hit)
    {
      Num_read_hits++;
      Num_read_hit_bytes += size;
    }
    else
    {
      Num_read_misses++;
      Num_read_miss_bytes += size;
    }

    Is_busy = false;
    return true;
  }

  Is_busy = true;
  Num_stall_cycles++;
  return false;
}

template<bool LRU_REPLACEMENT>
bool set_assoc_data_cache_t<LRU_REPLACEMENT>::
     write(simulator_t &s, uword_t address, byte_t *value, uword_t size)
{
  // get block address
  unsigned int block_address = get_block_address(address, size);

  // read block data to simulate a block-based write
  byte_t buf[Num_block_bytes];
  Memory.read_peek(s, block_address, buf, Num_block_bytes, false);

  if (Memory.write(s, block_address, buf, Num_block_bytes))
  {
    // get tag information
    unsigned int entry_index = (block_address / Num_block_bytes)
			       % Num_indexes;
    cache_tags_t &tags(Content[entry_index]);

    // check if content is in the cache
    unsigned int tag_index = Associativity;
    for(unsigned int i = 0; i < Associativity; i++)
    {
      if (tags[i].Is_valid && tags[i].Block_address == block_address)
      {
	tag_index = i;
	break;
      }
    }

    // No write allocate; contents of cache is updated on write-hit,
    // but as the simulator implementation does not store contents in
    // the cache, we simply omit cache updates for the write-through D$

    bool cache_hit = (tag_index < Associativity);

    // update statistics
    if (cache_hit)
    {
      Num_write_hits++;
      Num_write_hit_bytes += size;
    }
    else
    {
      Num_write_misses++;
      Num_write_miss_bytes += size;
    }
    // actually write the data
    Memory.write_peek(s, address, value, size);

    Is_busy = false;
    return true;
  }
  else {
    Is_busy = true;
    Num_stall_cycles++;
    return false;
  }
}

template<bool LRU_REPLACEMENT>
bool set_assoc_data_cache_t<LRU_REPLACEMENT>::is_ready()
{
  return !Is_busy;
}

template<bool LRU_REPLACEMENT>
void set_assoc_data_cache_t<LRU_REPLACEMENT>::
     print(const simulator_t &s, std::ostream &os) const
{
  for(unsigned int i = 0; i < Num_indexes; i++)
  {
    bool is_empty = true;
    for(unsigned int j = 0; j < Associativity; j++)
    {
      if (Content[i][j].Is_valid)
      {
	if (is_empty)
	  os << boost::format("%1$03d:") % i;

	os << boost::format("  %1$08x") % Content[i][j].Block_address;
	is_empty = false;
      }
    }

    if (!is_empty)
      os << "\n";
  }

  os << "\n";
}

template<bool LRU_REPLACEMENT>
void set_assoc_data_cache_t<LRU_REPLACEMENT>::
     print_stats(const simulator_t &s, std::ostream &os,
                 const stats_options_t& options)
{
  // data cache statistics
  unsigned int total_reads = Num_read_hits + Num_read_misses;
  unsigned int read_miss_rate = total_reads == 0 ? 0 :
				      (Num_read_misses * 100) / total_reads;
  unsigned int read_transfer_bytes = Num_read_misses * Num_block_bytes;
  unsigned int total_read_bytes = Num_read_hit_bytes + Num_read_miss_bytes;
  float        read_reuse = (float)total_read_bytes /
			    (float)read_transfer_bytes;

  unsigned int total_writes = Num_write_hits + Num_write_misses;
  unsigned int write_miss_rate = total_writes == 0 ? 0 :
				    (Num_write_misses * 100) / total_writes;
  unsigned int write_transfer_bytes = total_writes * Num_block_bytes;
  unsigned int total_write_bytes = Num_write_hit_bytes + Num_write_miss_bytes;
  float        write_reuse = (float)total_write_bytes /
			     (float)write_transfer_bytes;

  // Ratio of bytes loaded from memory to bytes fetched from cache.
  // For every miss we load one full cache line.
  unsigned int bytes_transferred = Num_read_misses * Num_block_bytes +
				   Num_write_misses * Num_block_bytes;
  float transfer_ratio = total_reads == 0 && total_writes == 0 ? 0 :
			(float)bytes_transferred /
			(float)(Num_read_hit_bytes + Num_read_miss_bytes +
				Num_write_hit_bytes + Num_write_miss_bytes);

  os << boost::format("   Bytes Transferred   : %1$10d\n"
		      "   Transfer Ratio      : %2$10.3f\n"
		      "   Miss Stall Cycles   : %3$10d  %4$10.2f%%\n\n")
    % bytes_transferred
    % transfer_ratio
    % Num_stall_cycles % (100.0 * (float)Num_stall_cycles/(float)s.Cycle);

  os << boost::format("                           total        hit      miss    miss-rate     reuse\n"
		      "   Reads            : %1$10d %2$10d %3$10d %4$10d%%\n"
		      "   Bytes Read       : %5$10d %6$10d %7$10d          - %8$10.2f\n"
		      "   Writes           : %9$10d %10$10d %11$10d %12$10d%%\n"
		      "   Bytes Written    : %13$10d %14$10d %15$10d          - %16$10.2f\n")
    % total_reads % Num_read_hits % Num_read_misses % read_miss_rate
    % total_read_bytes % Num_read_hit_bytes % Num_read_miss_bytes
    % read_reuse
    % total_writes % Num_write_hits % Num_write_misses % write_miss_rate
    % total_write_bytes % Num_write_hit_bytes % Num_write_miss_bytes
    % write_reuse;
}

template<bool LRU_REPLACEMENT>
void set_assoc_data_cache_t<LRU_REPLACEMENT>::reset_stats()
{
  Num_stall_cycles = 0;
  Num_read_hits = 0;
  Num_read_misses = 0;
  Num_read_hit_bytes = 0;
  Num_read_miss_bytes = 0;
  Num_write_hits = 0;
  Num_write_misses = 0;
  Num_write_hit_bytes = 0;
  Num_write_miss_bytes = 0;
}

template<bool LRU_REPLACEMENT>
void set_assoc_data_cache_t<LRU_REPLACEMENT>::flush_cache()
{
  for(unsigned int i = 0; i < Num_indexes; i++)
  {
    for(unsigned int j = 0; j < Associativity; j++)
    {
      Content[i][j].Is_valid = false;
    }
  }
}

// Explicit instantiation of template class for linking.
template class set_assoc_data_cache_t<false>;
template class set_assoc_data_cache_t<true>;

ext: cc

max_stars_repo_name: laurenkosub/wormhole-noc

max_issues_repo_name: laurenkosub/wormhole-noc

max_forks_repo_name: laurenkosub/wormhole-noc


text:
#ifndef LOGGER_H_
#define LOGGER_H_

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>

#include "logger/ILogger.hpp"

namespace logger = boost::log;
namespace sinks = boost::log::sinks;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;

using namespace logger::trivial;

namespace ice_engine
{
namespace logger
{

class Logger : public ILogger
{
public:
	Logger(const std::string& fileName = std::string("ice_engine.log"));
	Logger(const Logger& other);
	Logger& operator=(const Logger& other);
	virtual ~Logger();

	virtual void info(const std::string& message) override;
	virtual void debug(const std::string& message) override;
	virtual void trace(const std::string& message) override;
	virtual void warn(const std::string& message) override;
	virtual void error(const std::string& message) override;
	virtual void fatal(const std::string& message) override;

	virtual void info(const std::wstring& message) override;
	virtual void debug(const std::wstring& message) override;
	virtual void trace(const std::wstring& message) override;
	virtual void warn(const std::wstring& message) override;
	virtual void error(const std::wstring& message) override;
	virtual void fatal(const std::wstring& message) override;

private:
	src::severity_logger< severity_level > log_;
};

}

}

#endif /* LOGGER_H_ */