<commit_before>/*

This file is part of VROOM.

Copyright (c) 2015-2022, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include "problems/cvrp/operators/reverse_two_opt.h"

namespace vroom {
namespace cvrp {

ReverseTwoOpt::ReverseTwoOpt(const Input& input,
                             const utils::SolutionState& sol_state,
                             RawRoute& s_route,
                             Index s_vehicle,
                             Index s_rank,
                             RawRoute& t_route,
                             Index t_vehicle,
                             Index t_rank)
  : Operator(OperatorName::ReverseTwoOpt,
             input,
             sol_state,
             s_route,
             s_vehicle,
             s_rank,
             t_route,
             t_vehicle,
             t_rank) {
  assert(s_vehicle != t_vehicle);
  assert(s_route.size() >= 1);
  assert(t_route.size() >= 1);
  assert(s_rank < s_route.size());
  assert(t_rank < t_route.size());

  assert(_sol_state.bwd_skill_rank[s_vehicle][t_vehicle] <= s_rank + 1);
  assert(t_rank < _sol_state.fwd_skill_rank[t_vehicle][s_vehicle]);
}

void ReverseTwoOpt::compute_gain() {
  const auto& s_v = _input.vehicles[s_vehicle];
  const auto& t_v = _input.vehicles[t_vehicle];

  Index s_index = _input.jobs[s_route[s_rank]].index();
  Index t_index = _input.jobs[t_route[t_rank]].index();
  Index last_s = _input.jobs[s_route.back()].index();
  Index first_t = _input.jobs[t_route.front()].index();
  stored_gain = Eval();
  bool last_in_source = (s_rank == s_route.size() - 1);
  bool last_in_target = (t_rank == t_route.size() - 1);

  // Cost of swapping route for vehicle s_vehicle after step
  // s_rank with route for vehicle t_vehicle up to step
  // t_rank, but reversed.

  // Add new source -> target edge.
  stored_gain -= s_v.eval(s_index, t_index);

  // Cost of reversing target route portion. First remove forward cost
  // for beginning of target route as seen from target vehicle. Then
  // add backward cost for beginning of target route as seen from
  // source vehicle since it's the new source route end.
  stored_gain += _sol_state.fwd_costs[t_vehicle][t_vehicle][t_rank];
  stored_gain -= _sol_state.bwd_costs[t_vehicle][s_vehicle][t_rank];

  if (!last_in_target) {
    // Spare next edge in target route.
    Index next_index = _input.jobs[t_route[t_rank + 1]].index();
    stored_gain += t_v.eval(t_index, next_index);
  }

  if (!last_in_source) {
    // Spare next edge in source route.
    Index next_index = _input.jobs[s_route[s_rank + 1]].index();
    stored_gain += s_v.eval(s_index, next_index);

    // Part of source route is moved to target route.
    Index next_s_index = _input.jobs[s_route[s_rank + 1]].index();

    // Cost or reverting source route portion. First remove forward
    // cost for end of source route as seen from source vehicle
    // (subtracting intermediate cost to overall cost). Then add
    // backward cost for end of source route as seen from target
    // vehicle since it's the new target route start.
    stored_gain += _sol_state.fwd_costs[s_vehicle][s_vehicle].back();
    stored_gain -= _sol_state.fwd_costs[s_vehicle][s_vehicle][s_rank + 1];
    stored_gain -= _sol_state.bwd_costs[s_vehicle][t_vehicle].back();
    stored_gain += _sol_state.bwd_costs[s_vehicle][t_vehicle][s_rank + 1];

    if (last_in_target) {
      if (t_v.has_end()) {
        // Handle target route new end.
        auto end_t = t_v.end.value().index();
        stored_gain += t_v.eval(t_index, end_t);
        stored_gain -= t_v.eval(next_s_index, end_t);
      }
    } else {
      // Add new target -> source edge.
      Index next_t_index = _input.jobs[t_route[t_rank + 1]].index();
      stored_gain -= t_v.eval(next_s_index, next_t_index);
    }
  }

  if (s_v.has_end()) {
    // Update cost to source end because last job changed.
    auto end_s = s_v.end.value().index();
    stored_gain += s_v.eval(last_s, end_s);
    stored_gain -= s_v.eval(first_t, end_s);
  }

  if (t_v.has_start()) {
    // Spare cost from target start because first job changed.
    auto start_t = t_v.start.value().index();
    stored_gain += t_v.eval(start_t, first_t);
    if (!last_in_source) {
      stored_gain -= t_v.eval(start_t, last_s);
    } else {
      // No job from source route actually swapped to target route.
      if (!last_in_target) {
        // Going straight from start to next job in target route.
        Index next_index = _input.jobs[t_route[t_rank + 1]].index();
        stored_gain -= t_v.eval(start_t, next_index);
      } else {
        // Emptying the whole target route here, so also gaining cost
        // to end if it exists.
        if (t_v.has_end()) {
          auto end_t = t_v.end.value().index();
          stored_gain += t_v.eval(t_index, end_t);
        }
      }
    }
  }

  gain_computed = true;
}

bool ReverseTwoOpt::is_valid() {
  const auto& t_delivery = target.fwd_deliveries(t_rank);
  const auto& t_pickup = target.fwd_pickups(t_rank);

  bool valid = source.is_valid_addition_for_capacity_margins(_input,
                                                             t_pickup,
                                                             t_delivery,
                                                             s_rank + 1,
                                                             s_route.size());

  const auto& s_delivery = source.bwd_deliveries(s_rank);
  const auto& s_pickup = source.bwd_pickups(s_rank);

  valid = valid && target.is_valid_addition_for_capacity_margins(_input,
                                                                 s_pickup,
                                                                 s_delivery,
                                                                 0,
                                                                 t_rank + 1);

  valid =
    valid && source.is_valid_addition_for_capacity_inclusion(_input,
                                                             t_delivery,
                                                             t_route.rbegin() +
                                                               t_route.size() -
                                                               1 - t_rank,
                                                             t_route.rend(),
                                                             s_rank + 1,
                                                             s_route.size());

  valid =
    valid && target.is_valid_addition_for_capacity_inclusion(_input,
                                                             s_delivery,
                                                             s_route.rbegin(),
                                                             s_route.rbegin() +
                                                               s_route.size() -
                                                               1 - s_rank,
                                                             0,
                                                             t_rank + 1);

  return valid;
}

void ReverseTwoOpt::apply() {
  auto nb_source = s_route.size() - 1 - s_rank;

  t_route.insert(t_route.begin(),
                 s_route.rbegin(),
                 s_route.rbegin() + nb_source);
  s_route.erase(s_route.begin() + s_rank + 1, s_route.end());
  s_route.insert(s_route.end(),
                 t_route.rend() - t_rank - nb_source - 1,
                 t_route.rend() - nb_source);
  t_route.erase(t_route.begin() + nb_source,
                t_route.begin() + nb_source + t_rank + 1);

  source.update_amounts(_input);
  target.update_amounts(_input);
}

std::vector<Index> ReverseTwoOpt::addition_candidates() const {
  return {s_vehicle, t_vehicle};
}

std::vector<Index> ReverseTwoOpt::update_candidates() const {
  return {s_vehicle, t_vehicle};
}

} // namespace cvrp
} // namespace vroom
<commit_msg>Split source and target gain in ReverseTwoOpt::compute_gain.<commit_after>/*

This file is part of VROOM.

Copyright (c) 2015-2022, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include "problems/cvrp/operators/reverse_two_opt.h"

namespace vroom {
namespace cvrp {

ReverseTwoOpt::ReverseTwoOpt(const Input& input,
                             const utils::SolutionState& sol_state,
                             RawRoute& s_route,
                             Index s_vehicle,
                             Index s_rank,
                             RawRoute& t_route,
                             Index t_vehicle,
                             Index t_rank)
  : Operator(OperatorName::ReverseTwoOpt,
             input,
             sol_state,
             s_route,
             s_vehicle,
             s_rank,
             t_route,
             t_vehicle,
             t_rank) {
  assert(s_vehicle != t_vehicle);
  assert(s_route.size() >= 1);
  assert(t_route.size() >= 1);
  assert(s_rank < s_route.size());
  assert(t_rank < t_route.size());

  assert(_sol_state.bwd_skill_rank[s_vehicle][t_vehicle] <= s_rank + 1);
  assert(t_rank < _sol_state.fwd_skill_rank[t_vehicle][s_vehicle]);
}

void ReverseTwoOpt::compute_gain() {
  const auto& s_v = _input.vehicles[s_vehicle];
  const auto& t_v = _input.vehicles[t_vehicle];

  Index s_index = _input.jobs[s_route[s_rank]].index();
  Index t_index = _input.jobs[t_route[t_rank]].index();
  Index last_s = _input.jobs[s_route.back()].index();
  Index first_t = _input.jobs[t_route.front()].index();

  bool last_in_source = (s_rank == s_route.size() - 1);
  bool last_in_target = (t_rank == t_route.size() - 1);

  // Cost of swapping route for vehicle s_vehicle after step
  // s_rank with route for vehicle t_vehicle up to step
  // t_rank, but reversed.

  // Add new source -> target edge.
  s_gain -= s_v.eval(s_index, t_index);

  // Cost of reversing target route portion. First remove forward cost
  // for beginning of target route as seen from target vehicle. Then
  // add backward cost for beginning of target route as seen from
  // source vehicle since it's the new source route end.
  t_gain += _sol_state.fwd_costs[t_vehicle][t_vehicle][t_rank];
  s_gain -= _sol_state.bwd_costs[t_vehicle][s_vehicle][t_rank];

  if (!last_in_target) {
    // Spare next edge in target route.
    Index next_index = _input.jobs[t_route[t_rank + 1]].index();
    t_gain += t_v.eval(t_index, next_index);
  }

  if (!last_in_source) {
    // Spare next edge in source route.
    Index next_index = _input.jobs[s_route[s_rank + 1]].index();
    s_gain += s_v.eval(s_index, next_index);

    // Part of source route is moved to target route.
    Index next_s_index = _input.jobs[s_route[s_rank + 1]].index();

    // Cost or reverting source route portion. First remove forward
    // cost for end of source route as seen from source vehicle
    // (subtracting intermediate cost to overall cost). Then add
    // backward cost for end of source route as seen from target
    // vehicle since it's the new target route start.
    s_gain += _sol_state.fwd_costs[s_vehicle][s_vehicle].back();
    s_gain -= _sol_state.fwd_costs[s_vehicle][s_vehicle][s_rank + 1];
    t_gain -= _sol_state.bwd_costs[s_vehicle][t_vehicle].back();
    t_gain += _sol_state.bwd_costs[s_vehicle][t_vehicle][s_rank + 1];

    if (last_in_target) {
      if (t_v.has_end()) {
        // Handle target route new end.
        auto end_t = t_v.end.value().index();
        t_gain += t_v.eval(t_index, end_t);
        t_gain -= t_v.eval(next_s_index, end_t);
      }
    } else {
      // Add new target -> source edge.
      Index next_t_index = _input.jobs[t_route[t_rank + 1]].index();
      t_gain -= t_v.eval(next_s_index, next_t_index);
    }
  }

  if (s_v.has_end()) {
    // Update cost to source end because last job changed.
    auto end_s = s_v.end.value().index();
    s_gain += s_v.eval(last_s, end_s);
    s_gain -= s_v.eval(first_t, end_s);
  }

  if (t_v.has_start()) {
    // Spare cost from target start because first job changed.
    auto start_t = t_v.start.value().index();
    t_gain += t_v.eval(start_t, first_t);
    if (!last_in_source) {
      t_gain -= t_v.eval(start_t, last_s);
    } else {
      // No job from source route actually swapped to target route.
      if (!last_in_target) {
        // Going straight from start to next job in target route.
        Index next_index = _input.jobs[t_route[t_rank + 1]].index();
        t_gain -= t_v.eval(start_t, next_index);
      } else {
        // Emptying the whole target route here, so also gaining cost
        // to end if it exists.
        if (t_v.has_end()) {
          auto end_t = t_v.end.value().index();
          t_gain += t_v.eval(t_index, end_t);
        }
      }
    }
  }

  stored_gain = s_gain + t_gain;
  gain_computed = true;
}

bool ReverseTwoOpt::is_valid() {
  const auto& t_delivery = target.fwd_deliveries(t_rank);
  const auto& t_pickup = target.fwd_pickups(t_rank);

  bool valid = source.is_valid_addition_for_capacity_margins(_input,
                                                             t_pickup,
                                                             t_delivery,
                                                             s_rank + 1,
                                                             s_route.size());

  const auto& s_delivery = source.bwd_deliveries(s_rank);
  const auto& s_pickup = source.bwd_pickups(s_rank);

  valid = valid && target.is_valid_addition_for_capacity_margins(_input,
                                                                 s_pickup,
                                                                 s_delivery,
                                                                 0,
                                                                 t_rank + 1);

  valid =
    valid && source.is_valid_addition_for_capacity_inclusion(_input,
                                                             t_delivery,
                                                             t_route.rbegin() +
                                                               t_route.size() -
                                                               1 - t_rank,
                                                             t_route.rend(),
                                                             s_rank + 1,
                                                             s_route.size());

  valid =
    valid && target.is_valid_addition_for_capacity_inclusion(_input,
                                                             s_delivery,
                                                             s_route.rbegin(),
                                                             s_route.rbegin() +
                                                               s_route.size() -
                                                               1 - s_rank,
                                                             0,
                                                             t_rank + 1);

  return valid;
}

void ReverseTwoOpt::apply() {
  auto nb_source = s_route.size() - 1 - s_rank;

  t_route.insert(t_route.begin(),
                 s_route.rbegin(),
                 s_route.rbegin() + nb_source);
  s_route.erase(s_route.begin() + s_rank + 1, s_route.end());
  s_route.insert(s_route.end(),
                 t_route.rend() - t_rank - nb_source - 1,
                 t_route.rend() - nb_source);
  t_route.erase(t_route.begin() + nb_source,
                t_route.begin() + nb_source + t_rank + 1);

  source.update_amounts(_input);
  target.update_amounts(_input);
}

std::vector<Index> ReverseTwoOpt::addition_candidates() const {
  return {s_vehicle, t_vehicle};
}

std::vector<Index> ReverseTwoOpt::update_candidates() const {
  return {s_vehicle, t_vehicle};
}

} // namespace cvrp
} // namespace vroom
<|endoftext|>


<commit_before>#include "backbuffer_output_pass.hpp"

#include "nova_renderer/nova_renderer.hpp"

namespace nova::renderer {
    struct RX_HINT_EMPTY_BASES BackbufferOutputRenderpassCreateInfo : shaderpack::RenderPassCreateInfo {
        BackbufferOutputRenderpassCreateInfo();
    };

    struct RX_HINT_EMPTY_BASES BackbufferOutputPipelineCreateInfo : shaderpack::PipelineCreateInfo {
        BackbufferOutputPipelineCreateInfo();
    };

    BackbufferOutputRenderpassCreateInfo::BackbufferOutputRenderpassCreateInfo() {
        name = BACKBUFFER_OUTPUT_RENDER_PASS_NAME;
        texture_inputs.emplace_back(UI_OUTPUT_RT_NAME);
        texture_inputs.emplace_back(SCENE_OUTPUT_RT_NAME);

        texture_outputs.emplace_back(BACKBUFFER_NAME, shaderpack::PixelFormatEnum::RGBA8, false);
    }

    BackbufferOutputPipelineCreateInfo::BackbufferOutputPipelineCreateInfo() {
        name = BACKBUFFER_OUTPUT_PIPELINE_NAME;
        pass = BACKBUFFER_OUTPUT_RENDER_PASS_NAME;

        const rx::string vertex_source {};

    }

    RX_GLOBAL<BackbufferOutputRenderpassCreateInfo> backbuffer_output_create_info{"Nova", "BackbufferOutputCreateInfo"};

    BackbufferOutputRenderpass::BackbufferOutputRenderpass(const NovaRenderer* nova) : Renderpass(BACKBUFFER_OUTPUT_RENDER_PASS_NAME, true) {
        auto& pipeline_storage = nova->get_pipeline_storage();
    }

    const shaderpack::RenderPassCreateInfo& BackbufferOutputRenderpass::get_create_info() { return *backbuffer_output_create_info; }
} // namespace nova::renderer
<commit_msg>[rendergraph] Create building vertex and pixel shaders for the backbuffer output render pass<commit_after>#include "backbuffer_output_pass.hpp"

#include "nova_renderer/nova_renderer.hpp"
#include "nova_renderer/loading/shaderpack_loading.hpp"

namespace nova::renderer {
    struct RX_HINT_EMPTY_BASES BackbufferOutputRenderpassCreateInfo : shaderpack::RenderPassCreateInfo {
        BackbufferOutputRenderpassCreateInfo();
    };

    struct RX_HINT_EMPTY_BASES BackbufferOutputPipelineCreateInfo : shaderpack::PipelineCreateInfo {
        BackbufferOutputPipelineCreateInfo();
    };

    BackbufferOutputRenderpassCreateInfo::BackbufferOutputRenderpassCreateInfo() {
        name = BACKBUFFER_OUTPUT_RENDER_PASS_NAME;
        texture_inputs.emplace_back(UI_OUTPUT_RT_NAME);
        texture_inputs.emplace_back(SCENE_OUTPUT_RT_NAME);

        texture_outputs.emplace_back(BACKBUFFER_NAME, shaderpack::PixelFormatEnum::RGBA8, false);
    }

    BackbufferOutputPipelineCreateInfo::BackbufferOutputPipelineCreateInfo() {
        name = BACKBUFFER_OUTPUT_PIPELINE_NAME;
        pass = BACKBUFFER_OUTPUT_RENDER_PASS_NAME;

        const rx::string vertex_source{R"(
            struct VsInput {
                float2 position : POSITION;
            };

            struct VsOutput {
                float4 position : SV_POSITION;
                float2 uv : TEXCOORD;

            };

            VsOutput main(VsInput input) {
                VsOutput output;
                output.position = float4(input.position, 0, 1);
                output.uv = input.position; // TODO: Figure out if I should flip the texture coordinates

                return output;
            })"};
        const auto& vertex_spirv = shaderpack::compile_shader(vertex_source, rhi::ShaderStage::Vertex, rhi::ShaderLanguage::Hlsl);
        vertex_shader = {"/nova/shaders/backbuffer_output.vertex.hlsl", vertex_spirv};

        const rx::string pixel_source{R"(
            [[vk::binding(0, 0)]]
            Texture2D ui_output : register(t0);

            [[vk::binding(1, 0)]]
            Texture2D scene_output : register(t1);

            [[vk::binding(2, 0)]]
            SamplerState sampler : register(s0);

            struct VsOutput {
                float4 position : SV_POSITION;
                float2 us : TEXCOORD;
            };

            float3 main(VsOutput input) : SV_Target {
                float4 ui_color = ui_output.Sample(sampler, input.uv);
                float4 scene_color = scene_output.Sample(sampler, input.uv);

                float3 combined_color = lerp(ui_color.rgb, scene_color.rgb, ui_color.a);

                return combined_color;
            })"};
        const auto& pixel_spirv = shaderpack::compile_shader(pixel_source, rhi::ShaderStage::Fragment, rhi::ShaderLanguage::Hlsl);
        fragment_shader = { "/nova/shaders/backbuffer_output.pixel.hlsl", pixel_spirv };
    }

    RX_GLOBAL<BackbufferOutputRenderpassCreateInfo> backbuffer_output_create_info{"Nova", "BackbufferOutputCreateInfo"};

    BackbufferOutputRenderpass::BackbufferOutputRenderpass(const NovaRenderer* nova)
        : Renderpass(BACKBUFFER_OUTPUT_RENDER_PASS_NAME, true) {
        auto& pipeline_storage = nova->get_pipeline_storage();
    }

    const shaderpack::RenderPassCreateInfo& BackbufferOutputRenderpass::get_create_info() { return *backbuffer_output_create_info; }
} // namespace nova::renderer
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include <QtDebug>

#include <iostream>
#include <fstream>
//#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <cerrno>
#include <cmath>
#include <thread>
#include <mutex>

#define OUTPUT_FILE "./trials.csv"
#define NUMBER_THREADS 1
#define USE_MULTIPLE_THREADS
// create a mutex that is used to protect the writing of the data to
// the file.
std::mutex writeToFile;

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SHOW_PROGRESS
//#define SHOW_INTERMEDIATE
//#define THREAD_DEBUG
#define BASE_DT 0.00001
#define RADIUS 0.06

#ifndef Q_OS_UNIX
double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}
#endif

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

void printToCSVFile(double dt, double beta, double g,double tau,
                    double q, double theta, double h,double s,
                    double *x,std::ofstream *fp)
{

    std::lock_guard<std::mutex> guard(writeToFile);  // Make sure that
                                                       // this routine
                                                       // can only
                                                       // access the file once
                                                       // at any one time.

    *fp << dt << ","
        << beta << ","
        << g << ","
        << tau << ","
        << q+1 << ","
        << theta << ","
        << h << ","
        << s << ","
        << 1-h-s << ","
        << x[0] << ","
        << x[1] << ","
        << 1-x[0]-x[1] << ","
        << x[2] << ","
        << x[3] << ","
        << 1-x[2]-x[3]
        << std::endl;

    (*fp).flush();
}

void linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              std::ofstream *fp,
              int q,
              double h,double s,double *v,double *w, double theta)
    {

        long m=n-1;
        long p=0;
        double B[2];
        int calcRandom=0;

#ifdef THREAD_DEBUG
        std::cout << "My thread id: " << std::this_thread::get_id() << std::endl;
#endif

        // Step through every time step.
        for (long k=0;k<steps;k++)
        {

            // Calculate a new set of random numbers if necessary.
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0] = y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0] += beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1] = z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2] =  v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2] += beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3] =  w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%n;
            p=(p+1)%n;
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.

        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        printToCSVFile(dt,beta,g,tau,q,theta,h,s,x,fp);

 #ifdef SHOW_INTERMEDIATE
        qDebug() << dt << ","
            << beta << ","
            << g << ","
            << tau << ","
            << q+1 << ","
            << h << ","
            << s << ","
            << 1-h-s << ","
            << x[0] << ","
            << x[1] << ","
            << 1-x[0]-x[1] << ","
            << x[2] << ","
            << x[3] << ","
            << 1-x[2]-x[3];
        qDebug() << errno << EDOM << ERANGE;
#endif

    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    ;//	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;

        double tau;
        double beta ;//	 = .5;
//        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
//        double gOne		 = (gamma*(a+d))/(a+r);
//        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
//        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
//        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
//        double coralSaddle		 = 1-cbar;						    //Saddle point value for coral
//        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);		//Saddle point value for macroalgae

//        long   numberDT;    // The current iteration for the number assocated with the value of dt.
//        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
//        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt        = BASE_DT;          // Set the initial time step
        double final;       // The final time for each simulation.
        long   trials;      // The number of simulations to make.

        final=50.0;  // Set the final time.
        trials=400;   // Set the number of trials to perform.

        // Set the time delay, tau
        //double tau = 0.5;

        // set up the variables for using different approximations on different threads.
        std::thread simulation[NUMBER_THREADS];
        int numberThreads = 0;

        // Sets the seed for the random numbers
#ifdef Q_OS_UNIX
        srand48(time(NULL));
        //qDebug() << "This is a POSIX system!" ;
#else
        srand(time(NULL));
#endif

        // Create a CSV File
        std::ofstream fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp.open(OUTPUT_FILE,std::ios::out | std::ios::trunc);

        fp << "dt,beta,g,tau,trial,theta,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf" << std::endl;

        for(tau = .2; tau <= .4; tau += .2 )
        {
           // Determine the number of time steps required to move back to the delay in time.
           // The number of cells needed for the delay (changes with dt)
            int n;
            if(tau > 0.0)
                n=(int)(tau/BASE_DT+0.5);
            else
                n = 1;
            // Allocate the space for the states of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise

            if((x==NULL) || (y==NULL) || (z==NULL) || (w==NULL))
            {
                std::cout << "Error - unable to allocate necessary memory." << std::endl;
                free(x);
                free(y);
                free(z);
                free(v);
                free(w);
                return b.exec();
            }

            for(g=.2; g<.8; g += .2) {
                //double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                // double tauZero	 = (1/omega)*acos(gZero/g);

                // Make different approximations for different values of beta.
                for(beta=.2;beta<=1.0; beta += .2) {

#ifdef SHOW_PROGRESS
                    std::cout << "dt = " << dt << std::endl;
#endif
                        //index = tau/dt;

                        //printf("%i\n",n);
                        steps=(long)(final/dt);

                        for (double theta=0;theta<=M_PI/2;theta+=(M_PI*0.5)*0.025)
                        {

                        // Make an approximation for different initial conditions.
                        // Make an arc through 0 to pi/2 radians from the origin.

                            for (int k=0;k<trials;k++)
                            {
                                y[0] = RADIUS*cos(theta); //initial Macroalgae level
                                z[0] = RADIUS*sin(theta); //initial Coral level
                                v[0] = RADIUS*cos(theta);
                                w[0] = RADIUS*sin(theta);
                                for (int l=1;l<n;l++) //fills in the past times for y, z, v, and w
                                {
                                    y[l]=y[0];
                                    z[l]=z[0];
                                    v[l]=v[0];
                                    w[l]=w[0];
                                }
                                //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
#ifdef USE_MULTIPLE_THREADS

                                // Make a simulation for each of the available threads.
                                // First check to see how many threads are running.
                                if(numberThreads >= NUMBER_THREADS)
                                {
                                    // There are too many threads. Wait for each run to end.
                                    while(numberThreads>0)
                                    {
#ifdef THREAD_DEBUG
                                        std::cout << "Waiting on thread "
                                                  << simulation[numberThreads-1].get_id()
                                                  << std::endl;
#endif
                                        simulation[--numberThreads].join();
                                    }
                                } // if(numberThreads)

                                // Make a run in a separate thread.
                                simulation[numberThreads++] = std::thread(linear,
                                                                          steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,y[0],z[0],v,w,theta);

#else

                                // Ignore the different threads. Just make one approximation in this one thread.
                                linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,y[0],z[0],v,w,theta);

#endif

#ifdef SHOW_PROGRESS
                                if(k%20 == 0)
                                    std::cout << "  Simulation number " << k << std::endl;
#endif

                            } // for(k<trials)
                        } // for(theta<pi/2
                   }
            }

            // Free up the allocated memory.
            free(x);
            free(y);
            free(z);
            free(v);
            free(w);

        }

        fp.close();

#ifdef SHOW_PROGRESS
        std::cout << "all done" << std::endl;
#endif

        return b.exec();
}
<commit_msg>Forgot to check for the v vector in the coral code<commit_after>#include <QCoreApplication>
#include <QtDebug>

#include <iostream>
#include <fstream>
//#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <cerrno>
#include <cmath>
#include <thread>
#include <mutex>

#define OUTPUT_FILE "./trials.csv"
#define NUMBER_THREADS 1
#define USE_MULTIPLE_THREADS
// create a mutex that is used to protect the writing of the data to
// the file.
std::mutex writeToFile;

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SHOW_PROGRESS
//#define SHOW_INTERMEDIATE
//#define THREAD_DEBUG
#define BASE_DT 0.00001
#define RADIUS 0.06

#ifndef Q_OS_UNIX
double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}
#endif

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

void printToCSVFile(double dt, double beta, double g,double tau,
                    double q, double theta, double h,double s,
                    double *x,std::ofstream *fp)
{

    std::lock_guard<std::mutex> guard(writeToFile);  // Make sure that
                                                       // this routine
                                                       // can only
                                                       // access the file once
                                                       // at any one time.

    *fp << dt << ","
        << beta << ","
        << g << ","
        << tau << ","
        << q+1 << ","
        << theta << ","
        << h << ","
        << s << ","
        << 1-h-s << ","
        << x[0] << ","
        << x[1] << ","
        << 1-x[0]-x[1] << ","
        << x[2] << ","
        << x[3] << ","
        << 1-x[2]-x[3]
        << std::endl;

    (*fp).flush();
}

void linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              std::ofstream *fp,
              int q,
              double h,double s,double *v,double *w, double theta)
    {

        long m=n-1;
        long p=0;
        double B[2];
        int calcRandom=0;

#ifdef THREAD_DEBUG
        std::cout << "My thread id: " << std::this_thread::get_id() << std::endl;
#endif

        // Step through every time step.
        for (long k=0;k<steps;k++)
        {

            // Calculate a new set of random numbers if necessary.
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0] = y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0] += beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1] = z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2] =  v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2] += beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3] =  w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%n;
            p=(p+1)%n;
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.

        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        printToCSVFile(dt,beta,g,tau,q,theta,h,s,x,fp);

 #ifdef SHOW_INTERMEDIATE
        qDebug() << dt << ","
            << beta << ","
            << g << ","
            << tau << ","
            << q+1 << ","
            << h << ","
            << s << ","
            << 1-h-s << ","
            << x[0] << ","
            << x[1] << ","
            << 1-x[0]-x[1] << ","
            << x[2] << ","
            << x[3] << ","
            << 1-x[2]-x[3];
        qDebug() << errno << EDOM << ERANGE;
#endif

    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    ;//	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;

        double tau;
        double beta ;//	 = .5;
//        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
//        double gOne		 = (gamma*(a+d))/(a+r);
//        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
//        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
//        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
//        double coralSaddle		 = 1-cbar;						    //Saddle point value for coral
//        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);		//Saddle point value for macroalgae

//        long   numberDT;    // The current iteration for the number assocated with the value of dt.
//        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
//        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt        = BASE_DT;          // Set the initial time step
        double final;       // The final time for each simulation.
        long   trials;      // The number of simulations to make.

        final=50.0;  // Set the final time.
        trials=400;   // Set the number of trials to perform.

        // Set the time delay, tau
        //double tau = 0.5;

        // set up the variables for using different approximations on different threads.
        std::thread simulation[NUMBER_THREADS];
        int numberThreads = 0;

        // Sets the seed for the random numbers
#ifdef Q_OS_UNIX
        srand48(time(NULL));
        //qDebug() << "This is a POSIX system!" ;
#else
        srand(time(NULL));
#endif

        // Create a CSV File
        std::ofstream fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp.open(OUTPUT_FILE,std::ios::out | std::ios::trunc);

        fp << "dt,beta,g,tau,trial,theta,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf" << std::endl;

        for(tau = .2; tau <= .4; tau += .2 )
        {
           // Determine the number of time steps required to move back to the delay in time.
           // The number of cells needed for the delay (changes with dt)
            int n;
            if(tau > 0.0)
                n=(int)(tau/BASE_DT+0.5);
            else
                n = 1;
            // Allocate the space for the states of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise

            if((x==NULL) || (y==NULL) || (z==NULL) || (v==NULL) || (w==NULL))
            {
                std::cout << "Error - unable to allocate necessary memory." << std::endl;
                free(x);
                free(y);
                free(z);
                free(v);
                free(w);
                return b.exec();
            }

            for(g=.2; g<.8; g += .2) {
                //double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                // double tauZero	 = (1/omega)*acos(gZero/g);

                // Make different approximations for different values of beta.
                for(beta=.2;beta<=1.0; beta += .2) {

#ifdef SHOW_PROGRESS
                    std::cout << "dt = " << dt << std::endl;
#endif
                        //index = tau/dt;

                        //printf("%i\n",n);
                        steps=(long)(final/dt);

                        for (double theta=0;theta<=M_PI/2;theta+=(M_PI*0.5)*0.025)
                        {

                        // Make an approximation for different initial conditions.
                        // Make an arc through 0 to pi/2 radians from the origin.

                            for (int k=0;k<trials;k++)
                            {
                                y[0] = RADIUS*cos(theta); //initial Macroalgae level
                                z[0] = RADIUS*sin(theta); //initial Coral level
                                v[0] = RADIUS*cos(theta);
                                w[0] = RADIUS*sin(theta);
                                for (int l=1;l<n;l++) //fills in the past times for y, z, v, and w
                                {
                                    y[l]=y[0];
                                    z[l]=z[0];
                                    v[l]=v[0];
                                    w[l]=w[0];
                                }
                                //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
#ifdef USE_MULTIPLE_THREADS

                                // Make a simulation for each of the available threads.
                                // First check to see how many threads are running.
                                if(numberThreads >= NUMBER_THREADS)
                                {
                                    // There are too many threads. Wait for each run to end.
                                    while(numberThreads>0)
                                    {
#ifdef THREAD_DEBUG
                                        std::cout << "Waiting on thread "
                                                  << simulation[numberThreads-1].get_id()
                                                  << std::endl;
#endif
                                        simulation[--numberThreads].join();
                                    }
                                } // if(numberThreads)

                                // Make a run in a separate thread.
                                simulation[numberThreads++] = std::thread(linear,
                                                                          steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,y[0],z[0],v,w,theta);

#else

                                // Ignore the different threads. Just make one approximation in this one thread.
                                linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,y[0],z[0],v,w,theta);

#endif

#ifdef SHOW_PROGRESS
                                if(k%20 == 0)
                                    std::cout << "  Simulation number " << k << std::endl;
#endif

                            } // for(k<trials)
                        } // for(theta<pi/2
                   }
            }

            // Free up the allocated memory.
            free(x);
            free(y);
            free(z);
            free(v);
            free(w);

        }

        fp.close();

#ifdef SHOW_PROGRESS
        std::cout << "all done" << std::endl;
#endif

        return b.exec();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2009, Willow Garage, Inc.
 * 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 the Willow Garage, Inc. 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 OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "shape_list_marker.h"
#include "marker_selection_handler.h"
#include "common.h"

#include "visualization_manager.h"
#include "selection/selection_manager.h"

#include <ogre_tools/shape.h>
#include <tf/transform_listener.h>

#include <OGRE/OgreSceneManager.h>
#include <OGRE/OgreSceneNode.h>
#include <OGRE/OgreMaterialManager.h>
#include <OGRE/OgreStaticGeometry.h>
#include <OGRE/OgreEntity.h>

namespace rviz
{

ShapeListMarker::ShapeListMarker(VisualizationManager* manager, Ogre::SceneNode* parent_node)
: MarkerBase(manager, parent_node)
, geometry_(0)
{
  static uint32_t count = 0;
  std::stringstream ss;
  ss << "ShapeListMarker" << count++;

  geometry_ = vis_manager_->getSceneManager()->createStaticGeometry(ss.str());

  ss << "Material";
  material_name_ = ss.str();
  material_ = Ogre::MaterialManager::getSingleton().create( material_name_, ROS_PACKAGE_NAME );
  material_->setReceiveShadows(false);
  material_->getTechnique(0)->setLightingEnabled(true);
  material_->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );

}

ShapeListMarker::~ShapeListMarker()
{
  vis_manager_->getSceneManager()->destroyStaticGeometry(geometry_);
}

void ShapeListMarker::onNewMessage(const MarkerPtr& old_message, const MarkerPtr& new_message)
{
  ROS_ASSERT(new_message->type == visualization_msgs::Marker::CUBE_LIST
          || new_message->type == visualization_msgs::Marker::SPHERE_LIST);

  if (!old_message)
  {
    SelectionManager* sel_manager = vis_manager_->getSelectionManager();
    coll_ = sel_manager->createHandle();
    sel_manager->addPickTechnique(coll_, material_);
    sel_manager->addObject(coll_, SelectionHandlerPtr(new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id))));
  }

  float r = new_message->color.r;
  float g = new_message->color.g;
  float b = new_message->color.b;
  float a = new_message->color.a;
  material_->getTechnique(0)->setAmbient( r*0.5, g*0.5, b*0.5 );
  material_->getTechnique(0)->setDiffuse( r, g, b, a );

  if ( a < 0.9998 )
  {
    material_->getTechnique(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
    material_->getTechnique(0)->setDepthWriteEnabled( false );
  }
  else
  {
    material_->getTechnique(0)->setSceneBlending( Ogre::SBT_REPLACE );
    material_->getTechnique(0)->setDepthWriteEnabled( true );
  }

  Ogre::Vector3 pos, scale;
  Ogre::Quaternion orient;
  transform(new_message, pos, orient, scale);

  Ogre::SceneManager* scene_manager = vis_manager_->getSceneManager();
  Ogre::Entity* entity = 0;
  switch (new_message->type)
  {
  case visualization_msgs::Marker::CUBE_LIST:
    entity = scene_manager->createEntity("ShapeListMarker Temp", "ogre_tools_cube.mesh");
    break;
  case visualization_msgs::Marker::SPHERE_LIST:
    entity = scene_manager->createEntity("ShapeListMarker Temp", "ogre_tools_sphere.mesh");
    break;
  default:
    ROS_BREAK();
  }

  entity->setMaterialName(material_name_);
  geometry_->reset();

  tf::TransformListener* tf_client = vis_manager_->getTFClient();
  std::string fixed_frame = vis_manager_->getFixedFrame();

  tf::Stamped<btTransform> transform;
  tf_client->lookupTransform (fixed_frame, new_message->header.frame_id, new_message->header.stamp, transform);

  std::vector<robot_msgs::Point>::iterator it = new_message->points.begin();
  std::vector<robot_msgs::Point>::iterator end = new_message->points.end();
  for ( ; it != end; ++it )
  {
    robot_msgs::Point& p = *it;

    Ogre::Vector3 point(p.x, p.y, p.z);
    robotToOgre(point);

    point = pos + (orient * point);

    geometry_->addEntity(entity, point, orient, scale);
  }

  geometry_->build();

  scene_manager->destroyEntity(entity);
}

}
<commit_msg>try/catch around lookupTransform<commit_after>/*
 * Copyright (c) 2009, Willow Garage, Inc.
 * 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 the Willow Garage, Inc. 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 OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "shape_list_marker.h"
#include "marker_selection_handler.h"
#include "common.h"

#include "visualization_manager.h"
#include "selection/selection_manager.h"

#include <ogre_tools/shape.h>
#include <tf/transform_listener.h>

#include <OGRE/OgreSceneManager.h>
#include <OGRE/OgreSceneNode.h>
#include <OGRE/OgreMaterialManager.h>
#include <OGRE/OgreStaticGeometry.h>
#include <OGRE/OgreEntity.h>

namespace rviz
{

ShapeListMarker::ShapeListMarker(VisualizationManager* manager, Ogre::SceneNode* parent_node)
: MarkerBase(manager, parent_node)
, geometry_(0)
{
  static uint32_t count = 0;
  std::stringstream ss;
  ss << "ShapeListMarker" << count++;

  geometry_ = vis_manager_->getSceneManager()->createStaticGeometry(ss.str());

  ss << "Material";
  material_name_ = ss.str();
  material_ = Ogre::MaterialManager::getSingleton().create( material_name_, ROS_PACKAGE_NAME );
  material_->setReceiveShadows(false);
  material_->getTechnique(0)->setLightingEnabled(true);
  material_->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );

}

ShapeListMarker::~ShapeListMarker()
{
  vis_manager_->getSceneManager()->destroyStaticGeometry(geometry_);
}

void ShapeListMarker::onNewMessage(const MarkerPtr& old_message, const MarkerPtr& new_message)
{
  ROS_ASSERT(new_message->type == visualization_msgs::Marker::CUBE_LIST
          || new_message->type == visualization_msgs::Marker::SPHERE_LIST);

  if (!old_message)
  {
    SelectionManager* sel_manager = vis_manager_->getSelectionManager();
    coll_ = sel_manager->createHandle();
    sel_manager->addPickTechnique(coll_, material_);
    sel_manager->addObject(coll_, SelectionHandlerPtr(new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id))));
  }

  float r = new_message->color.r;
  float g = new_message->color.g;
  float b = new_message->color.b;
  float a = new_message->color.a;
  material_->getTechnique(0)->setAmbient( r*0.5, g*0.5, b*0.5 );
  material_->getTechnique(0)->setDiffuse( r, g, b, a );

  if ( a < 0.9998 )
  {
    material_->getTechnique(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
    material_->getTechnique(0)->setDepthWriteEnabled( false );
  }
  else
  {
    material_->getTechnique(0)->setSceneBlending( Ogre::SBT_REPLACE );
    material_->getTechnique(0)->setDepthWriteEnabled( true );
  }

  Ogre::Vector3 pos, scale;
  Ogre::Quaternion orient;
  transform(new_message, pos, orient, scale);

  Ogre::SceneManager* scene_manager = vis_manager_->getSceneManager();
  Ogre::Entity* entity = 0;
  switch (new_message->type)
  {
  case visualization_msgs::Marker::CUBE_LIST:
    entity = scene_manager->createEntity("ShapeListMarker Temp", "ogre_tools_cube.mesh");
    break;
  case visualization_msgs::Marker::SPHERE_LIST:
    entity = scene_manager->createEntity("ShapeListMarker Temp", "ogre_tools_sphere.mesh");
    break;
  default:
    ROS_BREAK();
  }

  entity->setMaterialName(material_name_);
  geometry_->reset();

  tf::TransformListener* tf_client = vis_manager_->getTFClient();
  std::string fixed_frame = vis_manager_->getFixedFrame();

  tf::Stamped<btTransform> transform;
  try
  {
    tf_client->lookupTransform (fixed_frame, new_message->header.frame_id, new_message->header.stamp, transform);
  }
  catch (tf::TransformException& e)
  {
    ROS_ERROR("Error looking up transform for marker [%s/%d]: %s", new_message->ns.c_str(), new_message->id, e.what());
  }

  std::vector<robot_msgs::Point>::iterator it = new_message->points.begin();
  std::vector<robot_msgs::Point>::iterator end = new_message->points.end();
  for ( ; it != end; ++it )
  {
    robot_msgs::Point& p = *it;

    Ogre::Vector3 point(p.x, p.y, p.z);
    robotToOgre(point);

    point = pos + (orient * point);

    geometry_->addEntity(entity, point, orient, scale);
  }

  geometry_->build();

  scene_manager->destroyEntity(entity);
}

}
<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <string>
#include <memory>
#include <uv.h>
#include "event.hpp"
#include "handle.hpp"
#include "util.hpp"

namespace uvw {

namespace details {

enum class UVFsEventFlags: std::underlying_type_t<uv_fs_event_flags> {
    WATCH_ENTRY = UV_FS_EVENT_WATCH_ENTRY,
    STAT = UV_FS_EVENT_STAT,
    RECURSIVE = UV_FS_EVENT_RECURSIVE
};

enum class UVFsEvent: std::underlying_type_t<uv_fs_event> {
    RENAME = UV_RENAME,
    CHANGE = UV_CHANGE
};

}

struct FsEventEvent: Event<FsEventEvent> {
    FsEventEvent(std::string fPath, Flags<details::UVFsEvent> f)
        : flgs{std::move(f)}, relPath{std::move(fPath)}
    { }

    const char * filename() const noexcept { return relPath.data(); }
    Flags<details::UVFsEvent> flags() const noexcept { return flgs; }

private:
    Flags<details::UVFsEvent> flgs;
    std::string relPath;
};

class FsEvent final: public Handle<FsEvent, uv_fs_event_t> {
    static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) {
        FsEvent &fsEvent = *(static_cast<FsEvent*>(handle->data));
        if(status) { fsEvent.publish(ErrorEvent{status}); }
        else { fsEvent.publish(FsEventEvent{filename, static_cast<std::underlying_type_t<Event>>(events)}); }
    }

    using Handle::Handle;

public:
    using Watch = details::UVFsEvent;
    using Event = details::UVFsEventFlags;

    template<typename... Args>
    static std::shared_ptr<FsEvent> create(Args&&... args) {
        return std::shared_ptr<FsEvent>{new FsEvent{std::forward<Args>(args)...}};
    }

    bool init() { return initialize<uv_fs_event_t>(&uv_fs_event_init); }

    void start(std::string path, Flags<Watch> flags = Flags<Watch>{}) {
        invoke(&uv_fs_event_start, get<uv_fs_event_t>(), &startCallback, path.data(), flags);
    }

    void stop() { invoke(&uv_fs_event_stop, get<uv_fs_event_t>()); }
    std::string path() noexcept { return details::path(&uv_fs_event_getpath, get<uv_fs_event_t>()); }
};

}
<commit_msg>renaming FsEvent -> FsMonitor<commit_after>#pragma once

#include <utility>
#include <string>
#include <memory>
#include <uv.h>
#include "event.hpp"
#include "handle.hpp"
#include "util.hpp"

namespace uvw {

namespace details {

enum class UVFsEventFlags: std::underlying_type_t<uv_fs_event_flags> {
    WATCH_ENTRY = UV_FS_EVENT_WATCH_ENTRY,
    STAT = UV_FS_EVENT_STAT,
    RECURSIVE = UV_FS_EVENT_RECURSIVE
};

enum class UVFsEvent: std::underlying_type_t<uv_fs_event> {
    RENAME = UV_RENAME,
    CHANGE = UV_CHANGE
};

}

struct FsMonitorEvent: Event<FsMonitorEvent> {
    FsMonitorEvent(std::string fPath, Flags<details::UVFsEvent> f)
        : flgs{std::move(f)}, relPath{std::move(fPath)}
    { }

    const char * filename() const noexcept { return relPath.data(); }
    Flags<details::UVFsEvent> flags() const noexcept { return flgs; }

private:
    Flags<details::UVFsEvent> flgs;
    std::string relPath;
};

class FsMonitor final: public Handle<FsMonitor, uv_fs_event_t> {
    static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) {
        FsMonitor &fsMonitor = *(static_cast<FsMonitor*>(handle->data));
        if(status) { fsMonitor.publish(ErrorEvent{status}); }
        else { fsMonitor.publish(FsMonitorEvent{filename, static_cast<std::underlying_type_t<Event>>(events)}); }
    }

    using Handle::Handle;

public:
    using Watch = details::UVFsEvent;
    using Event = details::UVFsEventFlags;

    template<typename... Args>
    static std::shared_ptr<FsMonitor> create(Args&&... args) {
        return std::shared_ptr<FsMonitor>{new FsMonitor{std::forward<Args>(args)...}};
    }

    bool init() { return initialize<uv_fs_event_t>(&uv_fs_event_init); }

    void start(std::string path, Flags<Watch> flags = Flags<Watch>{}) {
        invoke(&uv_fs_event_start, get<uv_fs_event_t>(), &startCallback, path.data(), flags);
    }

    void stop() { invoke(&uv_fs_event_stop, get<uv_fs_event_t>()); }
    std::string path() noexcept { return details::path(&uv_fs_event_getpath, get<uv_fs_event_t>()); }
};

}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF 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.

#ifndef __MESOS_CONTAINERIZER_HPP__
#define __MESOS_CONTAINERIZER_HPP__

#include <list>
#include <vector>

#include <process/id.hpp>
#include <process/http.hpp>
#include <process/sequence.hpp>
#include <process/shared.hpp>

#include <process/metrics/counter.hpp>

#include <stout/hashmap.hpp>
#include <stout/multihashmap.hpp>
#include <stout/os/int_fd.hpp>

#include <mesos/slave/isolator.hpp>

#include "slave/state.hpp"

#include "slave/containerizer/containerizer.hpp"

#include "slave/containerizer/mesos/launcher.hpp"

#include "slave/containerizer/mesos/io/switchboard.hpp"

#include "slave/containerizer/mesos/isolators/gpu/nvidia.hpp"

#include "slave/containerizer/mesos/provisioner/provisioner.hpp"

namespace mesos {
namespace internal {
namespace slave {

// Forward declaration.
class MesosContainerizerProcess;

class MesosContainerizer : public Containerizer
{
public:
  static Try<MesosContainerizer*> create(
      const Flags& flags,
      bool local,
      Fetcher* fetcher,
      const Option<NvidiaComponents>& nvidia = None());

  static Try<MesosContainerizer*> create(
      const Flags& flags,
      bool local,
      Fetcher* fetcher,
      const process::Owned<Launcher>& launcher,
      const process::Shared<Provisioner>& provisioner,
      const std::vector<process::Owned<mesos::slave::Isolator>>& isolators);

  virtual ~MesosContainerizer();

  virtual process::Future<Nothing> recover(
      const Option<state::SlaveState>& state);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& directory,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const std::map<std::string, std::string>& environment,
      bool checkpoint);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const CommandInfo& commandInfo,
      const Option<ContainerInfo>& containerInfo,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const Option<mesos::slave::ContainerClass>& containerClass = None());

  virtual process::Future<process::http::Connection> attach(
      const ContainerID& containerId);

  virtual process::Future<Nothing> update(
      const ContainerID& containerId,
      const Resources& resources);

  virtual process::Future<ResourceStatistics> usage(
      const ContainerID& containerId);

  virtual process::Future<ContainerStatus> status(
      const ContainerID& containerId);

  virtual process::Future<Option<mesos::slave::ContainerTermination>> wait(
      const ContainerID& containerId);

  virtual process::Future<bool> destroy(
      const ContainerID& containerId);

  virtual process::Future<hashset<ContainerID>> containers();

  virtual process::Future<Nothing> remove(const ContainerID& containerId);

private:
  explicit MesosContainerizer(
      const process::Owned<MesosContainerizerProcess>& process);

  process::Owned<MesosContainerizerProcess> process;
};

class MesosContainerizerProcess
  : public process::Process<MesosContainerizerProcess>
{
public:
  MesosContainerizerProcess(
      const Flags& _flags,
      Fetcher* _fetcher,
      IOSwitchboard* _ioSwitchboard,
      const process::Owned<Launcher>& _launcher,
      const process::Shared<Provisioner>& _provisioner,
      const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators)
    : ProcessBase(process::ID::generate("mesos-containerizer")),
      flags(_flags),
      fetcher(_fetcher),
      ioSwitchboard(_ioSwitchboard),
      launcher(_launcher),
      provisioner(_provisioner),
      isolators(_isolators) {}

  virtual ~MesosContainerizerProcess() {}

  virtual process::Future<Nothing> recover(
      const Option<state::SlaveState>& state);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& directory,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const std::map<std::string, std::string>& environment,
      bool checkpoint);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const CommandInfo& commandInfo,
      const Option<ContainerInfo>& containerInfo,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const Option<mesos::slave::ContainerClass>& containerClass);

  virtual process::Future<process::http::Connection> attach(
      const ContainerID& containerId);

  virtual process::Future<Nothing> update(
      const ContainerID& containerId,
      const Resources& resources);

  virtual process::Future<ResourceStatistics> usage(
      const ContainerID& containerId);

  virtual process::Future<ContainerStatus> status(
      const ContainerID& containerId);

  virtual process::Future<Option<mesos::slave::ContainerTermination>> wait(
      const ContainerID& containerId);

  virtual process::Future<bool> exec(
      const ContainerID& containerId,
      int_fd pipeWrite);

  virtual process::Future<bool> destroy(
      const ContainerID& containerId);

  virtual process::Future<Nothing> remove(const ContainerID& containerId);

  virtual process::Future<hashset<ContainerID>> containers();

private:
  enum State
  {
    PROVISIONING,
    PREPARING,
    ISOLATING,
    FETCHING,
    RUNNING,
    DESTROYING
  };

  friend std::ostream& operator<<(std::ostream& stream, const State& state);

  process::Future<Nothing> _recover(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<std::list<Nothing>> recoverIsolators(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> recoverProvisioner(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> __recover(
      const std::list<mesos::slave::ContainerState>& recovered,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> prepare(
      const ContainerID& containerId,
      const Option<ProvisionInfo>& provisionInfo);

  process::Future<Nothing> fetch(
      const ContainerID& containerId,
      const SlaveID& slaveId);

  process::Future<bool> launch(
      const ContainerID& containerId,
      const mesos::slave::ContainerConfig& containerConfig,
      const std::map<std::string, std::string>& environment,
      const SlaveID& slaveId,
      bool checkpoint);

  process::Future<bool> _launch(
      const ContainerID& containerId,
      const Option<mesos::slave::ContainerIO>& containerIO,
      const std::map<std::string, std::string>& environment,
      const SlaveID& slaveId,
      bool checkpoint);

  process::Future<bool> isolate(
      const ContainerID& containerId,
      pid_t _pid);

  // Continues 'destroy()' once nested containers are handled.
  void _destroy(
      const ContainerID& containerId,
      const State& previousState,
      const std::list<process::Future<bool>>& destroys);

  // Continues '_destroy()' once isolators has completed.
  void __destroy(const ContainerID& containerId);

  // Continues '__destroy()' once all processes have been killed
  // by the launcher.
  void ___destroy(
      const ContainerID& containerId,
      const process::Future<Nothing>& future);

  // Continues '___destroy()' once we get the exit status of the container.
  void ____destroy(const ContainerID& containerId);

  // Continues '____destroy()' once all isolators have completed
  // cleanup.
  void _____destroy(
      const ContainerID& containerId,
      const process::Future<std::list<process::Future<Nothing>>>& cleanups);

  // Continues '_____destroy()' once provisioner have completed destroy.
  void ______destroy(
      const ContainerID& containerId,
      const process::Future<bool>& destroy);

  // Call back for when an isolator limits a container and impacts the
  // processes. This will trigger container destruction.
  void limited(
      const ContainerID& containerId,
      const process::Future<mesos::slave::ContainerLimitation>& future);

  // Helper for reaping the 'init' process of a container.
  process::Future<Option<int>> reap(
      const ContainerID& containerId,
      pid_t pid);

  // Call back for when the executor exits. This will trigger container
  // destroy.
  void reaped(const ContainerID& containerId);

  // TODO(jieyu): Consider introducing an Isolators struct and moving
  // all isolator related operations to that struct.
  process::Future<std::list<process::Future<Nothing>>> cleanupIsolators(
      const ContainerID& containerId);

  const Flags flags;
  Fetcher* fetcher;
  IOSwitchboard* ioSwitchboard;
  const process::Owned<Launcher> launcher;
  const process::Shared<Provisioner> provisioner;
  const std::vector<process::Owned<mesos::slave::Isolator>> isolators;

  struct Container
  {
    Container() : sequence("mesos-container-status-updates") {}

    // Promise for futures returned from wait().
    process::Promise<mesos::slave::ContainerTermination> termination;

    // NOTE: this represents 'PID 1', i.e., the "init" of the
    // container that we created (it may be for an executor, or any
    // arbitrary process that has been launched in the event of nested
    // containers).
    Option<pid_t> pid;

    // Sandbox directory for the container. It is optional here because
    // we don't keep track of sandbox directory for orphan containers.
    Option<std::string> directory;

    // We keep track of the future exit status for the container if it
    // has been launched. If the container has not been launched yet,
    // 'status' will be set to None().
    //
    // NOTE: A container has an exit status does not mean that it has
    // been properly destroyed. We need to perform cleanup on
    // isolators and provisioner after that.
    Option<process::Future<Option<int>>> status;

    // We keep track of the future for 'provisioner->provision' so
    // that destroy will only start calling 'provisioner->destroy'
    // after 'provisioner->provision' has finished.
    process::Future<ProvisionInfo> provisioning;

    // We keep track of the future that is waiting for all the
    // 'isolator->prepare' to finish so that destroy will only start
    // calling cleanup after all isolators have finished preparing.
    process::Future<std::list<Option<mesos::slave::ContainerLaunchInfo>>>
      launchInfos;

    // We keep track of the future that is waiting for all the
    // 'isolator->isolate' futures so that destroy will only start
    // calling cleanup after all isolators have finished isolating.
    process::Future<std::list<Nothing>> isolation;

    // We keep track of any limitations received from each isolator so
    // we can determine the cause of a container termination.
    std::vector<mesos::slave::ContainerLimitation> limitations;

    // We keep track of the resources for each container so we can set
    // the ResourceStatistics limits in usage().
    Resources resources;

    // The configuration for the container to be launched. This field
    // is only used during the launch of a container.
    mesos::slave::ContainerConfig config;

    // Container's information at the moment it was launched. For example,
    // used to bootstrap the launch information of future child DEBUG
    // containers. Checkpointed and restored on recovery. Optional because
    // it is not set for orphan containers.
    //
    // NOTE: Some of these data, may change during the container lifetime,
    // e.g., the working directory. Such changes are not be captured here,
    // which might be problematic, e.g., for DEBUG containers relying on
    // some data in parent working directory.
    Option<mesos::slave::ContainerLaunchInfo> launchInfo;

    State state;

    // Used when `status` needs to be collected from isolators
    // associated with this container. `Sequence` allows us to
    // maintain the order of `status` requests for a given container.
    process::Sequence sequence;

    // Child containers nested under this container.
    hashset<ContainerID> children;
  };

  hashmap<ContainerID, process::Owned<Container>> containers_;

  struct Metrics
  {
    Metrics();
    ~Metrics();

    process::metrics::Counter container_destroy_errors;
  } metrics;
};

std::ostream& operator<<(
    std::ostream& stream,
    const MesosContainerizerProcess::State& state);

} // namespace slave {
} // namespace internal {
} // namespace mesos {

#endif // __MESOS_CONTAINERIZER_HPP__
<commit_msg>Clarified the comment about Container.directory.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF 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.

#ifndef __MESOS_CONTAINERIZER_HPP__
#define __MESOS_CONTAINERIZER_HPP__

#include <list>
#include <vector>

#include <process/id.hpp>
#include <process/http.hpp>
#include <process/sequence.hpp>
#include <process/shared.hpp>

#include <process/metrics/counter.hpp>

#include <stout/hashmap.hpp>
#include <stout/multihashmap.hpp>
#include <stout/os/int_fd.hpp>

#include <mesos/slave/isolator.hpp>

#include "slave/state.hpp"

#include "slave/containerizer/containerizer.hpp"

#include "slave/containerizer/mesos/launcher.hpp"

#include "slave/containerizer/mesos/io/switchboard.hpp"

#include "slave/containerizer/mesos/isolators/gpu/nvidia.hpp"

#include "slave/containerizer/mesos/provisioner/provisioner.hpp"

namespace mesos {
namespace internal {
namespace slave {

// Forward declaration.
class MesosContainerizerProcess;

class MesosContainerizer : public Containerizer
{
public:
  static Try<MesosContainerizer*> create(
      const Flags& flags,
      bool local,
      Fetcher* fetcher,
      const Option<NvidiaComponents>& nvidia = None());

  static Try<MesosContainerizer*> create(
      const Flags& flags,
      bool local,
      Fetcher* fetcher,
      const process::Owned<Launcher>& launcher,
      const process::Shared<Provisioner>& provisioner,
      const std::vector<process::Owned<mesos::slave::Isolator>>& isolators);

  virtual ~MesosContainerizer();

  virtual process::Future<Nothing> recover(
      const Option<state::SlaveState>& state);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& directory,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const std::map<std::string, std::string>& environment,
      bool checkpoint);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const CommandInfo& commandInfo,
      const Option<ContainerInfo>& containerInfo,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const Option<mesos::slave::ContainerClass>& containerClass = None());

  virtual process::Future<process::http::Connection> attach(
      const ContainerID& containerId);

  virtual process::Future<Nothing> update(
      const ContainerID& containerId,
      const Resources& resources);

  virtual process::Future<ResourceStatistics> usage(
      const ContainerID& containerId);

  virtual process::Future<ContainerStatus> status(
      const ContainerID& containerId);

  virtual process::Future<Option<mesos::slave::ContainerTermination>> wait(
      const ContainerID& containerId);

  virtual process::Future<bool> destroy(
      const ContainerID& containerId);

  virtual process::Future<hashset<ContainerID>> containers();

  virtual process::Future<Nothing> remove(const ContainerID& containerId);

private:
  explicit MesosContainerizer(
      const process::Owned<MesosContainerizerProcess>& process);

  process::Owned<MesosContainerizerProcess> process;
};

class MesosContainerizerProcess
  : public process::Process<MesosContainerizerProcess>
{
public:
  MesosContainerizerProcess(
      const Flags& _flags,
      Fetcher* _fetcher,
      IOSwitchboard* _ioSwitchboard,
      const process::Owned<Launcher>& _launcher,
      const process::Shared<Provisioner>& _provisioner,
      const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators)
    : ProcessBase(process::ID::generate("mesos-containerizer")),
      flags(_flags),
      fetcher(_fetcher),
      ioSwitchboard(_ioSwitchboard),
      launcher(_launcher),
      provisioner(_provisioner),
      isolators(_isolators) {}

  virtual ~MesosContainerizerProcess() {}

  virtual process::Future<Nothing> recover(
      const Option<state::SlaveState>& state);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const Option<TaskInfo>& taskInfo,
      const ExecutorInfo& executorInfo,
      const std::string& directory,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const std::map<std::string, std::string>& environment,
      bool checkpoint);

  virtual process::Future<bool> launch(
      const ContainerID& containerId,
      const CommandInfo& commandInfo,
      const Option<ContainerInfo>& containerInfo,
      const Option<std::string>& user,
      const SlaveID& slaveId,
      const Option<mesos::slave::ContainerClass>& containerClass);

  virtual process::Future<process::http::Connection> attach(
      const ContainerID& containerId);

  virtual process::Future<Nothing> update(
      const ContainerID& containerId,
      const Resources& resources);

  virtual process::Future<ResourceStatistics> usage(
      const ContainerID& containerId);

  virtual process::Future<ContainerStatus> status(
      const ContainerID& containerId);

  virtual process::Future<Option<mesos::slave::ContainerTermination>> wait(
      const ContainerID& containerId);

  virtual process::Future<bool> exec(
      const ContainerID& containerId,
      int_fd pipeWrite);

  virtual process::Future<bool> destroy(
      const ContainerID& containerId);

  virtual process::Future<Nothing> remove(const ContainerID& containerId);

  virtual process::Future<hashset<ContainerID>> containers();

private:
  enum State
  {
    PROVISIONING,
    PREPARING,
    ISOLATING,
    FETCHING,
    RUNNING,
    DESTROYING
  };

  friend std::ostream& operator<<(std::ostream& stream, const State& state);

  process::Future<Nothing> _recover(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<std::list<Nothing>> recoverIsolators(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> recoverProvisioner(
      const std::list<mesos::slave::ContainerState>& recoverable,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> __recover(
      const std::list<mesos::slave::ContainerState>& recovered,
      const hashset<ContainerID>& orphans);

  process::Future<Nothing> prepare(
      const ContainerID& containerId,
      const Option<ProvisionInfo>& provisionInfo);

  process::Future<Nothing> fetch(
      const ContainerID& containerId,
      const SlaveID& slaveId);

  process::Future<bool> launch(
      const ContainerID& containerId,
      const mesos::slave::ContainerConfig& containerConfig,
      const std::map<std::string, std::string>& environment,
      const SlaveID& slaveId,
      bool checkpoint);

  process::Future<bool> _launch(
      const ContainerID& containerId,
      const Option<mesos::slave::ContainerIO>& containerIO,
      const std::map<std::string, std::string>& environment,
      const SlaveID& slaveId,
      bool checkpoint);

  process::Future<bool> isolate(
      const ContainerID& containerId,
      pid_t _pid);

  // Continues 'destroy()' once nested containers are handled.
  void _destroy(
      const ContainerID& containerId,
      const State& previousState,
      const std::list<process::Future<bool>>& destroys);

  // Continues '_destroy()' once isolators has completed.
  void __destroy(const ContainerID& containerId);

  // Continues '__destroy()' once all processes have been killed
  // by the launcher.
  void ___destroy(
      const ContainerID& containerId,
      const process::Future<Nothing>& future);

  // Continues '___destroy()' once we get the exit status of the container.
  void ____destroy(const ContainerID& containerId);

  // Continues '____destroy()' once all isolators have completed
  // cleanup.
  void _____destroy(
      const ContainerID& containerId,
      const process::Future<std::list<process::Future<Nothing>>>& cleanups);

  // Continues '_____destroy()' once provisioner have completed destroy.
  void ______destroy(
      const ContainerID& containerId,
      const process::Future<bool>& destroy);

  // Call back for when an isolator limits a container and impacts the
  // processes. This will trigger container destruction.
  void limited(
      const ContainerID& containerId,
      const process::Future<mesos::slave::ContainerLimitation>& future);

  // Helper for reaping the 'init' process of a container.
  process::Future<Option<int>> reap(
      const ContainerID& containerId,
      pid_t pid);

  // Call back for when the executor exits. This will trigger container
  // destroy.
  void reaped(const ContainerID& containerId);

  // TODO(jieyu): Consider introducing an Isolators struct and moving
  // all isolator related operations to that struct.
  process::Future<std::list<process::Future<Nothing>>> cleanupIsolators(
      const ContainerID& containerId);

  const Flags flags;
  Fetcher* fetcher;
  IOSwitchboard* ioSwitchboard;
  const process::Owned<Launcher> launcher;
  const process::Shared<Provisioner> provisioner;
  const std::vector<process::Owned<mesos::slave::Isolator>> isolators;

  struct Container
  {
    Container() : sequence("mesos-container-status-updates") {}

    // Promise for futures returned from wait().
    process::Promise<mesos::slave::ContainerTermination> termination;

    // NOTE: this represents 'PID 1', i.e., the "init" of the
    // container that we created (it may be for an executor, or any
    // arbitrary process that has been launched in the event of nested
    // containers).
    Option<pid_t> pid;

    // Sandbox directory for the container. It is optional here because
    // we don't keep track of sandbox directory for orphan containers.
    // It is not checkpointed explicitly; on recovery, it is reconstructed
    // from executor's directory and hierarchy of containers.
    //
    // NOTE: This holds the sandbox path in the host mount namespace,
    // while MESOS_SANDBOX is the path in the container mount namespace.
    Option<std::string> directory;

    // We keep track of the future exit status for the container if it
    // has been launched. If the container has not been launched yet,
    // 'status' will be set to None().
    //
    // NOTE: A container has an exit status does not mean that it has
    // been properly destroyed. We need to perform cleanup on
    // isolators and provisioner after that.
    Option<process::Future<Option<int>>> status;

    // We keep track of the future for 'provisioner->provision' so
    // that destroy will only start calling 'provisioner->destroy'
    // after 'provisioner->provision' has finished.
    process::Future<ProvisionInfo> provisioning;

    // We keep track of the future that is waiting for all the
    // 'isolator->prepare' to finish so that destroy will only start
    // calling cleanup after all isolators have finished preparing.
    process::Future<std::list<Option<mesos::slave::ContainerLaunchInfo>>>
      launchInfos;

    // We keep track of the future that is waiting for all the
    // 'isolator->isolate' futures so that destroy will only start
    // calling cleanup after all isolators have finished isolating.
    process::Future<std::list<Nothing>> isolation;

    // We keep track of any limitations received from each isolator so
    // we can determine the cause of a container termination.
    std::vector<mesos::slave::ContainerLimitation> limitations;

    // We keep track of the resources for each container so we can set
    // the ResourceStatistics limits in usage().
    Resources resources;

    // The configuration for the container to be launched. This field
    // is only used during the launch of a container.
    mesos::slave::ContainerConfig config;

    // Container's information at the moment it was launched. For example,
    // used to bootstrap the launch information of future child DEBUG
    // containers. Checkpointed and restored on recovery. Optional because
    // it is not set for orphan containers.
    //
    // NOTE: Some of these data, may change during the container lifetime,
    // e.g., the working directory. Such changes are not be captured here,
    // which might be problematic, e.g., for DEBUG containers relying on
    // some data in parent working directory.
    Option<mesos::slave::ContainerLaunchInfo> launchInfo;

    State state;

    // Used when `status` needs to be collected from isolators
    // associated with this container. `Sequence` allows us to
    // maintain the order of `status` requests for a given container.
    process::Sequence sequence;

    // Child containers nested under this container.
    hashset<ContainerID> children;
  };

  hashmap<ContainerID, process::Owned<Container>> containers_;

  struct Metrics
  {
    Metrics();
    ~Metrics();

    process::metrics::Counter container_destroy_errors;
  } metrics;
};

std::ostream& operator<<(
    std::ostream& stream,
    const MesosContainerizerProcess::State& state);

} // namespace slave {
} // namespace internal {
} // namespace mesos {

#endif // __MESOS_CONTAINERIZER_HPP__
<|endoftext|>


<commit_before>#pragma once

#include "openMVG/multiview/solver_fundamental_kernel.hpp"
#include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp"
#include "openMVG/robust_estimation/robust_estimator_ACRansacKernelAdaptator.hpp"

using namespace openMVG;
using namespace openMVG::robust;

//-- A contrario Functor to filter putative corresponding points
struct GeometricFilter_FMatrix_AC
{
  GeometricFilter_FMatrix_AC(double dPrecision, size_t iteration = 4096)
    : m_dPrecision(dPrecision), m_stIteration(iteration) {};

  /// Robust fitting of the FUNDAMENTAL matrix
  void Fit(
    const Mat & xA,
    const std::pair<size_t, size_t> & imgSizeA,
    const Mat & xB,
    const std::pair<size_t, size_t> & imgSizeB,
    std::vector<size_t> & vec_inliers) const
  {
    vec_inliers.resize(0);
    // Define the AContrario adapted Fundamental matrix solver
    typedef ACKernelAdaptor<
      openMVG::fundamental::kernel::SevenPointSolver,
      openMVG::fundamental::kernel::SimpleError,
      UnnormalizerT,
      Mat3>
      KernelType;

    KernelType kernel(xA, imgSizeA.first, imgSizeA.second,
                      xB, imgSizeB.first, imgSizeB.second, true);

    // Robustly estimate the Fundamental matrix with A Contrario ransac
    Mat3 F;
    double upper_bound_precision = m_dPrecision;
    std::pair<double,double> ACRansacOut =
      ACRANSAC(kernel, vec_inliers, m_stIteration, &F, upper_bound_precision);
    const double & threshold = ACRansacOut.first;
    const double & NFA = ACRansacOut.second;

    if (vec_inliers.size() < KernelType::MINIMUM_SAMPLES *2.5)  {
      vec_inliers.clear();
    }
  }

  double m_dPrecision;  //upper_bound of the precision
  size_t m_stIteration; //maximal number of iteration used
};
<commit_msg>add default argument<commit_after>#pragma once

#include <limits>
#include "openMVG/multiview/solver_fundamental_kernel.hpp"
#include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp"
#include "openMVG/robust_estimation/robust_estimator_ACRansacKernelAdaptator.hpp"

using namespace openMVG;
using namespace openMVG::robust;

//-- A contrario Functor to filter putative corresponding points
struct GeometricFilter_FMatrix_AC
{
  GeometricFilter_FMatrix_AC(
    double dPrecision = std::numeric_limits<double>::infinity(),
    size_t iteration = 4096)
    : m_dPrecision(dPrecision), m_stIteration(iteration) {};

  /// Robust fitting of the FUNDAMENTAL matrix
  void Fit(
    const Mat & xA,
    const std::pair<size_t, size_t> & imgSizeA,
    const Mat & xB,
    const std::pair<size_t, size_t> & imgSizeB,
    std::vector<size_t> & vec_inliers) const
  {
    vec_inliers.resize(0);
    // Define the AContrario adapted Fundamental matrix solver
    typedef ACKernelAdaptor<
      openMVG::fundamental::kernel::SevenPointSolver,
      openMVG::fundamental::kernel::SimpleError,
      UnnormalizerT,
      Mat3>
      KernelType;

    KernelType kernel(xA, imgSizeA.first, imgSizeA.second,
                      xB, imgSizeB.first, imgSizeB.second, true);

    // Robustly estimate the Fundamental matrix with A Contrario ransac
    Mat3 F;
    double upper_bound_precision = m_dPrecision;
    std::pair<double,double> ACRansacOut =
      ACRANSAC(kernel, vec_inliers, m_stIteration, &F, upper_bound_precision);
    const double & threshold = ACRansacOut.first;
    const double & NFA = ACRansacOut.second;

    if (vec_inliers.size() < KernelType::MINIMUM_SAMPLES *2.5)  {
      vec_inliers.clear();
    }
  }

  double m_dPrecision;  //upper_bound of the precision
  size_t m_stIteration; //maximal number of iteration used
};
<|endoftext|>


<commit_before>#include <openMVG/rig/Rig.hpp>
#include <openMVG/logger.hpp>

#include <openMVG/sfm/sfm_data.hpp>
#include <openMVG/sfm/sfm_data_io.hpp>

#if HAVE_ALEMBIC
#include <openMVG/sfm/AlembicExporter.hpp>
#endif // HAVE_ALEMBIC

#include <boost/filesystem.hpp>
#include <boost/progress.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <chrono>
#include <memory>

namespace bfs = boost::filesystem;
namespace po = boost::program_options;

using namespace openMVG;
using namespace openMVG::sfm;

static std::vector<double> ReadIntrinsicsFile(const std::string& fname)
{
  cout << "reading intrinsics: " << fname << endl;

  std::vector<double> v(8);
  std::ifstream ifs(fname);
  if (!(ifs >> v[0] >> v[1] >> v[2] >> v[3] >> v[4] >> v[5] >> v[6] >> v[7]))
    throw std::runtime_error("failed to read intrinsics file");
  return v;
}

int main(int argc, char** argv)
{
  std::string exportFile = "trackedcameras-rig.abc"; //!< the export file
  std::string importFile = "";
  std::string rigFile = "";
  std::string calibFile = "";
  std::vector<openMVG::geometry::Pose3> extrinsics;  // the rig subposes

  po::options_description desc("If you have localized a single camera from an acquisition with a RIG of cameras, you can use this program to deduce the pose of the other cameras of the RIG.");
  desc.add_options()
        ("help,h", "Print this message")
        ("input,i", po::value<std::string>(&importFile)->required(),
            "The input file containing cameras.")
        ("output,o", po::value<std::string>(&exportFile)->default_value(exportFile),
          "Filename for the SfM_Data export file (where camera poses will be stored)."
          " Only Alembic supported for now. Default: trackedcameras-rig.abc.")
        ("rigFile,e", po::value<std::string>(&rigFile)->required(),
            "Rig calibration file that will be  applied to input.")
        ("calibrationFile,c", po::value<std::string>(&calibFile)->required(),
            "A calibration file for the target camera.")
          ;

  po::variables_map vm;

  try
  {
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if(vm.count("help") || (argc == 1))
    {
      OPENMVG_COUT(desc);
      return EXIT_SUCCESS;
    }

    po::notify(vm);
  }
  catch(boost::program_options::required_option& e)
  {
    OPENMVG_CERR("ERROR: " << e.what() << std::endl);
    OPENMVG_COUT("Usage:\n\n" << desc);
    return EXIT_FAILURE;
  }
  catch(boost::program_options::error& e)
  {
    OPENMVG_CERR("ERROR: " << e.what() << std::endl);
    OPENMVG_COUT("Usage:\n\n" << desc);
    return EXIT_FAILURE;
  }
  // just debugging prints
  {
    OPENMVG_COUT("Program called with the following parameters:");
    OPENMVG_COUT("\timportFile: " << importFile);
    OPENMVG_COUT("\texportFile: " << exportFile);
    OPENMVG_COUT("\trigFile: " << rigFile);
    OPENMVG_COUT("\tcalibFile: " << calibFile);

  }

  // Load rig calibration file
  if(!rig::loadRigCalibration(rigFile, extrinsics))
  {
    cerr << "unable to open " << rigFile << endl;
    exit(1);
  }
  assert(!extrinsics.empty());

  // Import sfm data
  int flags = sfm::ESfM_Data::ALL;
  SfM_Data sfmData;
  Load(sfmData, importFile, ESfM_Data(flags));

  // Load intrinsics
  auto v = ReadIntrinsicsFile(calibFile);
  openMVG::cameras::Pinhole_Intrinsic_Radial_K3 intrinsics = openMVG::cameras::Pinhole_Intrinsic_Radial_K3(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);

  // Export to abc
#if HAVE_ALEMBIC
  dataio::AlembicExporter exporter( exportFile );
  exporter.initAnimatedCamera("camera");

  size_t idx = 0;
  for (auto &p : sfmData.poses)
  {
    const openMVG::geometry::Pose3 rigPose = extrinsics[0].inverse() * p.second;
    exporter.addCameraKeyframe(rigPose, &intrinsics, "", idx, idx);
    ++idx;
  }
  exporter.addPoints(sfmData.GetLandmarks());
#endif

  OPENMVG_COUT("Done.");
}
<commit_msg>[software] rigTransform: remove ifdef HAVE_ALEMBIC as the software is builded only if Alembic is available<commit_after>#include <openMVG/rig/Rig.hpp>
#include <openMVG/logger.hpp>

#include <openMVG/sfm/sfm_data.hpp>
#include <openMVG/sfm/sfm_data_io.hpp>

#include <openMVG/sfm/AlembicExporter.hpp>

#include <boost/filesystem.hpp>
#include <boost/progress.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <chrono>
#include <memory>

namespace bfs = boost::filesystem;
namespace po = boost::program_options;

using namespace openMVG;
using namespace openMVG::sfm;

static std::vector<double> ReadIntrinsicsFile(const std::string& fname)
{
  cout << "reading intrinsics: " << fname << endl;

  std::vector<double> v(8);
  std::ifstream ifs(fname);
  if (!(ifs >> v[0] >> v[1] >> v[2] >> v[3] >> v[4] >> v[5] >> v[6] >> v[7]))
    throw std::runtime_error("failed to read intrinsics file");
  return v;
}

int main(int argc, char** argv)
{
  std::string exportFile = "trackedcameras-rig.abc"; //!< the export file
  std::string importFile = "";
  std::string rigFile = "";
  std::string calibFile = "";
  std::vector<openMVG::geometry::Pose3> extrinsics;  // the rig subposes

  po::options_description desc("If you have localized a single camera from an acquisition with a RIG of cameras, you can use this program to deduce the pose of the other cameras of the RIG.");
  desc.add_options()
        ("help,h", "Print this message")
        ("input,i", po::value<std::string>(&importFile)->required(),
            "The input file containing cameras.")
        ("output,o", po::value<std::string>(&exportFile)->default_value(exportFile),
          "Filename for the SfM_Data export file (where camera poses will be stored)."
          " Only Alembic supported for now. Default: trackedcameras-rig.abc.")
        ("rigFile,e", po::value<std::string>(&rigFile)->required(),
            "Rig calibration file that will be  applied to input.")
        ("calibrationFile,c", po::value<std::string>(&calibFile)->required(),
            "A calibration file for the target camera.")
          ;

  po::variables_map vm;

  try
  {
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if(vm.count("help") || (argc == 1))
    {
      OPENMVG_COUT(desc);
      return EXIT_SUCCESS;
    }

    po::notify(vm);
  }
  catch(boost::program_options::required_option& e)
  {
    OPENMVG_CERR("ERROR: " << e.what() << std::endl);
    OPENMVG_COUT("Usage:\n\n" << desc);
    return EXIT_FAILURE;
  }
  catch(boost::program_options::error& e)
  {
    OPENMVG_CERR("ERROR: " << e.what() << std::endl);
    OPENMVG_COUT("Usage:\n\n" << desc);
    return EXIT_FAILURE;
  }
  // just debugging prints
  {
    OPENMVG_COUT("Program called with the following parameters:");
    OPENMVG_COUT("\timportFile: " << importFile);
    OPENMVG_COUT("\texportFile: " << exportFile);
    OPENMVG_COUT("\trigFile: " << rigFile);
    OPENMVG_COUT("\tcalibFile: " << calibFile);

  }

  // Load rig calibration file
  if(!rig::loadRigCalibration(rigFile, extrinsics))
  {
    cerr << "unable to open " << rigFile << endl;
    exit(1);
  }
  assert(!extrinsics.empty());

  // Import sfm data
  int flags = sfm::ESfM_Data::ALL;
  SfM_Data sfmData;
  Load(sfmData, importFile, ESfM_Data(flags));

  // Load intrinsics
  auto v = ReadIntrinsicsFile(calibFile);
  openMVG::cameras::Pinhole_Intrinsic_Radial_K3 intrinsics = openMVG::cameras::Pinhole_Intrinsic_Radial_K3(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);

  // Export to abc
  dataio::AlembicExporter exporter( exportFile );
  exporter.initAnimatedCamera("camera");

  size_t idx = 0;
  for (auto &p : sfmData.poses)
  {
    const openMVG::geometry::Pose3 rigPose = extrinsics[0].inverse() * p.second;
    exporter.addCameraKeyframe(rigPose, &intrinsics, "", idx, idx);
    ++idx;
  }
  exporter.addPoints(sfmData.GetLandmarks());

  OPENMVG_COUT("Done.");
}
<|endoftext|>