text:
/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

//
// sandesh_client.cc
//
// Sandesh Client
//

#include <boost/bind.hpp>
#include <boost/assign.hpp>
#include <boost/foreach.hpp>

#include <base/task_annotations.h>
#include <base/time_util.h>
#include <io/event_manager.h>
#include <io/tcp_session.h>
#include <io/tcp_server.h>

#include <sandesh/sandesh_constants.h>
#include <sandesh/sandesh_types.h>
#include <sandesh/sandesh.h>
#include <sandesh/sandesh_trace.h>
#include <sandesh/sandesh_session.h>

#include "sandesh_state_machine.h"

#include <sandesh/protocol/TXMLProtocol.h>
#include <sandesh/sandesh_ctrl_types.h>
#include <sandesh/sandesh_uve_types.h>
#include <sandesh/derived_stats_results_types.h>
#include <sandesh/common/vns_constants.h>
#include "sandesh_client.h"
#include "sandesh_uve.h"
#include "sandesh_util.h"

using boost::asio::ip::address;
using namespace boost::asio;
using boost::system::error_code;
using std::string;
using std::map;
using std::make_pair;
using std::vector;

const std::string SandeshClient::kSMTask = "sandesh::SandeshClientSM";
const std::string SandeshClient::kSessionWriterTask = "sandesh::SandeshClientSession";
const std::string SandeshClient::kSessionReaderTask = "sandesh::SandeshClientReader";
bool SandeshClient::task_policy_set_ = false;
const std::vector<Sandesh::QueueWaterMarkInfo>
    SandeshClient::kSessionWaterMarkInfo = boost::assign::tuple_list_of
                                               (50*1024*1024, SandeshLevel::SYS_UVE, true, false)
                                               (30*1024*1024, SandeshLevel::SYS_EMERG, true, false)
                                               (20*1024*1024, SandeshLevel::SYS_ERR, true, false)
                                               (1*1024*1024, SandeshLevel::SYS_DEBUG, true, false)
                                               (35*1024*1024, SandeshLevel::SYS_EMERG, false, false)
                                               (25*1024*1024, SandeshLevel::SYS_ERR, false, false)
                                               (15*1024*1024, SandeshLevel::SYS_DEBUG, false, false)
                                               (2*1024, SandeshLevel::INVALID, false, false);

SandeshClient::SandeshClient(EventManager *evm,
        const std::vector<Endpoint> &collectors,
        const SandeshConfig &config,
        bool periodicuve)
    :   SslServer(evm, boost::asio::ssl::context::tlsv1_client,
                  config.sandesh_ssl_enable),
        sm_task_instance_(kSMTaskInstance),
        sm_task_id_(TaskScheduler::GetInstance()->GetTaskId(kSMTask)),
        session_task_instance_(kSessionTaskInstance),
        session_writer_task_id_(TaskScheduler::GetInstance()->GetTaskId(kSessionWriterTask)),
        session_reader_task_id_(TaskScheduler::GetInstance()->GetTaskId(kSessionReaderTask)),
        dscp_value_(0),
        collectors_(collectors),
        sm_(SandeshClientSM::CreateClientSM(evm, this, sm_task_instance_, sm_task_id_, periodicuve)),
        session_wm_info_(kSessionWaterMarkInfo),
        session_close_interval_msec_(0),
        session_close_time_usec_(0) {
    // Set task policy for exclusion between state machine and session tasks since
    // session delete happens in state machine task
    if (!task_policy_set_) {
        TaskPolicy sm_task_policy = boost::assign::list_of
                (TaskExclusion(session_writer_task_id_))
                (TaskExclusion(session_reader_task_id_));
        TaskScheduler::GetInstance()->SetPolicy(sm_task_id_, sm_task_policy);
        task_policy_set_ = true;
    }
    if (config.sandesh_ssl_enable) {
        boost::asio::ssl::context *ctx = context();
        boost::system::error_code ec;
        ctx->set_options(boost::asio::ssl::context::default_workarounds |
                         boost::asio::ssl::context::no_sslv3 |
                         boost::asio::ssl::context::no_sslv2, ec);
        if (ec.value() != 0) {
            SANDESH_LOG(ERROR, "Error setting ssl options: " << ec.message());
            exit(EINVAL);
        }
        // CA certificate
        if (!config.ca_cert.empty()) {
            // Verify that the peer certificate is signed by a trusted CA
            ctx->set_verify_mode(boost::asio::ssl::verify_peer |
                                 boost::asio::ssl::verify_fail_if_no_peer_cert,
                                 ec);
            if (ec.value() != 0) {
                SANDESH_LOG(ERROR, "Error setting verification mode: " <<
                            ec.message());
                exit(EINVAL);
            }
            ctx->load_verify_file(config.ca_cert, ec);
            if (ec.value() != 0) {
                SANDESH_LOG(ERROR, "Error loading CA certificate: " <<
                            ec.message());
                exit(EINVAL);
            }
        }
        // Server certificate
        ctx->use_certificate_chain_file(config.certfile, ec);
        if (ec.value() != 0) {
            SANDESH_LOG(ERROR, "Error using server certificate: " <<
                        ec.message());
            exit(EINVAL);
        }
        // Server private key
        ctx->use_private_key_file(config.keyfile,
                                  boost::asio::ssl::context::pem, ec);
        if (ec.value() != 0) {
            SANDESH_LOG(ERROR, "Error using server private key file: " <<
                        ec.message());
            exit(EINVAL);
        }
    }
}

SandeshClient::~SandeshClient() {}

void SandeshClient::ReConfigCollectors(
        const std::vector<std::string>& collector_list) {
    std::vector<Endpoint> collector_endpoints;

    BOOST_FOREACH(const std::string& collector, collector_list) {
        Endpoint ep;
        if (!MakeEndpoint(&ep, collector)) {
            SANDESH_LOG(ERROR, __func__ << ": Invalid collector address: " <<
                        collector);
            return;
        }
        collector_endpoints.push_back(ep);
    }
    sm_->SetCollectors(collector_endpoints);
}

void SandeshClient::Initiate() {
    sm_->SetAdminState(false);
    if (collectors_.size())
        sm_->SetCollectors(collectors_);
}

void SandeshClient::Shutdown() {
    sm_->SetAdminState(true);
}

bool SandeshClient::SendSandesh(Sandesh *snh) {
    return sm_->SendSandesh(snh);
}

bool SandeshClient::ReceiveCtrlMsg(const std::string &msg,
        const SandeshHeader &header, const std::string &sandesh_name,
        const uint32_t header_offset) {

    Sandesh * sandesh = SandeshSession::DecodeCtrlSandesh(msg, header, sandesh_name, header_offset);

    const SandeshCtrlServerToClient * snh = dynamic_cast<const SandeshCtrlServerToClient *>(sandesh);
    if (!snh) {
        SANDESH_LOG(ERROR, "Received Ctrl Message with wrong type " << sandesh->Name());
        sandesh->Release();
        return false;
    }
    if (!snh->get_success()) {
        SANDESH_LOG(ERROR, "Received Ctrl Message : Connection with server has failed");
        sandesh->Release();
        return false;
    }
    SANDESH_LOG(DEBUG, "Received Ctrl Message with size " << snh->get_type_info().size());

    map<string,uint32_t> sMap;
    const vector<UVETypeInfo> & vu = snh->get_type_info();
    for(uint32_t i = 0; i < vu.size(); i++) {
        sMap.insert(std::make_pair(vu[i].get_type_name(), vu[i].get_seq_num()));
    }
    SandeshUVETypeMaps::SyncAllMaps(sMap);

    sandesh->Release();
    return true;
}

bool SandeshClient::ReceiveMsg(const std::string& msg,
        const SandeshHeader &header, const std::string &sandesh_name,
        const uint32_t header_offset) {

    namespace sandesh_prot = contrail::sandesh::protocol;
    namespace sandesh_trans = contrail::sandesh::transport;

    if (header.get_Hints() & g_sandesh_constants.SANDESH_CONTROL_HINT) {
        bool success = ReceiveCtrlMsg(msg, header, sandesh_name, header_offset);
        if (success) {
            Sandesh::UpdateRxMsgStats(sandesh_name, msg.size());
        } else {
            Sandesh::UpdateRxMsgFailStats(sandesh_name, msg.size(),
                SandeshRxDropReason::ControlMsgFailed);
        }
        return success;
    }

    // Create and process the sandesh
    Sandesh *sandesh = SandeshBaseFactory::CreateInstance(sandesh_name);
    if (sandesh == NULL) {
        SANDESH_LOG(ERROR, __func__ << ": Unknown sandesh: " << sandesh_name);
        Sandesh::UpdateRxMsgFailStats(sandesh_name, msg.size(),
            SandeshRxDropReason::CreateFailed);
        return true;
    }
    boost::shared_ptr<sandesh_trans::TMemoryBuffer> btrans =
            boost::shared_ptr<sandesh_trans::TMemoryBuffer>(
                    new sandesh_trans::TMemoryBuffer((uint8_t *)msg.c_str() + header_offset,
                            msg.size() - header_offset));
    boost::shared_ptr<sandesh_prot::TXMLProtocol> prot =
            boost::shared_ptr<sandesh_prot::TXMLProtocol>(new sandesh_prot::TXMLProtocol(btrans));
    int32_t xfer = sandesh->Read(prot);
    if (xfer < 0) {
        SANDESH_LOG(ERROR, __func__ << ": Decoding " << sandesh_name << " FAILED");
        Sandesh::UpdateRxMsgFailStats(sandesh_name, msg.size(),
            SandeshRxDropReason::DecodingFailed);
        return false;
    }

    Sandesh::UpdateRxMsgStats(sandesh_name, msg.size());
    SandeshRequest *sr = dynamic_cast<SandeshRequest *>(sandesh);
    assert(sr);
    sr->Enqueue(Sandesh::recv_queue());
    return true;
}

void
SandeshCtrlServerToClient::HandleRequest() const { }

void
SandeshCtrlClientToServer::HandleRequest() const { }

SandeshSession *SandeshClient::CreateSMSession(
        TcpSession::EventObserver eocb,
        SandeshReceiveMsgCb rmcb,
        TcpServer::Endpoint ep) {
    TcpSession *session = SslServer::CreateSession();
    Socket *socket = session->socket();

    error_code ec;
    socket->open(ip::tcp::v4(), ec);
    if (ec) {
        SANDESH_LOG(ERROR, __func__ << " Open FAILED: " << ec.message());
        DeleteSession(session);
        return NULL;
    }
    ec = session->SetSocketOptions();
    if (ec) {
        SANDESH_LOG(ERROR, __func__ << " Unable to set socket options: " << ec.message());
        DeleteSession(session);
        return NULL;
    }
    if (dscp_value_) {
        session->SetDscpSocketOption(dscp_value_);
    }
    SandeshSession *sandesh_session =
            static_cast<SandeshSession *>(session);
    sandesh_session->SetReceiveMsgCb(rmcb);
    sandesh_session->SetConnection(NULL);
    sandesh_session->set_observer(eocb);
    // Set watermarks
    for (size_t i = 0; i < session_wm_info_.size(); i++) {
        sandesh_session->SetSendQueueWaterMark(session_wm_info_[i]);
    }
    TcpServer::Connect(sandesh_session, ep);

    return sandesh_session;
}

void SandeshClient::InitializeSMSession(int count) {
    std::vector<string> stv;

    SandeshUVETypeMaps::uve_global_map::const_iterator it =
        SandeshUVETypeMaps::Begin();
    for(; it!= SandeshUVETypeMaps::End(); it++) {
        stv.push_back(it->first);
    }
    SANDESH_LOG(DEBUG, "Sending Ctrl Message for " << Sandesh::source() << ":" <<
        Sandesh::module() << ":" << Sandesh::instance_id() << ":" <<
        Sandesh::node_type() << " count " << count);

    SandeshCtrlClientToServer::Request(Sandesh::source(), Sandesh::module(),
            count, stv, getpid(), Sandesh::http_port(),
            Sandesh::node_type(), Sandesh::instance_id(), "ctrl");

}

bool SandeshClient::CloseSMSessionInternal() {
    SandeshSession *session(sm_->session());
    if (session) {
        session->EnqueueClose();
        return true;
    }
    return false;
}

bool DoCloseSMSession(uint64_t now_usec, uint64_t last_close_usec,
    uint64_t last_close_interval_usec, int *close_interval_msec) {
    // If this is the first time, we will accept the next close
    // only after the initial close interval time
    if (last_close_interval_usec == 0 || last_close_usec == 0) {
        *close_interval_msec =
            SandeshClient::kInitialSMSessionCloseIntervalMSec;
        return true;
    }
    assert(now_usec >= last_close_usec);
    uint64_t time_since_close_usec(now_usec - last_close_usec);
    // We will ignore close events receive before the last close
    // interval is finished
    if (time_since_close_usec <= last_close_interval_usec) {
        *close_interval_msec = 0;
        return false;
    }
    // We will double the close interval time if we get a close
    // event between last close interval and 2 * last close interval.
    // If the close event is between 2 * last close interval and
    // 4 * last close interval, then the close interval will be
    // same as the current close interval. If the close event is
    // after 4 * last close interval, then we will reset the close
    // interval to the initial close interval
    if (time_since_close_usec > last_close_interval_usec &&
        time_since_close_usec <= 2 * last_close_interval_usec) {
        uint64_t nclose_interval_msec((2 * last_close_interval_usec)/1000);
        *close_interval_msec = std::min(nclose_interval_msec,
            static_cast<uint64_t>(
            SandeshClient::kMaxSMSessionCloseIntervalMSec));
        return true;
    } else if ((2 * last_close_interval_usec <= time_since_close_usec) &&
        (time_since_close_usec <= 4 * last_close_interval_usec)) {
        *close_interval_msec = last_close_interval_usec/1000;
        return true;
    } else {
        *close_interval_msec =
            SandeshClient::kInitialSMSessionCloseIntervalMSec;
        return true;
    }
}

bool SandeshClient::CloseSMSession() {
    uint64_t now_usec(UTCTimestampUsec());
    int close_interval_msec(0);
    bool close(DoCloseSMSession(now_usec, session_close_time_usec_,
        session_close_interval_msec_ * 1000, &close_interval_msec));
    if (close) {
        session_close_time_usec_ = now_usec;
        session_close_interval_msec_ = close_interval_msec;
        return CloseSMSessionInternal();
    }
    return false;
}

static bool client_start = false;
static uint64_t client_start_time;

void SandeshClient::SendUVE(int count,
        const string & stateName, const string & server,
        const Endpoint & server_ip,
        const std::vector<TcpServer::Endpoint> & collector_eps) {
    ModuleClientState mcs;
    mcs.set_name(Sandesh::source() + ":" + Sandesh::node_type() +
        ":" + Sandesh::module() + ":" + Sandesh::instance_id());
    SandeshClientInfo sci;
    if (!client_start) {
        client_start_time = UTCTimestampUsec();
        client_start = true;
    }
    sci.set_start_time(client_start_time);
    sci.set_successful_connections(count);
    sci.set_pid(getpid());
    sci.set_http_port(Sandesh::http_port());
    sci.set_status(stateName);
    sci.set_collector_name(server);
    std::ostringstream collector_ip;
    collector_ip << server_ip;
    sci.set_collector_ip(collector_ip.str());
    std::vector<std::string> collectors;
    BOOST_FOREACH(const TcpServer::Endpoint& ep, collector_eps) {
        std::ostringstream collector_ip;
        collector_ip << ep;
        collectors.push_back(collector_ip.str());
    }
    sci.set_collector_list(collectors);
    // Sandesh client socket statistics
    SocketIOStats rx_stats;
    GetRxSocketStats(rx_stats);
    sci.set_rx_socket_stats(rx_stats);
    SocketIOStats tx_stats;
    GetTxSocketStats(tx_stats);
    sci.set_tx_socket_stats(tx_stats);

    mcs.set_client_info(sci);

    std::vector<SandeshMessageTypeStats> mtype_stats;
    SandeshMessageStats magg_stats;
    Sandesh::GetMsgStats(&mtype_stats, &magg_stats);

    map<string,uint64_t> csev;
    csev.insert(make_pair("sent", magg_stats.get_messages_sent()));
    csev.insert(make_pair("dropped_no_queue",
             magg_stats.get_messages_sent_dropped_no_queue()));
    csev.insert(make_pair("dropped_no_client",
             magg_stats.get_messages_sent_dropped_no_client()));
    csev.insert(make_pair("dropped_no_session",
             magg_stats.get_messages_sent_dropped_no_session()));
    csev.insert(make_pair("dropped_queue_level",
             magg_stats.get_messages_sent_dropped_queue_level()));
    csev.insert(make_pair("dropped_client_send_failed",
             magg_stats.get_messages_sent_dropped_client_send_failed()));
    csev.insert(make_pair("dropped_session_not_connected",
             magg_stats.get_messages_sent_dropped_session_not_connected()));
    csev.insert(make_pair("dropped_header_write_failed",
             magg_stats.get_messages_sent_dropped_header_write_failed()));
    csev.insert(make_pair("dropped_write_failed",
             magg_stats.get_messages_sent_dropped_write_failed()));
    csev.insert(make_pair("dropped_wrong_client_sm_state",
             magg_stats.get_messages_sent_dropped_wrong_client_sm_state()));
    csev.insert(make_pair("dropped_validation_failed",
             magg_stats.get_messages_sent_dropped_validation_failed()));
    csev.insert(make_pair("dropped_rate_limited",
             magg_stats.get_messages_sent_dropped_rate_limited()));
    csev.insert(make_pair("dropped_sending_disabled",
             magg_stats.get_messages_sent_dropped_sending_disabled()));
    csev.insert(make_pair("dropped_sending_to_syslog",
             magg_stats.get_messages_sent_dropped_sending_to_syslog()));
    mcs.set_tx_msg_agg(csev);

    map <string,SandeshMessageStats> csevm;
    for (vector<SandeshMessageTypeStats>::const_iterator smit = mtype_stats.begin();
            smit != mtype_stats.end(); smit++) {
        SandeshMessageStats res_sms;
        const SandeshMessageStats& src_sms = smit->get_stats();
        res_sms.set_messages_sent(src_sms.get_messages_sent());
        res_sms.set_messages_sent_dropped_no_queue(
            src_sms.get_messages_sent_dropped_no_queue());
        res_sms.set_messages_sent_dropped_no_client(
            src_sms.get_messages_sent_dropped_no_client());
        res_sms.set_messages_sent_dropped_no_session(
            src_sms.get_messages_sent_dropped_no_session());
        res_sms.set_messages_sent_dropped_queue_level(
            src_sms.get_messages_sent_dropped_queue_level());
        res_sms.set_messages_sent_dropped_client_send_failed(
            src_sms.get_messages_sent_dropped_client_send_failed());
        res_sms.set_messages_sent_dropped_session_not_connected(
            src_sms.get_messages_sent_dropped_session_not_connected());
        res_sms.set_messages_sent_dropped_header_write_failed(
            src_sms.get_messages_sent_dropped_header_write_failed());
        res_sms.set_messages_sent_dropped_write_failed(
            src_sms.get_messages_sent_dropped_write_failed());
        res_sms.set_messages_sent_dropped_wrong_client_sm_state(
            src_sms.get_messages_sent_dropped_wrong_client_sm_state());
        res_sms.set_messages_sent_dropped_validation_failed(
            src_sms.get_messages_sent_dropped_validation_failed());
        res_sms.set_messages_sent_dropped_rate_limited(
            src_sms.get_messages_sent_dropped_rate_limited());
        res_sms.set_messages_sent_dropped_sending_disabled(
            src_sms.get_messages_sent_dropped_sending_disabled());
        res_sms.set_messages_sent_dropped_sending_to_syslog(
            src_sms.get_messages_sent_dropped_sending_to_syslog());
        csevm.insert(make_pair(smit->get_message_type(), res_sms));
    }
    mcs.set_msg_type_agg(csevm);

    SandeshModuleClientTrace::Send(mcs);
}

void SandeshClient::SetSessionWaterMarkInfo(
    Sandesh::QueueWaterMarkInfo &scwm) {
    SandeshSession *session = sm_->session();
    if (session) {
        session->SetSendQueueWaterMark(scwm);
    }
    session_wm_info_.push_back(scwm);
}

void SandeshClient::ResetSessionWaterMarkInfo() {
    SandeshSession *session = sm_->session();
    if (session) {
        session->ResetSendQueueWaterMark();
    }
    session_wm_info_.clear();
}

void SandeshClient::GetSessionWaterMarkInfo(
    std::vector<Sandesh::QueueWaterMarkInfo> &scwm_info) const {
    scwm_info = session_wm_info_;
}

SslSession *SandeshClient::AllocSession(SslSocket *socket) {
    return new SandeshSession(this, socket, session_task_instance_,
                              session_writer_task_id_,
                              session_reader_task_id_);
}

void SandeshClient::SetDscpValue(uint8_t value) {
    if (value == dscp_value_)
        return;

    dscp_value_ = value;
    SandeshSession *sess = session();
    if (sess) {
        sess->SetDscpSocketOption(value);
    }

}

ext: cc

max_stars_repo_name: atsgen/contrail-sandesh

max_issues_repo_name: atsgen/contrail-sandesh

max_forks_repo_name: atsgen/contrail-sandesh


text:
//
// detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// 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 BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
#define BOOST_ASIO_DETAIL_BIND_HANDLER_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>

#include <boost/asio/detail/push_options.hpp>

namespace boost {
namespace asio {
namespace detail {

template <typename Handler, typename Arg1>
class binder1
{
public:
  binder1(const Handler& handler, const Arg1& arg1)
    : handler_(handler),
      arg1_(arg1)
  {
  }

  binder1(Handler& handler, const Arg1& arg1)
    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
      arg1_(arg1)
  {
  }

  void operator()()
  {
    handler_(static_cast<const Arg1&>(arg1_));
  }

  void operator()() const
  {
    handler_(arg1_);
  }

//private:
  Handler handler_;
  Arg1 arg1_;
};

template <typename Handler, typename Arg1>
inline void* asio_handler_allocate(std::size_t size,
    binder1<Handler, Arg1>* this_handler)
{
  return boost_asio_handler_alloc_helpers::allocate(
      size, this_handler->handler_);
}

template <typename Handler, typename Arg1>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
    binder1<Handler, Arg1>* this_handler)
{
  boost_asio_handler_alloc_helpers::deallocate(
      pointer, size, this_handler->handler_);
}

template <typename Handler, typename Arg1>
inline bool asio_handler_is_continuation(
    binder1<Handler, Arg1>* this_handler)
{
  return boost_asio_handler_cont_helpers::is_continuation(
      this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1>
inline void asio_handler_invoke(Function& function,
    binder1<Handler, Arg1>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1>
inline void asio_handler_invoke(const Function& function,
    binder1<Handler, Arg1>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Handler, typename Arg1>
inline binder1<Handler, Arg1> bind_handler(Handler handler,
    const Arg1& arg1)
{
  return binder1<Handler, Arg1>(handler, arg1);
}

template <typename Handler, typename Arg1, typename Arg2>
class binder2
{
public:
  binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
    : handler_(handler),
      arg1_(arg1),
      arg2_(arg2)
  {
  }

  binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)
    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
      arg1_(arg1),
      arg2_(arg2)
  {
  }

  void operator()()
  {
    handler_(static_cast<const Arg1&>(arg1_),
        static_cast<const Arg2&>(arg2_));
  }

  void operator()() const
  {
    handler_(arg1_, arg2_);
  }

//private:
  Handler handler_;
  Arg1 arg1_;
  Arg2 arg2_;
};

template <typename Handler, typename Arg1, typename Arg2>
inline void* asio_handler_allocate(std::size_t size,
    binder2<Handler, Arg1, Arg2>* this_handler)
{
  return boost_asio_handler_alloc_helpers::allocate(
      size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
    binder2<Handler, Arg1, Arg2>* this_handler)
{
  boost_asio_handler_alloc_helpers::deallocate(
      pointer, size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2>
inline bool asio_handler_is_continuation(
    binder2<Handler, Arg1, Arg2>* this_handler)
{
  return boost_asio_handler_cont_helpers::is_continuation(
      this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2>
inline void asio_handler_invoke(Function& function,
    binder2<Handler, Arg1, Arg2>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2>
inline void asio_handler_invoke(const Function& function,
    binder2<Handler, Arg1, Arg2>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2>
inline binder2<Handler, Arg1, Arg2> bind_handler(Handler handler,
    const Arg1& arg1, const Arg2& arg2)
{
  return binder2<Handler, Arg1, Arg2>(handler, arg1, arg2);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
class binder3
{
public:
  binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3)
    : handler_(handler),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3)
  {
  }

  binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3)
    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3)
  {
  }

  void operator()()
  {
    handler_(static_cast<const Arg1&>(arg1_),
        static_cast<const Arg2&>(arg2_),
        static_cast<const Arg3&>(arg3_));
  }

  void operator()() const
  {
    handler_(arg1_, arg2_, arg3_);
  }

//private:
  Handler handler_;
  Arg1 arg1_;
  Arg2 arg2_;
  Arg3 arg3_;
};

template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
inline void* asio_handler_allocate(std::size_t size,
    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
  return boost_asio_handler_alloc_helpers::allocate(
      size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
  boost_asio_handler_alloc_helpers::deallocate(
      pointer, size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
inline bool asio_handler_is_continuation(
    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
  return boost_asio_handler_cont_helpers::is_continuation(
      this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3>
inline void asio_handler_invoke(Function& function,
    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3>
inline void asio_handler_invoke(const Function& function,
    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
inline binder3<Handler, Arg1, Arg2, Arg3> bind_handler(Handler handler,
    const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
{
  return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4>
class binder4
{
public:
  binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3, const Arg4& arg4)
    : handler_(handler),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3),
      arg4_(arg4)
  {
  }

  binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3, const Arg4& arg4)
    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3),
      arg4_(arg4)
  {
  }

  void operator()()
  {
    handler_(static_cast<const Arg1&>(arg1_),
        static_cast<const Arg2&>(arg2_),
        static_cast<const Arg3&>(arg3_),
        static_cast<const Arg4&>(arg4_));
  }

  void operator()() const
  {
    handler_(arg1_, arg2_, arg3_, arg4_);
  }

//private:
  Handler handler_;
  Arg1 arg1_;
  Arg2 arg2_;
  Arg3 arg3_;
  Arg4 arg4_;
};

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4>
inline void* asio_handler_allocate(std::size_t size,
    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
  return boost_asio_handler_alloc_helpers::allocate(
      size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
  boost_asio_handler_alloc_helpers::deallocate(
      pointer, size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4>
inline bool asio_handler_is_continuation(
    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
  return boost_asio_handler_cont_helpers::is_continuation(
      this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3, typename Arg4>
inline void asio_handler_invoke(Function& function,
    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3, typename Arg4>
inline void asio_handler_invoke(const Function& function,
    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4>
inline binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(
    Handler handler, const Arg1& arg1, const Arg2& arg2,
    const Arg3& arg3, const Arg4& arg4)
{
  return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
      arg4);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4, typename Arg5>
class binder5
{
public:
  binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
    : handler_(handler),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3),
      arg4_(arg4),
      arg5_(arg5)
  {
  }

  binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
      const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
      arg1_(arg1),
      arg2_(arg2),
      arg3_(arg3),
      arg4_(arg4),
      arg5_(arg5)
  {
  }

  void operator()()
  {
    handler_(static_cast<const Arg1&>(arg1_),
        static_cast<const Arg2&>(arg2_),
        static_cast<const Arg3&>(arg3_),
        static_cast<const Arg4&>(arg4_),
        static_cast<const Arg5&>(arg5_));
  }

  void operator()() const
  {
    handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
  }

//private:
  Handler handler_;
  Arg1 arg1_;
  Arg2 arg2_;
  Arg3 arg3_;
  Arg4 arg4_;
  Arg5 arg5_;
};

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4, typename Arg5>
inline void* asio_handler_allocate(std::size_t size,
    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
  return boost_asio_handler_alloc_helpers::allocate(
      size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4, typename Arg5>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
  boost_asio_handler_alloc_helpers::deallocate(
      pointer, size, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4, typename Arg5>
inline bool asio_handler_is_continuation(
    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
  return boost_asio_handler_cont_helpers::is_continuation(
      this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3, typename Arg4, typename Arg5>
inline void asio_handler_invoke(Function& function,
    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Function, typename Handler, typename Arg1, typename Arg2,
    typename Arg3, typename Arg4, typename Arg5>
inline void asio_handler_invoke(const Function& function,
    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
{
  boost_asio_handler_invoke_helpers::invoke(
      function, this_handler->handler_);
}

template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
    typename Arg4, typename Arg5>
inline binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(
    Handler handler, const Arg1& arg1, const Arg2& arg2,
    const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
{
  return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
      arg3, arg4, arg5);
}

} // namespace detail
} // namespace asio
} // namespace boost

#include <boost/asio/detail/pop_options.hpp>

#endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP

ext: hpp


text:
/***************************************************************************************************************************
 * aruco_det.cpp
 * Author: Jario
 * Update Time: 2020.1.14
 *
 * 说明: 单个二维码识别程序，可识别的二维码在Prometheus/Modules/object_detection/config/aruco_images文件夹中
 *      视野里只允许存在一个二维码 且二维码的字典类型要对应
 *      默认二维码的边长为0.2m
 *      1. 【订阅】图像话题 (默认来自web_cam)
 *         /prometheus/camera/rgb/image_raw
 *      2. 【发布】目标位置，发布话题见 Prometheus/Modules/msgs/msg/DetectionInfo.msg
 *         /prometheus/object_detection/aruco_det
 *      3. 【发布】检测结果的可视化图像话题
 *         /prometheus/camera/rgb/image_aruco_det
***************************************************************************************************************************/
#include <pthread.h>
#include <thread>
#include <chrono>
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>

#include <ros/ros.h>
#include <ros/package.h>
#include <yaml-cpp/yaml.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <geometry_msgs/Pose.h>
#include <std_msgs/Bool.h>
#include <prometheus_msgs/DetectionInfo.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include "opencv2/aruco.hpp"
#include "opencv2/aruco/dictionary.hpp"
#include "opencv2/aruco/charuco.hpp"
#include "opencv2/calib3d.hpp"
#include "message_utils.h"

using namespace std;
using namespace cv;

//【订阅】输入图像
image_transport::Subscriber image_subscriber;
//【发布】检测得到的位置与姿态信息
ros::Publisher pose_pub;
//【发布】输入检测结果图像
image_transport::Publisher aruco_pub;

//【订阅】输入开关量
ros::Subscriber switch_subscriber;
// 接收消息，允许暂停检测
bool is_suspanded = false;
// 使用cout打印消息
bool local_print = false;
// 使用prometheus_msgs::Message打印消息
bool message_print = true;
//【发布】调试消息
ros::Publisher message_pub;
std::string msg_node_name;

void CodeRotateByZ(double x, double y, double thetaz, double& outx, double& outy)
{
    double x1 = x;//将变量拷贝一次，保证&x == &outx这种情况下也能计算正确
    double y1 = y;
    double rz = thetaz * CV_PI / 180;
    outx = cos(rz) * x1 - sin(rz) * y1;
    outy = sin(rz) * x1 + cos(rz) * y1;
}
void CodeRotateByY(double x, double z, double thetay, double& outx, double& outz)
{
    double x1 = x;
    double z1 = z;
    double ry = thetay * CV_PI / 180;
    outx = cos(ry) * x1 + sin(ry) * z1;
    outz = cos(ry) * z1 - sin(ry) * x1;
}
void CodeRotateByX(double y, double z, double thetax, double& outy, double& outz)
{
    double y1 = y;//将变量拷贝一次，保证&y == &y这种情况下也能计算正确
    double z1 = z;
    double rx = thetax * CV_PI / 180;
    outy = cos(rx) * y1 - sin(rx) * z1;
    outz = cos(rx) * z1 + sin(rx) * y1;
}
static float static_depth = 0;
static float static_real_x = 0;
static float static_real_y = 0;

// 相机话题中的图像同步相关变量
int frame_width, frame_height;
std_msgs::Header image_header;
cv::Mat cam_image_copy;
boost::shared_mutex mutex_image_callback;
bool image_status = false;
boost::shared_mutex mutex_image_status;

// 图像接收回调函数，接收web_cam的话题，并将图像保存在cam_image_copy中
void cameraCallback(const sensor_msgs::ImageConstPtr& msg)
{
    if (local_print)
        ROS_DEBUG("[ArucoDetector] USB image received.");

    cv_bridge::CvImagePtr cam_image;

    try {
        cam_image = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
        image_header = msg->header;
    } catch (cv_bridge::Exception& e) {
        if (local_print)
            ROS_ERROR("cv_bridge exception: %s", e.what());
        if (message_print)
            pub_message(message_pub, prometheus_msgs::Message::ERROR, msg_node_name, "cv_bridge exception");
        return;
    }

    if (cam_image) {
        {
            boost::unique_lock<boost::shared_mutex> lockImageCallback(mutex_image_callback);
            cam_image_copy = cam_image->image.clone();
        }
        {
            boost::unique_lock<boost::shared_mutex> lockImageStatus(mutex_image_status);
            image_status = true;
        }
        frame_width = cam_image->image.size().width;
        frame_height = cam_image->image.size().height;
    }
    return;
}

// 用此函数查看是否收到图像话题
bool getImageStatus(void)
{
    boost::shared_lock<boost::shared_mutex> lock(mutex_image_status);
    return image_status;
}

void switchCallback(const std_msgs::Bool::ConstPtr& msg)
{
    is_suspanded = !(bool)msg->data;
    // cout << is_suspanded << endl;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "aruco_det");
    ros::NodeHandle nh("~");
    image_transport::ImageTransport it(nh);
    // 更新频率为30HZ
    ros::Rate loop_rate(30);
    //【发布】识别
    pose_pub = nh.advertise<prometheus_msgs::DetectionInfo>("/prometheus/object_detection/aruco_det", 1);

    // 发布调试消息
    msg_node_name = "/prometheus/message/aruco_det";
    message_pub = nh.advertise<prometheus_msgs::Message>(msg_node_name, 10);

    std::string camera_topic, camera_info;
    if (nh.getParam("camera_topic", camera_topic)) {
        if (local_print)
            ROS_INFO("camera_topic is %s", camera_topic.c_str());
        if (message_print)
            pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "camera_topic is" + camera_topic);
    } else {
        if (local_print)
            ROS_WARN("didn't find parameter camera_topic");
        if (message_print)
            pub_message(message_pub, prometheus_msgs::Message::WARN, msg_node_name, "didn't find parameter camera_topic");
        camera_topic = "/prometheus/camera/rgb/image_raw";
    }

    if (nh.getParam("camera_info", camera_info)) {
        if (local_print)
            ROS_INFO("camera_info is %s", camera_info.c_str());
        if (message_print)
            pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "camera_info is" + camera_info);
    } else {
        if (local_print)
            ROS_WARN("didn't find parameter camera_info");
        if (message_print)
            pub_message(message_pub, prometheus_msgs::Message::WARN, msg_node_name, "didn't find parameter camera_info");
        camera_info = "camera_param.yaml";
    }

    // 接收图像的话题
    image_subscriber = it.subscribe(camera_topic.c_str(), 1, cameraCallback);
    // 发布ArUco检测结果的话题
    aruco_pub = it.advertise("/prometheus/camera/rgb/image_aruco_det", 1);

    bool switch_state = is_suspanded;
    // 接收开关话题
    switch_subscriber = nh.subscribe("/prometheus/switch/aruco_det", 10, switchCallback);

    sensor_msgs::ImagePtr msg_ellipse;
    // 开启编号为0的摄像头
    // cv::VideoCapture cap(0);
	cv::Mat frame;

    cv::Mat camera_matrix;
    cv::Mat distortion_coefficients;

    std::string ros_path = ros::package::getPath("prometheus_detection");
    if (local_print)
        cout << "DETECTION_PATH: " << ros_path << endl;
    if (message_print)
        pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "DETECTION_PATH: " + ros_path);
    //读取参数文档camera_param.yaml中的参数值；
    YAML::Node camera_config = YAML::LoadFile(ros_path + "/config/" + camera_info);
    //相机内部参数
    double fx = camera_config["fx"].as<double>();
    double fy = camera_config["fy"].as<double>();
    double cx = camera_config["x0"].as<double>();
    double cy = camera_config["y0"].as<double>();
    //相机畸变系数
    double k1 = camera_config["k1"].as<double>();
    double k2 = camera_config["k2"].as<double>();
    double p1 = camera_config["p1"].as<double>();
    double p2 = camera_config["p2"].as<double>();
    double k3 = camera_config["k3"].as<double>();

    double aruco_det_len = camera_config["aruco_det_len"].as<double>();

    //相机内参
    camera_matrix = cv::Mat(3,3,CV_64FC1,cv::Scalar::all(0));
    camera_matrix.ptr<double>(0)[0]=fx;
    camera_matrix.ptr<double>(0)[2]=cx;
    camera_matrix.ptr<double>(1)[1]=fy;
    camera_matrix.ptr<double>(1)[2]=cy;
    camera_matrix.ptr<double>(2)[2]=1.0f;

    //相机畸变参数
    distortion_coefficients=cv::Mat(5,1,CV_64FC1,cv::Scalar::all(0));
    distortion_coefficients.ptr<double>(0)[0]=k1;
    distortion_coefficients.ptr<double>(1)[0]=k2;
    distortion_coefficients.ptr<double>(2)[0]=p1;
    distortion_coefficients.ptr<double>(3)[0]=p2;
    distortion_coefficients.ptr<double>(4)[0]=k3;

    //ArUco Marker字典选择
    Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
    vector<double> rv(3),tv(3);
    cv::Mat rvec(rv),tvec(tv);
    const auto wait_duration = std::chrono::milliseconds(2000);

    // 生成Aruco码
    // 保存在Prometheus/Modules/object_detection/config/aruco_images文件夹中
    /*******************************************************************************************
    cv::Mat markerImage;
    cv::Mat markerImagePad = cv::Mat::ones(500, 500,  CV_8UC1) * 255;
    for (int i=0; i<250; i++)
    {
        cv::aruco::drawMarker(dictionary, i, 400, markerImage, 1);
        markerImage.copyTo(markerImagePad.rowRange(50, 450).colRange(50, 450));
        cv::imshow("markerImagePad", markerImagePad);
        cv::waitKey(100);
        char img_fn[256];
        sprintf(img_fn, "Prometheus/Modules/object_detection/config/aruco_images/DICT_6X6_250_%d.png", i);
        cv::imwrite(img_fn, markerImagePad);
    }
    *******************************************************************************************/

    while (ros::ok())
	{
        while (!getImageStatus() && ros::ok())
        {
            if (local_print)
                cout << "Waiting for image." << endl;
            if (message_print)
                pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "Waiting for image.");
            std::this_thread::sleep_for(wait_duration);
            ros::spinOnce();
        }

        if (switch_state != is_suspanded)
        {
            switch_state = is_suspanded;
            if (!is_suspanded)
            {
                if (local_print)
                    cout << "Start Detection." << endl;
                if (message_print)
                    pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "Start Detection.");
            }
            else
            {
                if (local_print)
                    cout << "Stop Detection." << endl;
                if (message_print)
                    pub_message(message_pub, prometheus_msgs::Message::NORMAL, msg_node_name, "Stop Detection.");
            }
        }

        if (!is_suspanded)
        {

        {
            boost::unique_lock<boost::shared_mutex> lockImageCallback(mutex_image_callback);
            frame = cam_image_copy.clone();
        }

        if (!frame.empty())
        {
            std::vector<int> markerids;
            vector<vector<Point2f> > markerCorners,rejectedCandidate;
            Ptr<cv::aruco::DetectorParameters> parameters=cv::aruco::DetectorParameters::create();
            cv::aruco::detectMarkers(frame,dictionary,markerCorners,markerids,parameters,rejectedCandidate);

            bool deted = false;
            if (markerids.size()>0)
            {
                cv::Mat RoteM, TransM;
                cv::Point3f Theta_C2W;
                cv::Point3f Theta_W2C;
                cv::Point3f Position_OcInW;

                cv::aruco::estimatePoseSingleMarkers(markerCorners,aruco_det_len,camera_matrix,distortion_coefficients,rvec,tvec);

                prometheus_msgs::DetectionInfo pose_now;
                pose_now.header.stamp = ros::Time::now();
                pose_now.detected = true;
                pose_now.frame = 0;
                pose_now.position[0] = tvec.ptr<double>(0)[0];
                pose_now.position[1] = tvec.ptr<double>(0)[1];
                pose_now.position[2] = tvec.ptr<double>(0)[2];

                static_real_x = tvec.ptr<double>(0)[0];
                static_real_y = tvec.ptr<double>(0)[1];
                static_depth  = tvec.ptr<double>(0)[2];

                if (local_print) {
                    cout << "flag_detected: " << int(pose_now.detected) <<endl;
                    cout << "pos_target: [X Y Z] : " << " " << pose_now.position[0] << " [m] "<< pose_now.position[1] <<" [m] "<< pose_now.position[2] <<" [m] "<<endl;
                }
                pose_pub.publish(pose_now);
                deted=true;
            }
            if (!deted)
            {
                prometheus_msgs::DetectionInfo pose_now;
                pose_now.header.stamp = ros::Time::now();
                pose_now.detected = false;
                pose_now.frame = 0;
                pose_now.position[0] = static_real_x;
                pose_now.position[1] = static_real_y;
                pose_now.position[2] = static_depth;

                pose_pub.publish(pose_now);

                if (local_print) {
                    cout << "flag_detected: " << int(pose_now.detected) <<endl;
                    cout << "pos_target: [X Y Z] : " << " " << pose_now.position[0] << " [m] "<< pose_now.position[1] <<" [m] "<< pose_now.position[2] <<" [m] "<<endl;
                }
            }

            Mat img_copy;
            frame.copyTo(img_copy);
            cv::aruco::drawDetectedMarkers(img_copy,markerCorners,markerids);
            msg_ellipse = cv_bridge::CvImage(std_msgs::Header(), "bgr8", img_copy).toImageMsg();
            aruco_pub.publish(msg_ellipse);
            cv::waitKey(1);

		}
        }

        ros::spinOnce();
        loop_rate.sleep();
    }

	  // cap.release();

}

ext: cpp

max_issues_repo_name: JcZou/Prometheus

max_forks_repo_name: JcZou/Prometheus


text:
#include "ApplicationEnvironment.hpp"
#include <windows.h>
#include <omp.h>
#include "foundation/OutOfMemoryException.hpp"
#include "foundation/ApplicationErrorException.hpp"
#include <string>
#include <boost/algorithm/string.hpp>

#define AXIS_FORCE_GPU    "AXIS_FORCE_GPU"
#define AXIS_FORCE_CPU    "AXIS_FORCE_CPU"

class axis::ApplicationEnvironment::Pimpl
{
public:
  bool ForceGPU;
  bool ForceCPU;

  Pimpl(void)
  {
    ForceCPU = false;
    ForceCPU = false;
  }
};

namespace {
  typedef struct
  {
    long PhysicalProcessorCount;
    long LogicalProcessorCount;
    long ProcessorCoreCount;
  } ProcessorStatistics;

  void ResolveBooleanValue(bool& targetVariable, const char *value, bool defaultValue = false)
  {
    if (value == nullptr)
    {
      targetVariable = defaultValue;
      return;
    }
    std::string s = value;
    boost::trim(s);
    boost::to_lower(s);
	if (s.length() > 1)
	{
		if (s[0] == '\"' && s[s.length() - 1] == '\"')
		{
			s = s.substr(1, s.length() - 2);
		}
	}

    if (s == "yes" || s == "true" || s == "1")
    {
      targetVariable = true;
    }
    else if (s == "no" || s == "false" || s == "0")
    {
      targetVariable = false;
    }
    else
    { // undefined value
      targetVariable = defaultValue;
    }
  }

  // Helper function to count set bits in the processor mask.
  // Extracted from MSDN GetLogicalProcessorInformation article.
  DWORD CountSetBits(ULONG_PTR bitMask)
  {
    DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
    DWORD bitSetCount = 0;
    ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
    DWORD i;

    for (i = 0; i <= LSHIFT; ++i)
    {
      bitSetCount += ((bitMask & bitTest)?1:0);
      bitTest/=2;
    }

    return bitSetCount;
  }

  // Helper function that gets logical processors information
  // from Windows API
  DWORD GetProcessorsInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION *buffer)
  {
    *buffer = NULL;
    DWORD returnLength = 0;
    long cpuCount = 0;
    bool done = false;

    while (!done)
    {
      DWORD rc = GetLogicalProcessorInformation(*buffer, &returnLength);

      if (FALSE == rc)
      {	// at first try, should fail and return required buffer size
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {	// what we were expecting; allocate buffer
          if (*buffer) free(*buffer);
          *buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(returnLength);
          if (NULL == buffer)
          {	// could not allocate enough memory
            throw axis::foundation::OutOfMemoryException();
          }
        }
        else
        {	// huh, another error was triggered; this is bad...
          throw axis::foundation::ApplicationErrorException(
            _T("Could not retrieve local logical processor information. Error code = 0x") +
            axis::String::int_to_hex(rc));
        }
      }
      else
      {	// ok, processor information retrieved
        done = true;
      }
    }

    return returnLength;
  }

  // Compiles processor information into a single statistics structure.
  ProcessorStatistics GetProcessorStatistics(void)
  {
    ProcessorStatistics statistics = {0};
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
    DWORD returnLength = 0;
    int cpuCount = 0;

    // get information using helper function
    returnLength = GetProcessorsInformation(&buffer);

    // count how many processor records we have
    int recordCount = returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
    for (int i = 0; i < recordCount; ++i)
    {
      // note: if in the future new relationships values are added,
      // this method might not count processors correctly
      if (ptr->Relationship == RelationProcessorCore)
      {
        // hyperthread cores supply more than one logical processor per
        // core
        statistics.LogicalProcessorCount += CountSetBits(ptr->ProcessorMask);

        // count a physical core
        statistics.ProcessorCoreCount++;
      }
      if (ptr->Relationship == RelationProcessorPackage)
      {
        // count a processor package
        statistics.PhysicalProcessorCount++;
      }

      // advance to next record
      ++ptr;
    }

    // free resources
    free(buffer);

    return statistics;
  }
}

axis::ApplicationEnvironment::ApplicationEnvironment( void )
{
  pimpl_ = new Pimpl();
}

axis::ApplicationEnvironment::~ApplicationEnvironment( void )
{
  delete pimpl_;
}

bool axis::ApplicationEnvironment::ForceGPU( void ) const
{
  return pimpl_->ForceGPU;
}

bool axis::ApplicationEnvironment::ForceCPU( void ) const
{
  return pimpl_->ForceCPU;
}

void axis::ApplicationEnvironment::RefreshFromSystem( void )
{
  const char *val = getenv(AXIS_FORCE_CPU);
  ResolveBooleanValue(pimpl_->ForceCPU, val, false);
  val = getenv(AXIS_FORCE_GPU);
  ResolveBooleanValue(pimpl_->ForceGPU, val, false);
}

int axis::ApplicationEnvironment::GetLocalLogicalProcessorCount( void )
{
  return GetProcessorStatistics().LogicalProcessorCount;
}

int axis::ApplicationEnvironment::GetLocalProcessorCoreCount( void )
{
  return GetProcessorStatistics().ProcessorCoreCount;
}

int axis::ApplicationEnvironment::GetLocalProcessorPackageCount( void )
{
  return GetProcessorStatistics().PhysicalProcessorCount;
}

int axis::ApplicationEnvironment::GetLocalLogicalProcessorAvailableCount( void )
{
  // OpenMP is the one who restricts processors available for use
  return omp_get_num_procs();
}

int axis::ApplicationEnvironment::GetMaxLocalWorkerThreads( void )
{
  return omp_get_max_threads();
}

void axis::ApplicationEnvironment::SetMaxLocalWorkerThread( int threadCount )
{
  omp_set_num_threads(threadCount);
}

max_stars_repo_name: renato-yuzup/axis-fem

max_issues_repo_name: renato-yuzup/axis-fem

max_forks_repo_name: renato-yuzup/axis-fem


text:
//
// Licensed to Green Energy Corp (www.greenenergycorp.com) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Green Enery Corp licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
#include <boost/test/unit_test.hpp>
#include <APLTestTools/TestHelpers.h>

#include <APL/Util.h>
#include <APLTestTools/BufferHelpers.h>

using namespace std;
using namespace apl;

BOOST_AUTO_TEST_SUITE(UtilSuite)
template <int N>
void TestHex(const std::string& aHex, boost::uint8_t* aCompareBytes, size_t aCount)
{
	HexSequence hs(aHex);

	BOOST_REQUIRE(hs.Size() <= N);

	BOOST_REQUIRE_EQUAL(hs.Size(), aCount );
	for ( size_t i = 0; i < aCount; i++ )
		BOOST_REQUIRE_EQUAL(hs[i], aCompareBytes[i]);
}

BOOST_AUTO_TEST_CASE(HexToBytes2TestSmall)
{
	boost::uint8_t values[] = { 0xAF, 0x23 };
	TestHex<2>( "AF23", values, 2 );
}
BOOST_AUTO_TEST_CASE(HexToBytes2Test64)
{
	boost::uint8_t values[] = { 0x13, 0xA2, 0x00, 0x40, 0x56, 0x1D, 0x08 };
	TestHex<7>( "13A20040561D08", values, 7 );
}

BOOST_AUTO_TEST_CASE(HexToBytes2Test64TooBig)
{
	boost::uint8_t values[] = { 0x13, 0xA2, 0x00, 0x40, 0x56, 0x1D, 0x08 };
	TestHex<8>( "13A20040561D08", values, 7 );
}

BOOST_AUTO_TEST_CASE(HexToBytes2Test64Hole)
{
	boost::uint8_t values[] = { 0x13, 0xA2, 0x00, 0x40, 0x56, 0x1D, 0x08 };
	TestHex<8>( "13A200 40561   D08", values, 7 );
}

BOOST_AUTO_TEST_SUITE_END()


text:
/****************************************************************************
**
** Copyright (C) 2018 TU Wien, ACIN, Vision 4 Robotics (V4R) group
** Contact: v4r.acin.tuwien.ac.at
**
** This file is part of V4R
**
** V4R is distributed under dual licenses - GPLv3 or closed source.
**
** GNU General Public License Usage
** V4R is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** V4R is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** Please review the following information to ensure the GNU General Public
** License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
**
** Commercial License Usage
** If GPL is not suitable for your project, you must purchase a commercial
** license to use V4R. Licensees holding valid commercial V4R licenses may
** use this file in accordance with the commercial license agreement
** provided with the Software or, alternatively, in accordance with the
** terms contained in a written agreement between you and TU Wien, ACIN, V4R.
** For licensing terms and conditions please contact office<at>acin.tuwien.ac.at.
**
**
** The copyright holder additionally grants the author(s) of the file the right
** to use, copy, modify, merge, publish, distribute, sublicense, and/or
** sell copies of their contributions without any restrictions.
**
****************************************************************************/

#include <iostream>

#include <glog/logging.h>

#include <boost/filesystem.hpp>
#include <boost/format.hpp>

#include <pcl/io/obj_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <v4r/io/eigen.h>
#include <v4r/io/pcd_grabber.h>
#include <v4r/surface/mvs_texturing.h>

#include "program_options.h"

struct ProgramOptions : public ProgramOptionsBase {
  std::string model_path = "";
  std::string views_path = "";
  std::string output_path = "textured_mesh";
  v4r::surface::MVSTexturing::Parameters mvs_params;
  bool visualize = false;

  void printDescription() override {
    std::cout << "Texture a mesh using a set of camera images with known poses." << std::endl;
    std::cout << std::endl;
    std::cout << "Output path for the model should have no extension. Three files will be created:" << std::endl;
    std::cout << "  <output-path>.obj - with mesh and texture coordinates " << std::endl;
    std::cout << "  <output-path>.mtl - with materials" << std::endl;
    std::cout << "  <output-path>_material.png - with texture atlas" << std::endl;
  }

  void addGeneral(po::options_description& desc) override {
    desc.add_options()("visualize,v", po::bool_switch(&visualize), "Visualize textured model");
  }

  void addOther(std::vector<po::options_description>& descs) override {
    descs.push_back(po::options_description("MVS Texturing"));
    mvs_params.init(descs.back());
  }

  void addPositional(po::options_description& desc, po::positional_options_description& positional) override {
    desc.add_options()("model-path", po::value<std::string>(&model_path), "Path to model PLY file");
    desc.add_options()("views-path", po::value<std::string>(&views_path), "Path to views directory");
    desc.add_options()("output-path", po::value<std::string>(&output_path),
                       "Path to output textured model (without extension)");
    positional.add("model-path", 1);
    positional.add("views-path", 1);
    positional.add("output-path", 1);
  }
};

int main(int argc, const char** argv) {
  ProgramOptions options;
  if (!options.parse(argc, argv))
    return 1;

  pcl::PolygonMesh mesh;
  std::vector<cv::Mat> images;
  v4r::surface::MVSTexturing::PoseVector poses;

  LOG(INFO) << "Loading mesh from file: " << options.model_path;
  pcl::io::loadPolygonFile(options.model_path, mesh);

  LOG(INFO) << "Loading camera images: " << options.views_path;
  v4r::io::PCDGrabber grabber(options.views_path);
  while (grabber.hasMoreFrames()) {
    cv::Mat color, depth;
    auto timestamp = grabber.grabFrame(color, depth);
    LOG(INFO) << "  timestamp: " << timestamp << " size: " << color.size().width << " x " << color.size().height;
    boost::filesystem::path p = options.views_path;
    p /= boost::str(boost::format("pose_%08d.txt") % timestamp);
    Eigen::Matrix4f pose = v4r::io::readMatrixFromFile(p.string()).inverse();
    images.push_back(color);
    poses.push_back(pose);
  }

  v4r::surface::MVSTexturing tex;
  tex.mapTextureToMesh(mesh, grabber.getCameraIntrinsics(), images, poses, options.output_path);

  if (options.visualize) {
    // We have to use both loaders and merge the results to work around this PCL issue:
    // https://github.com/PointCloudLibrary/pcl/issues/2252
    pcl::TextureMesh textured_mesh;
    pcl::io::loadPolygonFileOBJ(options.output_path + ".obj", textured_mesh);
    pcl::TextureMesh mesh2;
    pcl::io::loadOBJFile(options.output_path + ".obj", mesh2);
    textured_mesh.tex_materials = mesh2.tex_materials;

    pcl::visualization::PCLVisualizer visualizer;
    visualizer.addTextureMesh(textured_mesh);
    visualizer.spin();
  }

  return 0;
}


text:
/**
 * Copyright (c) 2019 Melown Technologies SE
 *
 * 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.
 *
 * 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 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.
 */

#ifndef pysupport_vector_hpp_included_
#define pysupport_vector_hpp_included_

#include <vector>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

namespace pysupport {

namespace detail {

template <typename Vector>
typename Vector::value_type& append(Vector &v)
{
    v.emplace_back();
    return v.back();
}

} // namespace

template <typename Vector
          , typename Policy = boost::python::return_internal_reference<>>
boost::python::class_<Vector> vector(const char *name)
{
    namespace bp = boost::python;
    return bp::class_<Vector>(name)
        .def(bp::vector_indexing_suite<Vector>())
        .def("append"
             , bp::make_function(&detail::append<Vector>, Policy()))
        ;
}

} // namespace pysupport

#endif // pysupport_array_hpp_included_

max_stars_repo_name: Melown/libpysupport

max_issues_repo_name: Melown/libpysupport

max_forks_repo_name: Melown/libpysupport


text:
/* Simple program for solving the two-dimensional diffusion
   equation or Poisson equation using Jacobi's iterative method
   Note that this program does not contain a loop over the time
   dependence. It uses OpenMP to parallelize the spatial part.
*/

#include <iostream>
#include <iomanip>
#include <armadillo>
#include <omp.h>
using namespace std;
using namespace arma;

int JacobiSolver(int, double, double, mat &, mat &, double);

int main(int argc, char * argv[]){
  int Npoints = 100;
  double ExactSolution;
  double dx = 1.0/(Npoints-1);
  double dt = 0.25*dx*dx;
  double tolerance = 1.0e-8;
  mat A = zeros<mat>(Npoints,Npoints);
  mat q = zeros<mat>(Npoints,Npoints);

  int thread_num;
  omp_set_num_threads(4);
  thread_num = omp_get_max_threads ();
  cout << "  The number of processors available = " << omp_get_num_procs () << endl ;
  cout << "  The number of threads available    = " << thread_num <<  endl;
  // setting up an additional source term
  for(int i = 0; i < Npoints; i++)
    for(int j = 0; j < Npoints; j++)
      q(i,j) = -2.0*M_PI*M_PI*sin(M_PI*dx*i)*sin(M_PI*dx*j);

  int itcount = JacobiSolver(Npoints,dx,dt,A,q,tolerance);

  // Testing against exact solution
  double sum = 0.0;
  for(int i = 0; i < Npoints; i++){
    for(int j=0;j < Npoints; j++){
      ExactSolution = -sin(M_PI*dx*i)*sin(M_PI*dx*j);
      sum += fabs((A(i,j) - ExactSolution));
    }
  }
  cout << setprecision(5) << setiosflags(ios::scientific);
  cout << "Jacobi error is " << sum/Npoints << " in " << itcount << " iterations" << endl;
}

// Function for setting up the iterative Jacobi solver
int JacobiSolver(int N, double dx, double dt, mat &A, mat &q, double abstol)
{
  int MaxIterations = 100000;

  double D = dt/(dx*dx);
  // initial guess
  mat Aold = randu<mat>(N,N);
  // Boundary conditions, all zeros
  for(int i=0; i < N; i++){
    A(0,i) = 0.0;
    A(N-1,i) = 0.0;
    A(i,0) = 0.0;
    A(i,N-1) = 0.0;
  }
  double sum = 1.0;
  int k = 0;
  // Start the iterative solver
  while (k < MaxIterations && sum > abstol){
  int i, j;
  sum = 0.0;
  // Define parallel region
# pragma omp parallel default(shared) private (i, j) reduction(+:sum)
  {
     # pragma omp for
    for(i = 1; i < N-1; i++){
      for(j = 1; j < N-1; j++){
	A(i,j) = dt*q(i,j) + Aold(i,j) +
	  D*(Aold(i+1,j) + Aold(i,j+1) - 4.0*Aold(i,j) +
	     Aold(i-1,j) + Aold(i,j-1));
      }
    }
    for(i = 0; i < N;i++){
      for(j = 0; j < N;j++){
	sum += fabs(Aold(i,j)-A(i,j));
	Aold(i,j) = A(i,j);
      }
    }
    sum /= (N*N);
  } //end parallel region
  k++;
  } //end while loop
  return k;
}

max_stars_repo_name: kimrojas/ComputationalPhysicsMSU


text:
#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<float, Eigen::Dynamic, 6> test_float_D_6(const Eigen::Matrix<float, Eigen::Dynamic, 6> & M)
{
	return M;
}
void export_float_D_6()
{
	boost::python::def("test_float_D_6",test_float_D_6);
}

max_stars_repo_name: PushyamiKaveti/kalibr

max_issues_repo_name: PushyamiKaveti/kalibr

max_forks_repo_name: PushyamiKaveti/kalibr


text:
// generate by pypp
// original source code: /opt/boost/1.65.1/boost/compute/kernel.hpp

#include <boost/compute/kernel.hpp>

#include <boost/python.hpp>

void init_boost_compute_kernel_hpp() {
    boost::python::class_<boost::compute::kernel, std::shared_ptr<boost::compute::kernel>>("kernel")
        //.def(boost::python::init<cl_kernel, boost::python::optional<bool>>())
        .def(boost::python::init<const boost::compute::program &, const std::string &>())
        //.def("operator=", static_cast<boost::compute::kernel &(boost::compute::kernel::*)(const boost::compute::kernel &)>(&boost::compute::kernel::operator=), boost::python::return_value_policy<boost::python::copy_non_const_reference>())
        //.def("operator=", static_cast<boost::compute::kernel &(boost::compute::kernel::*)(boost::compute::kernel &&)>(&boost::compute::kernel::operator=), boost::python::return_value_policy<boost::python::copy_non_const_reference>())
        //.def("get", &boost::compute::kernel::get, boost::python::return_value_policy<boost::python::copy_non_const_reference>())
        .def("name", &boost::compute::kernel::name)
        .def("arity", &boost::compute::kernel::arity)
        .def("get_program", &boost::compute::kernel::get_program)
        .def("get_context", &boost::compute::kernel::get_context)
        //.def("set_arg", static_cast<void(boost::compute::kernel::*)(int, int, const void *)>(&boost::compute::kernel::set_arg))
        //.def("set_arg", static_cast<void(boost::compute::kernel::*)(int, _cl_mem *const)>(&boost::compute::kernel::set_arg))
        //.def("set_arg", static_cast<void(boost::compute::kernel::*)(int, _cl_sampler *const)>(&boost::compute::kernel::set_arg))
        .def("set_arg_svm_ptr", &boost::compute::kernel::set_arg_svm_ptr)
        //.def("operator==", &boost::compute::kernel::operator==)
        //.def("operator!=", &boost::compute::kernel::operator!=)
        .def("create_with_source", &boost::compute::kernel::create_with_source)
        .staticmethod("create_with_source")
        ;
}

max_stars_repo_name: mugwort-rc/python-compute

max_issues_repo_name: mugwort-rc/python-compute

max_forks_repo_name: mugwort-rc/python-compute


text:
// Copyright (c) 2020, ETH Zurich
// 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.
//
//     * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
//       its contributors may 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 HOLDERS 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.
//
// Author: Pascal Sommer (pasommer-at-student-dot-ethz-dot-ch)

#define TEST_NAME "base/gravity_relative_pose"
#include "util/testing.h"

#include <Eigen/Geometry>

#include "base/gravity_relative_pose.h"
#include "base/projection.h"
#include "util/random.h"

using namespace colmap;
using namespace Eigen;

BOOST_AUTO_TEST_CASE(TestEstimateRelativePoseGravity) {
  SetPRNGSeed(0);

  const std::size_t kNumPoints = 100;

  std::vector<Eigen::Vector3d> points3D;
  for (std::size_t i = 0; i < kNumPoints; ++i) {
    points3D.emplace_back(RandomReal<double>(0, 1),
                          RandomReal<double>(-1, 1),
                          RandomReal<double>(0.5, 5));
  }

  std::array<Pose, 2> poses_orig;
  poses_orig[0].tvec = Vector3d::Zero();
  poses_orig[0].qvec = Vector4d(0.981445, 0.104679, -0.15143, 0.053634);
  poses_orig[1].tvec = Vector3d(-4, -0.5, 5).normalized();
  poses_orig[1].qvec = Vector4d(0.960427, -0.101919, 0.258302, -0.021735);

  std::array<Image, 2> images;
  std::array<Camera, 2> cameras;
  std::array<std::vector<Vector2d>, 2> projected;
  std::array<Matrix3x4d, 2> projection_matrix;
  for (auto i : {0, 1}) {
    images[i].SetGravityPrior(
        QuaternionRotatePoint(poses_orig[i].qvec, Vector3d::UnitY()));

    cameras[i].SetCameraId(i);
    cameras[i].InitializeWithName("PINHOLE", 1, 1, 1);

    projection_matrix[i] =
        ComposeProjectionMatrix(poses_orig[i].qvec, poses_orig[i].tvec);

    projected[i].reserve(kNumPoints);
  }

  FeatureMatches matches;
  matches.reserve(kNumPoints);

  for (std::size_t point_id = 0; point_id < kNumPoints; ++point_id) {
    matches.emplace_back(point_id, point_id);

    for (auto i : {0, 1}) {
      const Vector2d projected_normalized =
          (projection_matrix[i] * points3D[point_id].homogeneous())
              .hnormalized();
      projected[i].push_back(cameras[i].WorldToImage(projected_normalized));
    }
  }

  for (auto i : {0, 1}) {
    images[i].SetPoints2D(projected[i]);
  }

  RANSACOptions ransac_options;
  ransac_options.min_num_trials = 10;
  ransac_options.max_num_trials = 50;
  ransac_options.max_error = 1e-5;

  std::array<Pose, 2> poses_est;

  const auto report = EstimateRelativePoseGravity(images, cameras, matches,
                                                  ransac_options, &poses_est,
                                                  nullptr);
  const unsigned nr_inliers = report.support.num_inliers;

  BOOST_CHECK_EQUAL(poses_est[0].tvec, Vector3d::Zero());
  BOOST_CHECK_CLOSE(poses_est[0].qvec.norm(), 1., 1e-9);
  BOOST_CHECK_CLOSE(poses_est[1].tvec.norm(), 1., 1e-9);
  BOOST_CHECK_CLOSE(poses_est[1].qvec.norm(), 1., 1e-9);
  BOOST_CHECK_EQUAL(nr_inliers, kNumPoints);

  BOOST_CHECK_SMALL((poses_est[1].tvec - poses_orig[1].tvec).norm(), 1e-9);

  const Vector4d relative_rot_est = ConcatenateQuaternions(
      InvertQuaternion(poses_est[1].qvec), poses_est[0].qvec);
  const Vector4d relative_rot_orig = ConcatenateQuaternions(
      InvertQuaternion(poses_orig[1].qvec), poses_orig[0].qvec);

  BOOST_CHECK_SMALL((relative_rot_est - relative_rot_orig).norm(), 1e-9);
}

max_stars_repo_name: Pascal-So/colmap

max_issues_repo_name: Pascal-So/colmap

max_forks_repo_name: Pascal-So/colmap


text:
//  Copyright (c) 2007-2020 Hartmut Kaiser
//
//  SPDX-License-Identifier: BSL-1.0
//  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)

#include <pika/assert.hpp>
#include <pika/modules/errors.hpp>
#include <pika/runtime_local/custom_exception_info.hpp>
#include <pika/runtime_local/detail/serialize_exception.hpp>
#include <pika/serialization/serialize.hpp>

#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/exception.hpp>
#endif

#include <cstddef>
#include <cstdint>
#include <exception>
#include <stdexcept>
#include <string>
#include <system_error>
#include <typeinfo>

///////////////////////////////////////////////////////////////////////////////
namespace pika { namespace runtime_local { namespace detail {
    ///////////////////////////////////////////////////////////////////////////
    // TODO: This is not scalable, and painful to update.
    void save_custom_exception(pika::serialization::output_archive& ar,
        std::exception_ptr const& ep, unsigned int /* version */)
    {
        pika::util::exception_type type(pika::util::unknown_exception);
        std::string what;
        int err_value = pika::success;
        std::string err_message;

        std::uint32_t throw_locality_ = 0;
        std::string throw_hostname_;
        std::int64_t throw_pid_ = -1;
        std::size_t throw_shepherd_ = 0;
        std::size_t throw_thread_id_ = 0;
        std::string throw_thread_name_;
        std::string throw_function_;
        std::string throw_file_;
        std::string throw_back_trace_;
        long throw_line_ = 0;
        std::string throw_env_;
        std::string throw_config_;
        std::string throw_state_;
        std::string throw_auxinfo_;

        // retrieve information related to exception_info
        try
        {
            std::rethrow_exception(ep);
        }
        catch (exception_info const& xi)
        {
            std::string const* function =
                xi.get<pika::detail::throw_function>();
            if (function)
                throw_function_ = *function;

            std::string const* file = xi.get<pika::detail::throw_file>();
            if (file)
                throw_file_ = *file;

            long const* line = xi.get<pika::detail::throw_line>();
            if (line)
                throw_line_ = *line;

            std::uint32_t const* locality =
                xi.get<pika::detail::throw_locality>();
            if (locality)
                throw_locality_ = *locality;

            std::string const* hostname_ =
                xi.get<pika::detail::throw_hostname>();
            if (hostname_)
                throw_hostname_ = *hostname_;

            std::int64_t const* pid_ = xi.get<pika::detail::throw_pid>();
            if (pid_)
                throw_pid_ = *pid_;

            std::size_t const* shepherd =
                xi.get<pika::detail::throw_shepherd>();
            if (shepherd)
                throw_shepherd_ = *shepherd;

            std::size_t const* thread_id =
                xi.get<pika::detail::throw_thread_id>();
            if (thread_id)
                throw_thread_id_ = *thread_id;

            std::string const* thread_name =
                xi.get<pika::detail::throw_thread_name>();
            if (thread_name)
                throw_thread_name_ = *thread_name;

            std::string const* back_trace =
                xi.get<pika::detail::throw_stacktrace>();
            if (back_trace)
                throw_back_trace_ = *back_trace;

            std::string const* env_ = xi.get<pika::detail::throw_env>();
            if (env_)
                throw_env_ = *env_;

            std::string const* config_ = xi.get<pika::detail::throw_config>();
            if (config_)
                throw_config_ = *config_;

            std::string const* state_ = xi.get<pika::detail::throw_state>();
            if (state_)
                throw_state_ = *state_;

            std::string const* auxinfo_ = xi.get<pika::detail::throw_auxinfo>();
            if (auxinfo_)
                throw_auxinfo_ = *auxinfo_;
        }
        catch (...)
        {
            // do nothing
        }

        // figure out concrete underlying exception type
        try
        {
            std::rethrow_exception(ep);
        }
        catch (pika::thread_interrupted const&)
        {
            type = pika::util::pika_thread_interrupted_exception;
            what = "pika::thread_interrupted";
            err_value = pika::thread_cancelled;
        }
        catch (pika::exception const& e)
        {
            type = pika::util::pika_exception;
            what = e.what();
            err_value = e.get_error();
        }
        catch (std::system_error const& e)
        {
            type = pika::util::std_system_error;
            what = e.what();
            err_value = e.code().value();
            err_message = e.code().message();
        }
        catch (std::runtime_error const& e)
        {
            type = pika::util::std_runtime_error;
            what = e.what();
        }
        catch (std::invalid_argument const& e)
        {
            type = pika::util::std_invalid_argument;
            what = e.what();
        }
        catch (std::out_of_range const& e)
        {
            type = pika::util::std_out_of_range;
            what = e.what();
        }
        catch (std::logic_error const& e)
        {
            type = pika::util::std_logic_error;
            what = e.what();
        }
        catch (std::bad_alloc const& e)
        {
            type = pika::util::std_bad_alloc;
            what = e.what();
        }
        catch (std::bad_cast const& e)
        {
            type = pika::util::std_bad_cast;
            what = e.what();
        }
        catch (std::bad_typeid const& e)
        {
            type = pika::util::std_bad_typeid;
            what = e.what();
        }
        catch (std::bad_exception const& e)
        {
            type = pika::util::std_bad_exception;
            what = e.what();
        }
        catch (std::exception const& e)
        {
            type = pika::util::std_exception;
            what = e.what();
        }
#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
        catch (boost::exception const& e)
        {
            type = pika::util::boost_exception;
            what = boost::diagnostic_information(e);
        }
#endif
        catch (...)
        {
            type = pika::util::unknown_exception;
            what = "unknown exception";
        }

        // clang-format off
        ar & type & what & throw_function_ & throw_file_ & throw_line_ &
            throw_locality_ & throw_hostname_ & throw_pid_ & throw_shepherd_ &
            throw_thread_id_ & throw_thread_name_ & throw_back_trace_ &
            throw_env_ & throw_config_ & throw_state_ & throw_auxinfo_;
        // clang-format on

        if (pika::util::pika_exception == type)
        {
            // clang-format off
            ar & err_value;
            // clang-format on
        }
        else if (pika::util::std_system_error == type)
        {
            // clang-format off
            ar & err_value & err_message;
            // clang-format on
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // TODO: This is not scalable, and painful to update.
    void load_custom_exception(pika::serialization::input_archive& ar,
        std::exception_ptr& e, unsigned int)
    {
        pika::util::exception_type type(pika::util::unknown_exception);
        std::string what;
        int err_value = pika::success;
        std::string err_message;

        std::uint32_t throw_locality_ = 0;
        std::string throw_hostname_;
        std::int64_t throw_pid_ = -1;
        std::size_t throw_shepherd_ = 0;
        std::size_t throw_thread_id_ = 0;
        std::string throw_thread_name_;
        std::string throw_function_;
        std::string throw_file_;
        std::string throw_back_trace_;
        int throw_line_ = 0;
        std::string throw_env_;
        std::string throw_config_;
        std::string throw_state_;
        std::string throw_auxinfo_;

        // clang-format off
        ar & type & what & throw_function_ & throw_file_ & throw_line_ &
            throw_locality_ & throw_hostname_ & throw_pid_ & throw_shepherd_ &
            throw_thread_id_ & throw_thread_name_ & throw_back_trace_ &
            throw_env_ & throw_config_ & throw_state_ & throw_auxinfo_;
        // clang-format on

        if (pika::util::pika_exception == type)
        {
            // clang-format off
            ar & err_value;
            // clang-format on
        }
        else if (pika::util::std_system_error == type)
        {
            // clang-format off
            ar & err_value & err_message;
            // clang-format on
        }

        switch (type)
        {
        default:
        case pika::util::std_exception:
        case pika::util::unknown_exception:
            e = pika::detail::construct_exception(
                pika::detail::std_exception(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        // standard exceptions
        case pika::util::std_runtime_error:
            e = pika::detail::construct_exception(std::runtime_error(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_invalid_argument:
            e = pika::detail::construct_exception(std::invalid_argument(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_out_of_range:
            e = pika::detail::construct_exception(std::out_of_range(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_logic_error:
            e = pika::detail::construct_exception(std::logic_error(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_bad_alloc:
            e = pika::detail::construct_exception(pika::detail::bad_alloc(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_bad_cast:
            e = pika::detail::construct_exception(pika::detail::bad_cast(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        case pika::util::std_bad_typeid:
            e = pika::detail::construct_exception(
                pika::detail::bad_typeid(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;
        case pika::util::std_bad_exception:
            e = pika::detail::construct_exception(
                pika::detail::bad_exception(what),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
        // boost exceptions
        case pika::util::boost_exception:
            PIKA_ASSERT(false);    // shouldn't happen
            break;
#endif

        // boost::system::system_error
        case pika::util::boost_system_error:
            PIKA_FALLTHROUGH;

        // std::system_error
        case pika::util::std_system_error:
            e = pika::detail::construct_exception(
                std::system_error(
                    err_value, std::system_category(), err_message),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        // pika::exception
        case pika::util::pika_exception:
            e = pika::detail::construct_exception(
                pika::exception(
                    static_cast<pika::error>(err_value), what, pika::rethrow),
                pika::detail::construct_exception_info(throw_function_,
                    throw_file_, throw_line_, throw_back_trace_,
                    throw_locality_, throw_hostname_, throw_pid_,
                    throw_shepherd_, throw_thread_id_, throw_thread_name_,
                    throw_env_, throw_config_, throw_state_, throw_auxinfo_));
            break;

        // pika::thread_interrupted
        case pika::util::pika_thread_interrupted_exception:
            e = pika::detail::construct_lightweight_exception(
                pika::thread_interrupted());
            break;
        }
    }
}}}    // namespace pika::runtime_local::detail

max_stars_repo_name: msimberg/pika

max_issues_repo_name: msimberg/pika

max_forks_repo_name: msimberg/pika


text:
// copyright (c) 2011-2013 the dzcoin core developers
// distributed under the mit software license, see the accompanying
// file copying or http://www.opensource.org/licenses/mit-license.php.
#include "arith_uint256.h"
#include "uint256.h"
#include "version.h"
#include "test/test_dzcoin.h"

#include <boost/test/unit_test.hpp>
#include <stdint.h>
#include <sstream>
#include <iomanip>
#include <limits>
#include <cmath>
#include <string>
#include <stdio.h>

boost_fixture_test_suite(uint256_tests, basictestingsetup)

const unsigned char r1array[] =
    "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
    "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
const char r1arrayhex[] = "7d1de5eaf9b156d53208f033b5aa8122d2d2355d5e12292b121156cfdb4a529c";
const uint256 r1l = uint256(std::vector<unsigned char>(r1array,r1array+32));
const uint160 r1s = uint160(std::vector<unsigned char>(r1array,r1array+20));

const unsigned char r2array[] =
    "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
    "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
const uint256 r2l = uint256(std::vector<unsigned char>(r2array,r2array+32));
const uint160 r2s = uint160(std::vector<unsigned char>(r2array,r2array+20));

const unsigned char zeroarray[] =
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 zerol = uint256(std::vector<unsigned char>(zeroarray,zeroarray+32));
const uint160 zeros = uint160(std::vector<unsigned char>(zeroarray,zeroarray+20));

const unsigned char onearray[] =
    "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 onel = uint256(std::vector<unsigned char>(onearray,onearray+32));
const uint160 ones = uint160(std::vector<unsigned char>(onearray,onearray+20));

const unsigned char maxarray[] =
    "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
    "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
const uint256 maxl = uint256(std::vector<unsigned char>(maxarray,maxarray+32));
const uint160 maxs = uint160(std::vector<unsigned char>(maxarray,maxarray+20));

std::string arraytostring(const unsigned char a[], unsigned int width)
{
    std::stringstream stream;
    stream << std::hex;
    for (unsigned int i = 0; i < width; ++i)
    {
        stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)a[width-i-1];
    }
    return stream.str();
}

inline uint160 uint160s(const char *str)
{
    uint160 rv;
    rv.sethex(str);
    return rv;
}
inline uint160 uint160s(const std::string& str)
{
    uint160 rv;
    rv.sethex(str);
    return rv;
}

boost_auto_test_case( basics ) // constructors, equality, inequality
{
    boost_check(1 == 0+1);
    // constructor uint256(vector<char>):
    boost_check(r1l.tostring() == arraytostring(r1array,32));
    boost_check(r1s.tostring() == arraytostring(r1array,20));
    boost_check(r2l.tostring() == arraytostring(r2array,32));
    boost_check(r2s.tostring() == arraytostring(r2array,20));
    boost_check(zerol.tostring() == arraytostring(zeroarray,32));
    boost_check(zeros.tostring() == arraytostring(zeroarray,20));
    boost_check(onel.tostring() == arraytostring(onearray,32));
    boost_check(ones.tostring() == arraytostring(onearray,20));
    boost_check(maxl.tostring() == arraytostring(maxarray,32));
    boost_check(maxs.tostring() == arraytostring(maxarray,20));
    boost_check(onel.tostring() != arraytostring(zeroarray,32));
    boost_check(ones.tostring() != arraytostring(zeroarray,20));

    // == and !=
    boost_check(r1l != r2l && r1s != r2s);
    boost_check(zerol != onel && zeros != ones);
    boost_check(onel != zerol && ones != zeros);
    boost_check(maxl != zerol && maxs != zeros);

    // string constructor and copy constructor
    boost_check(uint256s("0x"+r1l.tostring()) == r1l);
    boost_check(uint256s("0x"+r2l.tostring()) == r2l);
    boost_check(uint256s("0x"+zerol.tostring()) == zerol);
    boost_check(uint256s("0x"+onel.tostring()) == onel);
    boost_check(uint256s("0x"+maxl.tostring()) == maxl);
    boost_check(uint256s(r1l.tostring()) == r1l);
    boost_check(uint256s("   0x"+r1l.tostring()+"   ") == r1l);
    boost_check(uint256s("") == zerol);
    boost_check(r1l == uint256s(r1arrayhex));
    boost_check(uint256(r1l) == r1l);
    boost_check(uint256(zerol) == zerol);
    boost_check(uint256(onel) == onel);

    boost_check(uint160s("0x"+r1s.tostring()) == r1s);
    boost_check(uint160s("0x"+r2s.tostring()) == r2s);
    boost_check(uint160s("0x"+zeros.tostring()) == zeros);
    boost_check(uint160s("0x"+ones.tostring()) == ones);
    boost_check(uint160s("0x"+maxs.tostring()) == maxs);
    boost_check(uint160s(r1s.tostring()) == r1s);
    boost_check(uint160s("   0x"+r1s.tostring()+"   ") == r1s);
    boost_check(uint160s("") == zeros);
    boost_check(r1s == uint160s(r1arrayhex));

    boost_check(uint160(r1s) == r1s);
    boost_check(uint160(zeros) == zeros);
    boost_check(uint160(ones) == ones);
}

boost_auto_test_case( comparison ) // <= >= < >
{
    uint256 lastl;
    for (int i = 255; i >= 0; --i) {
        uint256 tmpl;
        *(tmpl.begin() + (i>>3)) |= 1<<(7-(i&7));
        boost_check( lastl < tmpl );
        lastl = tmpl;
    }

    boost_check( zerol < r1l );
    boost_check( r2l < r1l );
    boost_check( zerol < onel );
    boost_check( onel < maxl );
    boost_check( r1l < maxl );
    boost_check( r2l < maxl );

    uint160 lasts;
    for (int i = 159; i >= 0; --i) {
        uint160 tmps;
        *(tmps.begin() + (i>>3)) |= 1<<(7-(i&7));
        boost_check( lasts < tmps );
        lasts = tmps;
    }
    boost_check( zeros < r1s );
    boost_check( r2s < r1s );
    boost_check( zeros < ones );
    boost_check( ones < maxs );
    boost_check( r1s < maxs );
    boost_check( r2s < maxs );
}

boost_auto_test_case( methods ) // gethex sethex begin() end() size() getlow64 getserializesize, serialize, unserialize
{
    boost_check(r1l.gethex() == r1l.tostring());
    boost_check(r2l.gethex() == r2l.tostring());
    boost_check(onel.gethex() == onel.tostring());
    boost_check(maxl.gethex() == maxl.tostring());
    uint256 tmpl(r1l);
    boost_check(tmpl == r1l);
    tmpl.sethex(r2l.tostring());   boost_check(tmpl == r2l);
    tmpl.sethex(zerol.tostring()); boost_check(tmpl == uint256());

    tmpl.sethex(r1l.tostring());
    boost_check(memcmp(r1l.begin(), r1array, 32)==0);
    boost_check(memcmp(tmpl.begin(), r1array, 32)==0);
    boost_check(memcmp(r2l.begin(), r2array, 32)==0);
    boost_check(memcmp(zerol.begin(), zeroarray, 32)==0);
    boost_check(memcmp(onel.begin(), onearray, 32)==0);
    boost_check(r1l.size() == sizeof(r1l));
    boost_check(sizeof(r1l) == 32);
    boost_check(r1l.size() == 32);
    boost_check(r2l.size() == 32);
    boost_check(zerol.size() == 32);
    boost_check(maxl.size() == 32);
    boost_check(r1l.begin() + 32 == r1l.end());
    boost_check(r2l.begin() + 32 == r2l.end());
    boost_check(onel.begin() + 32 == onel.end());
    boost_check(maxl.begin() + 32 == maxl.end());
    boost_check(tmpl.begin() + 32 == tmpl.end());
    boost_check(r1l.getserializesize(0,protocol_version) == 32);
    boost_check(zerol.getserializesize(0,protocol_version) == 32);

    std::stringstream ss;
    r1l.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(r1array,r1array+32));
    tmpl.unserialize(ss,0,protocol_version);
    boost_check(r1l == tmpl);
    ss.str("");
    zerol.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(zeroarray,zeroarray+32));
    tmpl.unserialize(ss,0,protocol_version);
    boost_check(zerol == tmpl);
    ss.str("");
    maxl.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(maxarray,maxarray+32));
    tmpl.unserialize(ss,0,protocol_version);
    boost_check(maxl == tmpl);
    ss.str("");

    boost_check(r1s.gethex() == r1s.tostring());
    boost_check(r2s.gethex() == r2s.tostring());
    boost_check(ones.gethex() == ones.tostring());
    boost_check(maxs.gethex() == maxs.tostring());
    uint160 tmps(r1s);
    boost_check(tmps == r1s);
    tmps.sethex(r2s.tostring());   boost_check(tmps == r2s);
    tmps.sethex(zeros.tostring()); boost_check(tmps == uint160());

    tmps.sethex(r1s.tostring());
    boost_check(memcmp(r1s.begin(), r1array, 20)==0);
    boost_check(memcmp(tmps.begin(), r1array, 20)==0);
    boost_check(memcmp(r2s.begin(), r2array, 20)==0);
    boost_check(memcmp(zeros.begin(), zeroarray, 20)==0);
    boost_check(memcmp(ones.begin(), onearray, 20)==0);
    boost_check(r1s.size() == sizeof(r1s));
    boost_check(sizeof(r1s) == 20);
    boost_check(r1s.size() == 20);
    boost_check(r2s.size() == 20);
    boost_check(zeros.size() == 20);
    boost_check(maxs.size() == 20);
    boost_check(r1s.begin() + 20 == r1s.end());
    boost_check(r2s.begin() + 20 == r2s.end());
    boost_check(ones.begin() + 20 == ones.end());
    boost_check(maxs.begin() + 20 == maxs.end());
    boost_check(tmps.begin() + 20 == tmps.end());
    boost_check(r1s.getserializesize(0,protocol_version) == 20);
    boost_check(zeros.getserializesize(0,protocol_version) == 20);

    r1s.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(r1array,r1array+20));
    tmps.unserialize(ss,0,protocol_version);
    boost_check(r1s == tmps);
    ss.str("");
    zeros.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(zeroarray,zeroarray+20));
    tmps.unserialize(ss,0,protocol_version);
    boost_check(zeros == tmps);
    ss.str("");
    maxs.serialize(ss,0,protocol_version);
    boost_check(ss.str() == std::string(maxarray,maxarray+20));
    tmps.unserialize(ss,0,protocol_version);
    boost_check(maxs == tmps);
    ss.str("");
}

boost_auto_test_case( conversion )
{
    boost_check(arithtouint256(uinttoarith256(zerol)) == zerol);
    boost_check(arithtouint256(uinttoarith256(onel)) == onel);
    boost_check(arithtouint256(uinttoarith256(r1l)) == r1l);
    boost_check(arithtouint256(uinttoarith256(r2l)) == r2l);
    boost_check(uinttoarith256(zerol) == 0);
    boost_check(uinttoarith256(onel) == 1);
    boost_check(arithtouint256(0) == zerol);
    boost_check(arithtouint256(1) == onel);
    boost_check(arith_uint256(r1l.gethex()) == uinttoarith256(r1l));
    boost_check(arith_uint256(r2l.gethex()) == uinttoarith256(r2l));
    boost_check(r1l.gethex() == uinttoarith256(r1l).gethex());
    boost_check(r2l.gethex() == uinttoarith256(r2l).gethex());
}

boost_auto_test_suite_end()

max_stars_repo_name: dzcoin/DzCoinMiningAlgorithm

max_issues_repo_name: dzcoin/DzCoinMiningAlgorithm

max_forks_repo_name: dzcoin/DzCoinMiningAlgorithm