<commit_before>// Copyright 2014 Samsung Electronics. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "command_line_efl.h"

#include <string>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>

#include "content/public/common/content_switches.h"
#include "content/public/common/content_client.h"
#include "cc/base/switches.h"
#include "ui/events/event_switches.h"
#include "extensions/common/switches.h"
#include "ui/gl/gl_switches.h"
#include "url/gurl.h"

int CommandLineEfl::argc_ = 0;
char** CommandLineEfl::argv_ = NULL;
CommandLineEfl::ArgumentVector CommandLineEfl::original_arguments_;
bool CommandLineEfl::is_initialized_ = false;

void CommandLineEfl::Init(int argc, char *argv[]) {
  if (CommandLineEfl::is_initialized_) {
    LOG(ERROR) << "CommandLineEfl::Init should not be called more than once";
  }
  CommandLine::Init(argc, argv);
  argc_ = argc;
  argv_ = argv;

  // Unfortunately chromium modifies application's argument vector.
  // during initialization. This means that chromium after initialization
  // argv will only contain one valid entry, argv[0]. To be able to use
  // user provided arguments after initialization we need to make a copy
  // of them.
  // See: chromium/src/content/common/set_process_title_linux.cc
  for (int i = 0; i < argc; ++i)
    original_arguments_.push_back(std::string(argv[i]));
  CommandLineEfl::is_initialized_ = true;
}

content::MainFunctionParams CommandLineEfl::GetDefaultPortParams() {
  if (!CommandLineEfl::is_initialized_) {
    CommandLineEfl::Init(0, NULL);
  }
  CommandLine* p_command_line = CommandLine::ForCurrentProcess();

  p_command_line->AppendSwitch(switches::kNoSandbox);
  p_command_line->AppendSwitch(switches::kDisablePlugins);
  p_command_line->AppendSwitch(switches::kInProcessGPU);

  p_command_line->AppendSwitch(switches::kEnableViewportMeta);

  p_command_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName);
  p_command_line->AppendSwitch(switches::kDisableDelegatedRenderer);

  // (prashant.n): New mechanism supports drawing frame to mailbox only.
  p_command_line->AppendSwitch(cc::switches::kCompositeToMailbox);

#if defined(OS_TIZEN)
  p_command_line->AppendSwitch(switches::kEnableOverscrollNotifications);
  p_command_line->AppendSwitch(switches::kTouchEvents);
  p_command_line->AppendSwitch(switches::kEnablePinch);
#if !defined(EWK_BRINGUP)
  p_command_line->AppendSwitch(switches::kEnableGestureTapHighlight);
#endif
  p_command_line->AppendSwitch(switches::kEnableSpatialNavigation);
  p_command_line->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);

  // FIXME(Kapil) Will be removed after permission handling implementation.
  p_command_line->AppendSwitch(switches::kDisableWebSecurity);
  p_command_line->AppendSwitch(switches::kForceAccelerated2dCanvas);
#else
  p_command_line->AppendSwitch(switches::kIgnoreGpuBlacklist);
#endif

#if defined(OS_TIZEN_MOBILE)
  p_command_line->AppendSwitch(switches::kUseMobileUserAgent);
#endif

#warning "[M37] Investigae removed command line switches, are they still needed, do they have a replacement?"
  // [M37] Note: The commit "Temporarily disable zero copy as it causes browser crash during regression"
  // is to deprecate kEnableMapImage option.
  // But it was already deprecated during fixing M37 build as no command line option with such name (see above comment)
  // TODO: remove this commit if it turn out the option is unnecessary
  //Disabling temporarily, as it causes browser crash ID:335 in regression
  //p_command_line->AppendSwitch(cc::switches::kEnableMapImage);

  // Threaded compositing breaks touch events. Seems to be a linux specific issue
  // (see: http://code.google.com/p/chromium/issues/detail?id=271791)
  //p_command_line->AppendSwitch(switches::kEnableThreadedCompositing);

#warning "[M37] Investigae removed command line switches, are they still needed, do they have a replacement?"
  //p_command_line->AppendSwitch(switches::kAllowWebUICompositing);

  // XXX: Skia benchmarking should be only used for testing,
  // when enabled the following warning is printed to stderr:
  // "Enabling unsafe Skia benchmarking extension."
  // p_command_line->AppendSwitch(switches::kEnableSkiaBenchmarking);

  AppendUserArgs(*p_command_line);

  return content::MainFunctionParams(*p_command_line);
}

void CommandLineEfl::AppendProcessSpecificArgs(CommandLine& command_line) {
  std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType);

  if (process_type == switches::kRendererProcess) {
    command_line.AppendSwitch(switches::kDisablePlugins);
  }
  AppendUserArgs(command_line);
}

void CommandLineEfl::AppendUserArgs(CommandLine& command_line) {
  for (ArgumentVector::const_iterator it = original_arguments_.begin();
       it != original_arguments_.end(); ++it) {
    command_line.AppendSwitch(*it);
  }
}
<commit_msg>Enable "enable-view-port-meta" only on mobile<commit_after>// Copyright 2014 Samsung Electronics. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "command_line_efl.h"

#include <string>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>

#include "content/public/common/content_switches.h"
#include "content/public/common/content_client.h"
#include "cc/base/switches.h"
#include "ui/events/event_switches.h"
#include "extensions/common/switches.h"
#include "ui/gl/gl_switches.h"
#include "url/gurl.h"

int CommandLineEfl::argc_ = 0;
char** CommandLineEfl::argv_ = NULL;
CommandLineEfl::ArgumentVector CommandLineEfl::original_arguments_;
bool CommandLineEfl::is_initialized_ = false;

void CommandLineEfl::Init(int argc, char *argv[]) {
  if (CommandLineEfl::is_initialized_) {
    LOG(ERROR) << "CommandLineEfl::Init should not be called more than once";
  }
  CommandLine::Init(argc, argv);
  argc_ = argc;
  argv_ = argv;

  // Unfortunately chromium modifies application's argument vector.
  // during initialization. This means that chromium after initialization
  // argv will only contain one valid entry, argv[0]. To be able to use
  // user provided arguments after initialization we need to make a copy
  // of them.
  // See: chromium/src/content/common/set_process_title_linux.cc
  for (int i = 0; i < argc; ++i)
    original_arguments_.push_back(std::string(argv[i]));
  CommandLineEfl::is_initialized_ = true;
}

content::MainFunctionParams CommandLineEfl::GetDefaultPortParams() {
  if (!CommandLineEfl::is_initialized_) {
    CommandLineEfl::Init(0, NULL);
  }
  CommandLine* p_command_line = CommandLine::ForCurrentProcess();

  p_command_line->AppendSwitch(switches::kNoSandbox);
  p_command_line->AppendSwitch(switches::kDisablePlugins);
  p_command_line->AppendSwitch(switches::kInProcessGPU);
  p_command_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName);
  p_command_line->AppendSwitch(switches::kDisableDelegatedRenderer);

  // (prashant.n): New mechanism supports drawing frame to mailbox only.
  p_command_line->AppendSwitch(cc::switches::kCompositeToMailbox);

#if defined(OS_TIZEN)
  p_command_line->AppendSwitch(switches::kEnableOverscrollNotifications);
  p_command_line->AppendSwitch(switches::kTouchEvents);
  p_command_line->AppendSwitch(switches::kEnablePinch);
#if !defined(EWK_BRINGUP)
  p_command_line->AppendSwitch(switches::kEnableGestureTapHighlight);
#endif
  p_command_line->AppendSwitch(switches::kEnableSpatialNavigation);
  p_command_line->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);

  // FIXME(Kapil) Will be removed after permission handling implementation.
  p_command_line->AppendSwitch(switches::kDisableWebSecurity);
  p_command_line->AppendSwitch(switches::kForceAccelerated2dCanvas);
#else
  p_command_line->AppendSwitch(switches::kIgnoreGpuBlacklist);
#endif

#if defined(OS_TIZEN_MOBILE)
  p_command_line->AppendSwitch(switches::kUseMobileUserAgent);
  p_command_line->AppendSwitch(switches::kEnableViewportMeta);
#endif

#warning "[M37] Investigae removed command line switches, are they still needed, do they have a replacement?"
  // [M37] Note: The commit "Temporarily disable zero copy as it causes browser crash during regression"
  // is to deprecate kEnableMapImage option.
  // But it was already deprecated during fixing M37 build as no command line option with such name (see above comment)
  // TODO: remove this commit if it turn out the option is unnecessary
  //Disabling temporarily, as it causes browser crash ID:335 in regression
  //p_command_line->AppendSwitch(cc::switches::kEnableMapImage);

  // Threaded compositing breaks touch events. Seems to be a linux specific issue
  // (see: http://code.google.com/p/chromium/issues/detail?id=271791)
  //p_command_line->AppendSwitch(switches::kEnableThreadedCompositing);

#warning "[M37] Investigae removed command line switches, are they still needed, do they have a replacement?"
  //p_command_line->AppendSwitch(switches::kAllowWebUICompositing);

  // XXX: Skia benchmarking should be only used for testing,
  // when enabled the following warning is printed to stderr:
  // "Enabling unsafe Skia benchmarking extension."
  // p_command_line->AppendSwitch(switches::kEnableSkiaBenchmarking);

  AppendUserArgs(*p_command_line);

  return content::MainFunctionParams(*p_command_line);
}

void CommandLineEfl::AppendProcessSpecificArgs(CommandLine& command_line) {
  std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType);

  if (process_type == switches::kRendererProcess) {
    command_line.AppendSwitch(switches::kDisablePlugins);
  }
  AppendUserArgs(command_line);
}

void CommandLineEfl::AppendUserArgs(CommandLine& command_line) {
  for (ArgumentVector::const_iterator it = original_arguments_.begin();
       it != original_arguments_.end(); ++it) {
    command_line.AppendSwitch(*it);
  }
}
<|endoftext|>


<commit_before>#include "Globals.h"
#include "Application.h"
#include "ModuleCar.h"

#include "ModuleResourceManager.h"
#include "ModuleGOManager.h"
#include "ComponentTransform.h"
#include "Editor.h"
#include "Assets.h"
#include "GameObject.h"
#include "RaycastHit.h"

#include "ModuleInput.h"

#include "glmath.h"

#include "imgui\imgui.h"

#define DISTANCE_FROM_GROUND 1

ModuleCar::ModuleCar(const char* name, bool start_enabled) : Module(name, start_enabled)
{
}

// Destructor
ModuleCar::~ModuleCar()
{
}

// Called before render is available
bool ModuleCar::Init(Data& config)
{
	bool ret = true;
	return ret;
}

bool ModuleCar::Start()
{
	return true;
}

// Called every draw update
update_status ModuleCar::PreUpdate()
{
	if (loaded == false)
	{
		FindKartGOs();

		if (kart == nullptr || kart_trs == nullptr)
		{
			AssetFile* kartFile = App->editor->assets->FindAssetFile("/Assets/kart.fbx");
			if (kartFile != nullptr)
			{
				App->resource_manager->LoadFile(kartFile->content_path, FileType::MESH);
			}
		}
		if (track == nullptr)
		{
			AssetFile* trackFile = App->editor->assets->FindAssetFile("/Assets/track_test.fbx");
			if (trackFile != nullptr)
			{
				App->resource_manager->LoadFile(trackFile->content_path, FileType::MESH);
			}
		}

		if (light == nullptr)
		{
			light = App->go_manager->CreateGameObject(NULL);
			light->name = "Directional_Light";
			light->AddComponent(ComponentType::C_LIGHT);
			ComponentTransform* tmp = (ComponentTransform*)light->GetComponent(C_TRANSFORM);
			tmp->SetRotation(float3(50, -10, -50));
		}
		if (cam != nullptr)
		{
			if (cam->GetComponent(C_CAMERA) == nullptr)
			{
				camera = (ComponentCamera*)cam->AddComponent(C_CAMERA);
			}
		}
		loaded = true;
	}

	return UPDATE_CONTINUE;
}

update_status ModuleCar::Update()
{
	if (App->IsGameRunning())
	{
		if (firstFrameOfExecution)
		{
			App->renderer3D->SetCamera(camera);
			firstFrameOfExecution = false;
		}

		Car_Debug_Ui();

		if (kart && kart_trs)
		{
			KartLogic();
		}
	}
	else
	{
		if (firstFrameOfExecution == false)
		{
			App->renderer3D->SetCamera(App->camera->GetEditorCamera());
			FindKartGOs();
			firstFrameOfExecution = true;
		}
	}
	return UPDATE_CONTINUE;
}

update_status ModuleCar::PostUpdate()
{
	return UPDATE_CONTINUE;
}

// Called before quitting
bool ModuleCar::CleanUp()
{
	return true;
}

void ModuleCar::KartLogic()
{
	float3 pos = kart_trs->GetPosition();
	float3 newPos = pos;
	float3 kartY = kart_trs->GetGlobalMatrix().WorldY();

	//Setting the two rays, Front and Back
	math::Ray rayF, rayB;
	rayB.dir = rayF.dir = -kartY;
	rayB.pos = rayF.pos = kart_trs->GetPosition() + kartY;
	rayF.pos += kart_trs->GetGlobalMatrix().WorldZ();
	rayB.pos -= kart_trs->GetGlobalMatrix().WorldZ();

	//Raycasting, checking only for the NavMesh layer
	RaycastHit hitF = App->go_manager->Raycast(rayF, std::vector<int>(1, track->layer));
	RaycastHit hitB = App->go_manager->Raycast(rayB, std::vector<int>(1, track->layer));

	//Setting the "desired up" value, taking in account if both rays are close enough to the ground or none of them
	float3 desiredUp = float3(0, 1, 0);
	onTheGround = false;
	if ((hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 1) && (hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 1))
	{
		onTheGround = true;
		desiredUp = hitF.normal.Lerp(hitB.normal, 0.5f);
		newPos = hitB.point + (hitF.point - hitB.point) / 2;
	}
	else if ((hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 0.8) && !(hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 0.8))
	{
		onTheGround = true;
		desiredUp = hitF.normal;
		if (hitB.object == nullptr)
		{
			newPos -= kart_trs->GetGlobalMatrix().WorldZ() * speed;
			speed = -speed / 4;
		}
	}
	else if (!(hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 0.8) && (hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 0.8))
	{
		onTheGround = true;
		desiredUp = hitB.normal;
		if (hitF.object == nullptr)
		{
			newPos -= kart_trs->GetGlobalMatrix().WorldZ() * speed;
			speed = -speed / 4;
		}
	}
	desiredUp.Normalize();

	if (desiredUp.AngleBetweenNorm(kartY) > DEGTORAD * 3.0f)
	{
		//Interpolating to obtain the desired rotation
		float3 nextStep;
		if (onTheGround)
		{
			nextStep = kartY.Lerp(desiredUp, 2.0f * time->DeltaTime());
		}
		else
		{
			nextStep = kartY.Lerp(desiredUp, (1.0f/recoveryTime) * time->DeltaTime());
		}
		Quat normal_rot = Quat::RotateFromTo(kart_trs->GetRotation().WorldY(), nextStep);
		kart_trs->Rotate(normal_rot);
	}

	//Manage Input to accelerate/brake. Returns acceleration
	if (onTheGround)
	{
		speed += AccelerationInput();
		speed = math::Clamp(speed, -maxSpeed, maxSpeed);
	}

	//Steering
	if (App->input->GetKey(SDL_SCANCODE_D) == KEY_REPEAT) { Steer(1); }
	if (App->input->GetKey(SDL_SCANCODE_A) == KEY_REPEAT) { Steer(-1); }
	Steer(App->input->GetJoystickAxis(0, JOY_AXIS::LEFT_STICK_X));

	//Returning steer to 0 gradually if the player isn't inputting anything
	if (steering == false)
	{
		AutoSteer();
	}
	steering = false;

	if (onTheGround)
	{
		float rotateAngle = maxSteer * math::Clamp(speed / (maxSpeed / 3), -1.0f, 1.0f) * currentSteer * time->DeltaTime();
		Quat tmp = kart_trs->GetRotation().RotateAxisAngle(kartY, -rotateAngle * DEGTORAD);
		kart_trs->Rotate(tmp);

		fallSpeed = 0.0f;
	}
	else
	{
		fallSpeed += CAR_GRAVITY * time->DeltaTime();
		newPos.y -= fallSpeed;
	}
#pragma region Esthetic_rotation_chasis_wheels
	ComponentTransform* chasis_trs = (ComponentTransform*)chasis->GetComponent(C_TRANSFORM);
	chasis_trs->SetRotation(float3(0, -currentSteer * 15 * math::Clamp(speed / (maxSpeed / 3), -1.0f, 1.0f), 0));

	ComponentTransform* wheel_trs = (ComponentTransform*)frontWheel->GetComponent(C_TRANSFORM);
	wheel_trs->SetRotation(float3(0, -currentSteer * 15, 0));
#pragma endregion

	newPos += kart_trs->GetGlobalMatrix().WorldZ() * speed;
	kart_trs->SetPosition(newPos);
}

float ModuleCar::AccelerationInput()
{
	float acceleration = 0.0f;
	if (App->input->GetKey(SDL_SCANCODE_W) == KEY_REPEAT || App->input->GetJoystickButton(0, JOY_BUTTON::A))
	{
		if (speed < -0.01f)
		{
			if (speed < -brakePower * time->DeltaTime())
			{
				acceleration += brakePower * time->DeltaTime();
			}
			else
			{
				speed = 0;
			}
		}
		else
		{
			acceleration += maxAcceleration * time->DeltaTime();
		}
	}
	else if (App->input->GetKey(SDL_SCANCODE_S) == KEY_REPEAT || App->input->GetJoystickButton(0, JOY_BUTTON::B))
	{
		if (speed > 0.01f)
		{
			if (speed > brakePower * time->DeltaTime())
			{
				acceleration -= brakePower * time->DeltaTime();
			}
			else
			{
				speed = 0;
			}
		}
		else
		{
			acceleration -= (maxAcceleration / 2.0f) * time->DeltaTime();
		}
	}
	else
	{
		if (speed > drag * time->DeltaTime())
		{
			acceleration = -drag * time->DeltaTime();
		}
		else if (speed < -drag * time->DeltaTime())
		{
			acceleration += drag * time->DeltaTime();
		}
		else
		{
			speed = 0;
		}
	}
	return acceleration;
}

void ModuleCar::Steer(float amount)
{
	amount = math::Clamp(amount, -1.0f, 1.0f);
	if (amount < -0.1 || amount > 0.1)
	{
		currentSteer += maneuverability * time->DeltaTime() * amount;
		amount = math::Abs(amount);
		currentSteer = math::Clamp(currentSteer, -amount, amount);
		steering = true;
	}
}

void ModuleCar::AutoSteer()
{
	if (currentSteer > maneuverability * time->DeltaTime())
	{
		currentSteer -= maneuverability * time->DeltaTime();
	}
	else if (currentSteer < -maneuverability * time->DeltaTime())
	{
		currentSteer += maneuverability * time->DeltaTime();
	}
	else { currentSteer = 0; }
}

void ModuleCar::Car_Debug_Ui()
{
	ImGui::SetNextWindowSize(ImVec2(350, 400));
	if (ImGui::Begin("Car_Debug"))
	{
		if (ImGui::Button("Set car cam"))
		{
			App->renderer3D->SetCamera(camera);
		}
		ImGui::SameLine();
		if (ImGui::Button("Set editor cam"))
		{
			App->renderer3D->SetCamera(App->camera->GetEditorCamera());
		}
		ImGui::NewLine();
		ImGui::Separator();

		ImGui::DragFloat("Max Speed", &maxSpeed, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Max Acceleration", &maxAcceleration, 0.01f, 0.01f, 20.0f);
		ImGui::DragFloat("Brake Power", &brakePower, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Maneuverability", &maneuverability, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Max Steer", &maxSteer, 1.0f, 0.0f, 300.0f);
		ImGui::DragFloat("Drag", &drag, 0.01f, 0.01f, 20.0f);
		ImGui::NewLine();
		ImGui::Separator();
		ImGui::Text("Just for display, do not touch");
		ImGui::DragFloat("Speed", &speed);
		ImGui::DragFloat("Current Steer", &currentSteer);
		ImGui::Checkbox("Steering", &steering);
		ImGui::NewLine();
		ImGui::Separator();
		ImGui::Text(tmpOutput);
		ImGui::End();
	}
}

void ModuleCar::FindKartGOs()
{
	kart = nullptr;
	chasis = nullptr;
	frontWheel = nullptr;
	backWheel = nullptr;
	cam = nullptr;
	track = nullptr;
	kart_trs = nullptr;
	camera = nullptr;
	light = nullptr;

	const vector<GameObject*>* rootChilds = App->go_manager->root->GetChilds();
	for (vector<GameObject*>::const_iterator it = rootChilds->cbegin(); it != rootChilds->cend(); it++)
	{
		if ((*it)->name == "pivot")
		{
			kart = *it;
			kart_trs = (ComponentTransform*)kart->GetComponent(ComponentType::C_TRANSFORM);
			const vector<GameObject*>* kartChilds = kart->GetChilds();
			for (vector<GameObject*>::const_iterator it = kartChilds->cbegin(); it != kartChilds->cend(); it++)
			{
				if ((*it)->name == "chasis")
				{
					chasis = *it;
					const vector<GameObject*>* chasisChilds = chasis->GetChilds();
					for (vector<GameObject*>::const_iterator it = chasisChilds->cbegin(); it != chasisChilds->cend(); it++)
					{
						if ((*it)->name == "F_wheel") {	frontWheel = *it; }
						else if ((*it)->name == "B_wheel") { backWheel = *it; }
					}
				}
				else if ((*it)->name == "camera")
				{
					cam = *it;
					camera = (ComponentCamera*) cam->GetComponent(C_CAMERA);
				}
			}
		}

		if ((*it)->name == "track_test")
		{
			track = *it;
			track->layer = 20;
		}
		if ((*it)->name == "Directional_Light")
		{
			light = *it;
		}
	}
}
<commit_msg>Added "not falling off" ray<commit_after>#include "Globals.h"
#include "Application.h"
#include "ModuleCar.h"

#include "ModuleResourceManager.h"
#include "ModuleGOManager.h"
#include "ComponentTransform.h"
#include "Editor.h"
#include "Assets.h"
#include "GameObject.h"
#include "RaycastHit.h"

#include "ModuleInput.h"

#include "glmath.h"

#include "imgui\imgui.h"

#define DISTANCE_FROM_GROUND 1

ModuleCar::ModuleCar(const char* name, bool start_enabled) : Module(name, start_enabled)
{
}

// Destructor
ModuleCar::~ModuleCar()
{
}

// Called before render is available
bool ModuleCar::Init(Data& config)
{
	bool ret = true;
	return ret;
}

bool ModuleCar::Start()
{
	return true;
}

// Called every draw update
update_status ModuleCar::PreUpdate()
{
	if (loaded == false)
	{
		FindKartGOs();

		if (kart == nullptr || kart_trs == nullptr)
		{
			AssetFile* kartFile = App->editor->assets->FindAssetFile("/Assets/kart.fbx");
			if (kartFile != nullptr)
			{
				App->resource_manager->LoadFile(kartFile->content_path, FileType::MESH);
			}
		}
		if (track == nullptr)
		{
			AssetFile* trackFile = App->editor->assets->FindAssetFile("/Assets/track_test.fbx");
			if (trackFile != nullptr)
			{
				App->resource_manager->LoadFile(trackFile->content_path, FileType::MESH);
			}
		}

		if (light == nullptr)
		{
			light = App->go_manager->CreateGameObject(NULL);
			light->name = "Directional_Light";
			light->AddComponent(ComponentType::C_LIGHT);
			ComponentTransform* tmp = (ComponentTransform*)light->GetComponent(C_TRANSFORM);
			tmp->SetRotation(float3(50, -10, -50));
		}
		if (cam != nullptr)
		{
			if (cam->GetComponent(C_CAMERA) == nullptr)
			{
				camera = (ComponentCamera*)cam->AddComponent(C_CAMERA);
			}
		}
		loaded = true;
	}

	return UPDATE_CONTINUE;
}

update_status ModuleCar::Update()
{
	if (App->IsGameRunning())
	{
		if (firstFrameOfExecution)
		{
			App->renderer3D->SetCamera(camera);
			firstFrameOfExecution = false;
		}

		Car_Debug_Ui();

		if (kart && kart_trs)
		{
			KartLogic();
		}
	}
	else
	{
		if (firstFrameOfExecution == false)
		{
			App->renderer3D->SetCamera(App->camera->GetEditorCamera());
			FindKartGOs();
			firstFrameOfExecution = true;
		}
	}
	return UPDATE_CONTINUE;
}

update_status ModuleCar::PostUpdate()
{
	return UPDATE_CONTINUE;
}

// Called before quitting
bool ModuleCar::CleanUp()
{
	return true;
}

void ModuleCar::KartLogic()
{
	float3 pos = kart_trs->GetPosition();
	float3 newPos = pos;
	float3 kartY = kart_trs->GetGlobalMatrix().WorldY();

	//Setting the two rays, Front and Back
	math::Ray rayF, rayB;
	rayB.dir = rayF.dir = -kartY;
	rayB.pos = rayF.pos = kart_trs->GetPosition() + kartY;
	rayF.pos += kart_trs->GetGlobalMatrix().WorldZ();
	rayB.pos -= kart_trs->GetGlobalMatrix().WorldZ();

	//Raycasting, checking only for the NavMesh layer
	RaycastHit hitF = App->go_manager->Raycast(rayF, std::vector<int>(1, track->layer));
	RaycastHit hitB = App->go_manager->Raycast(rayB, std::vector<int>(1, track->layer));

	//Setting the "desired up" value, taking in account if both rays are close enough to the ground or none of them
	float3 desiredUp = float3(0, 1, 0);
	onTheGround = false;
	if ((hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 1) && (hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 1))
	{
		onTheGround = true;
		desiredUp = hitF.normal.Lerp(hitB.normal, 0.5f);
		newPos = hitB.point + (hitF.point - hitB.point) / 2;
	}
	else if ((hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 0.8) && !(hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 0.8))
	{
		onTheGround = true;
		desiredUp = hitF.normal;
	}
	else if (!(hitF.object != nullptr && hitF.distance < DISTANCE_FROM_GROUND + 0.8) && (hitB.object != nullptr && hitB.distance < DISTANCE_FROM_GROUND + 0.8))
	{
		onTheGround = true;
		desiredUp = hitB.normal;
	}
	desiredUp.Normalize();

	//Checking if the kart is still on the track
	math::Ray rayN;
	rayN.dir = float3(0, -1, 0);
	rayN.pos = kart_trs->GetPosition() + float3(0, 1, 0);
	//Raycasting, checking only for the NavMesh layer
	RaycastHit hitN = App->go_manager->Raycast(rayN, std::vector<int>(1, track->layer));
	if (hitN.object == nullptr)
	{
		newPos -= kart_trs->GetGlobalMatrix().WorldZ() * speed;
		speed = -speed / 4;
	}

	if (desiredUp.AngleBetweenNorm(kartY) > DEGTORAD * 3.0f)
	{
		//Interpolating to obtain the desired rotation
		float3 nextStep;
		if (onTheGround)
		{
			nextStep = kartY.Lerp(desiredUp, 2.0f * time->DeltaTime());
		}
		else
		{
			nextStep = kartY.Lerp(desiredUp, (1.0f/recoveryTime) * time->DeltaTime());
		}
		Quat normal_rot = Quat::RotateFromTo(kart_trs->GetRotation().WorldY(), nextStep);
		kart_trs->Rotate(normal_rot);
	}

	//Manage Input to accelerate/brake. Returns acceleration
	if (onTheGround)
	{
		speed += AccelerationInput();
		speed = math::Clamp(speed, -maxSpeed, maxSpeed);
	}

	//Steering
	if (App->input->GetKey(SDL_SCANCODE_D) == KEY_REPEAT) { Steer(1); }
	if (App->input->GetKey(SDL_SCANCODE_A) == KEY_REPEAT) { Steer(-1); }
	Steer(App->input->GetJoystickAxis(0, JOY_AXIS::LEFT_STICK_X));

	//Returning steer to 0 gradually if the player isn't inputting anything
	if (steering == false)
	{
		AutoSteer();
	}
	steering = false;

	if (onTheGround)
	{
		float rotateAngle = maxSteer * math::Clamp(speed / (maxSpeed / 3), -1.0f, 1.0f) * currentSteer * time->DeltaTime();
		Quat tmp = kart_trs->GetRotation().RotateAxisAngle(kartY, -rotateAngle * DEGTORAD);
		kart_trs->Rotate(tmp);

		fallSpeed = 0.0f;
	}
	else
	{
		fallSpeed += CAR_GRAVITY * time->DeltaTime();
		newPos.y -= fallSpeed;
	}
#pragma region Esthetic_rotation_chasis_wheels
	ComponentTransform* chasis_trs = (ComponentTransform*)chasis->GetComponent(C_TRANSFORM);
	chasis_trs->SetRotation(float3(0, -currentSteer * 15 * math::Clamp(speed / (maxSpeed / 3), -1.0f, 1.0f), 0));

	ComponentTransform* wheel_trs = (ComponentTransform*)frontWheel->GetComponent(C_TRANSFORM);
	wheel_trs->SetRotation(float3(0, -currentSteer * 15, 0));
#pragma endregion

	newPos += kart_trs->GetGlobalMatrix().WorldZ() * speed;
	kart_trs->SetPosition(newPos);
}

float ModuleCar::AccelerationInput()
{
	float acceleration = 0.0f;
	if (App->input->GetKey(SDL_SCANCODE_W) == KEY_REPEAT || App->input->GetJoystickButton(0, JOY_BUTTON::A))
	{
		if (speed < -0.01f)
		{
			if (speed < -brakePower * time->DeltaTime())
			{
				acceleration += brakePower * time->DeltaTime();
			}
			else
			{
				speed = 0;
			}
		}
		else
		{
			acceleration += maxAcceleration * time->DeltaTime();
		}
	}
	else if (App->input->GetKey(SDL_SCANCODE_S) == KEY_REPEAT || App->input->GetJoystickButton(0, JOY_BUTTON::B))
	{
		if (speed > 0.01f)
		{
			if (speed > brakePower * time->DeltaTime())
			{
				acceleration -= brakePower * time->DeltaTime();
			}
			else
			{
				speed = 0;
			}
		}
		else
		{
			acceleration -= (maxAcceleration / 2.0f) * time->DeltaTime();
		}
	}
	else
	{
		if (speed > drag * time->DeltaTime())
		{
			acceleration = -drag * time->DeltaTime();
		}
		else if (speed < -drag * time->DeltaTime())
		{
			acceleration += drag * time->DeltaTime();
		}
		else
		{
			speed = 0;
		}
	}
	return acceleration;
}

void ModuleCar::Steer(float amount)
{
	amount = math::Clamp(amount, -1.0f, 1.0f);
	if (amount < -0.1 || amount > 0.1)
	{
		currentSteer += maneuverability * time->DeltaTime() * amount;
		amount = math::Abs(amount);
		currentSteer = math::Clamp(currentSteer, -amount, amount);
		steering = true;
	}
}

void ModuleCar::AutoSteer()
{
	if (currentSteer > maneuverability * time->DeltaTime())
	{
		currentSteer -= maneuverability * time->DeltaTime();
	}
	else if (currentSteer < -maneuverability * time->DeltaTime())
	{
		currentSteer += maneuverability * time->DeltaTime();
	}
	else { currentSteer = 0; }
}

void ModuleCar::Car_Debug_Ui()
{
	ImGui::SetNextWindowSize(ImVec2(350, 400));
	if (ImGui::Begin("Car_Debug"))
	{
		if (ImGui::Button("Set car cam"))
		{
			App->renderer3D->SetCamera(camera);
		}
		ImGui::SameLine();
		if (ImGui::Button("Set editor cam"))
		{
			App->renderer3D->SetCamera(App->camera->GetEditorCamera());
		}
		ImGui::NewLine();
		ImGui::Separator();

		ImGui::DragFloat("Max Speed", &maxSpeed, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Max Acceleration", &maxAcceleration, 0.01f, 0.01f, 20.0f);
		ImGui::DragFloat("Brake Power", &brakePower, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Maneuverability", &maneuverability, 0.1f, 0.1f, 20.0f);
		ImGui::DragFloat("Max Steer", &maxSteer, 1.0f, 0.0f, 300.0f);
		ImGui::DragFloat("Drag", &drag, 0.01f, 0.01f, 20.0f);
		ImGui::NewLine();
		ImGui::Separator();
		ImGui::Text("Just for display, do not touch");
		ImGui::DragFloat("Speed", &speed);
		ImGui::DragFloat("Current Steer", &currentSteer);
		ImGui::Checkbox("Steering", &steering);
		ImGui::NewLine();
		ImGui::Separator();
		ImGui::Text(tmpOutput);
		ImGui::End();
	}
}

void ModuleCar::FindKartGOs()
{
	kart = nullptr;
	chasis = nullptr;
	frontWheel = nullptr;
	backWheel = nullptr;
	cam = nullptr;
	track = nullptr;
	kart_trs = nullptr;
	camera = nullptr;
	light = nullptr;

	const vector<GameObject*>* rootChilds = App->go_manager->root->GetChilds();
	for (vector<GameObject*>::const_iterator it = rootChilds->cbegin(); it != rootChilds->cend(); it++)
	{
		if ((*it)->name == "pivot")
		{
			kart = *it;
			kart_trs = (ComponentTransform*)kart->GetComponent(ComponentType::C_TRANSFORM);
			const vector<GameObject*>* kartChilds = kart->GetChilds();
			for (vector<GameObject*>::const_iterator it = kartChilds->cbegin(); it != kartChilds->cend(); it++)
			{
				if ((*it)->name == "chasis")
				{
					chasis = *it;
					const vector<GameObject*>* chasisChilds = chasis->GetChilds();
					for (vector<GameObject*>::const_iterator it = chasisChilds->cbegin(); it != chasisChilds->cend(); it++)
					{
						if ((*it)->name == "F_wheel") {	frontWheel = *it; }
						else if ((*it)->name == "B_wheel") { backWheel = *it; }
					}
				}
				else if ((*it)->name == "camera")
				{
					cam = *it;
					camera = (ComponentCamera*) cam->GetComponent(C_CAMERA);
				}
			}
		}

		if ((*it)->name == "track_test")
		{
			track = *it;
			track->layer = 20;
		}
		if ((*it)->name == "Directional_Light")
		{
			light = *it;
		}
	}
}
<|endoftext|>


<commit_before>//#include <boost/bind.hpp>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/JointState.h>
#include <geometry_msgs/Twist.h>
#include <eklavya_gazebo_plugins/gazebo_ros_eklavya.h>
#include <ros/time.h>
#include "sensors/SensorManager.hh"
//#include "sensors/RaySensor.hh"
using namespace gazebo;

enum {LEFT= 0, RIGHT=1, FRONT_CASTOR_WHEEL=2, FRONT_CASTOR_SWIVEL=3};

GazeboRosEklavya::GazeboRosEklavya()
{
  this->spinner_thread_ = new boost::thread( boost::bind( &GazeboRosEklavya::spin, this) );

  wheel_speed_ = new float[2];
  wheel_speed_[LEFT] = 0.0;
  wheel_speed_[RIGHT] = 0.0;

  set_joints_[0] = false;
  set_joints_[1] = false;
  set_joints_[2] = false;
  set_joints_[3] = false;
  joints_[0].reset();
  joints_[1].reset();
  joints_[2].reset();
  joints_[3].reset();
}

GazeboRosEklavya::~GazeboRosEklavya()
{
   rosnode_->shutdown();
   this->spinner_thread_->join();
   delete this->spinner_thread_;
  delete [] wheel_speed_;
  delete rosnode_;
}

void GazeboRosEklavya::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf )
{
  this->my_world_ = _parent->GetWorld();

  this->my_parent_ = _parent;
  if (!this->my_parent_)
  {
    ROS_FATAL("Gazebo_ROS_Eklavya controller requires a Model as its parent");
    return;
  }

  this->node_namespace_ = "";
  if (_sdf->HasElement("node_namespace"))
    this->node_namespace_ = _sdf->GetElement("node_namespace")->GetValueString() + "/";

  left_wheel_joint_name_ = "left_wheel_joint";
  if (_sdf->HasElement("left_wheel_joint"))
    left_wheel_joint_name_ = _sdf->GetElement("left_wheel_joint")->GetValueString();

  right_wheel_joint_name_ = "right_wheel_joint";
  if (_sdf->HasElement("right_wheel_joint"))
    right_wheel_joint_name_ = _sdf->GetElement("right_wheel_joint")->GetValueString();

  front_castor_wheel_joint_name_ = "front_castor_wheel_joint";
  if (_sdf->HasElement("front_castor_wheel_joint"))
    front_castor_wheel_joint_name_ = _sdf->GetElement("front_castor_wheel_joint")->GetValueString();

  front_castor_swivel_joint_name_ = "front_castor_swivel_joint";
  if (_sdf->HasElement("front_castor_swivel_joint"))
    front_castor_swivel_joint_name_ = _sdf->GetElement("front_castor_swivel_joint")->GetValueString();

  wheel_sep_ = 0.34;
  if (_sdf->HasElement("wheel_separation"))
    wheel_sep_ = _sdf->GetElement("wheel_separation")->GetValueDouble();

  wheel_sep_ = 0.34;
  if (_sdf->HasElement("wheel_separation"))
    wheel_sep_ = _sdf->GetElement("wheel_separation")->GetValueDouble();

  wheel_diam_ = 0.15;
  if (_sdf->HasElement("wheel_diameter"))
    wheel_diam_ = _sdf->GetElement("wheel_diameter")->GetValueDouble();

  torque_ = 10.0;
  if (_sdf->HasElement("torque"))
    torque_ = _sdf->GetElement("torque")->GetValueDouble();

  // Get then name of the parent model
  std::string modelName = _sdf->GetParent()->GetValueString("name");

  // Listen to the update event. This event is broadcast every
  // simulation iteration.
  this->updateConnection = event::Events::ConnectWorldUpdateStart(
      boost::bind(&GazeboRosEklavya::UpdateChild, this));
  gzdbg << "plugin model name: " << modelName << "\n";

  if (!ros::isInitialized())
  {
    int argc = 0;
    char** argv = NULL;
    ros::init(argc, argv, "gazebo_eklavya", ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
  }

  rosnode_ = new ros::NodeHandle( node_namespace_ );

  cmd_vel_sub_ = rosnode_->subscribe("/cmd_vel", 1, &GazeboRosEklavya::OnCmdVel, this );
  odom_pub_ = rosnode_->advertise<nav_msgs::Odometry>("/odom", 1);

  joint_state_pub_ = rosnode_->advertise<sensor_msgs::JointState>("/joint_states", 1);

  js_.name.push_back( left_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( right_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( front_castor_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( front_castor_swivel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  prev_update_time_ = 0;
  last_cmd_vel_time_ = 0;

  //TODO: fix this

  joints_[LEFT] = my_parent_->GetJoint(left_wheel_joint_name_);
  joints_[RIGHT] = my_parent_->GetJoint(right_wheel_joint_name_);
  joints_[FRONT_CASTOR_WHEEL] = my_parent_->GetJoint(front_castor_wheel_joint_name_);
  joints_[FRONT_CASTOR_SWIVEL] = my_parent_->GetJoint(front_castor_swivel_joint_name_);

  if (joints_[LEFT]) set_joints_[LEFT] = true;
  if (joints_[RIGHT]) set_joints_[RIGHT] = true;
  if (joints_[FRONT_CASTOR_WHEEL]) set_joints_[FRONT_CASTOR_WHEEL] = true;
  if (joints_[FRONT_CASTOR_SWIVEL]) set_joints_[FRONT_CASTOR_SWIVEL] = true;

  //initialize time and odometry position
  prev_update_time_ = last_cmd_vel_time_ = this->my_world_->GetSimTime();
  odom_pose_[0] = 0.0;
  odom_pose_[1] = 0.0;
  odom_pose_[2] = 0.0;
}

void GazeboRosEklavya::UpdateChild()
{
  common::Time time_now = this->my_world_->GetSimTime();
  common::Time step_time = time_now - prev_update_time_;
  prev_update_time_ = time_now;

  double wd, ws;
  double d1, d2;
  double dr, da;

  wd = wheel_diam_;
  ws = wheel_sep_;

  d1 = d2 = 0;
  dr = da = 0;

  // Distance travelled by front wheels
  if (set_joints_[LEFT])
    d1 = step_time.Double() * (wd / 2) * joints_[LEFT]->GetVelocity(0);
  if (set_joints_[RIGHT])
    d2 = step_time.Double() * (wd / 2) * joints_[RIGHT]->GetVelocity(0);

  // Can see NaN values here, just zero them out if needed
  if (isnan(d1)) {
    ROS_WARN_THROTTLE(0.1, "Gazebo ROS Eklavya plugin. NaN in d1. Step time: %.2f. WD: %.2f. Velocity: %.2f", step_time.Double(), wd, joints_[LEFT]->GetVelocity(0));
    d1 = 0;
  }

  if (isnan(d2)) {
    ROS_WARN_THROTTLE(0.1, "Gazebo ROS Eklavya plugin. NaN in d2. Step time: %.2f. WD: %.2f. Velocity: %.2f", step_time.Double(), wd, joints_[RIGHT]->GetVelocity(0));
    d2 = 0;
  }

  dr = (d1 + d2) / 2;
  da = (d2 - d1) / ws;

  // Compute odometric pose
  odom_pose_[0] += dr * cos( odom_pose_[2] );
  odom_pose_[1] += dr * sin( odom_pose_[2] );
  odom_pose_[2] -= da;

  // Compute odometric instantaneous velocity
  odom_vel_[0] = dr / step_time.Double();
  odom_vel_[1] = 0.0;
  odom_vel_[2] = da / step_time.Double();

  if (set_joints_[LEFT])
  {
    joints_[LEFT]->SetVelocity( 0, wheel_speed_[LEFT] / (wd/2.0) );
    joints_[LEFT]->SetMaxForce( 0, torque_ );
  }
  if (set_joints_[RIGHT])
  {
    joints_[RIGHT]->SetVelocity( 0, wheel_speed_[RIGHT] / (wd / 2.0) );
    joints_[RIGHT]->SetMaxForce( 0, torque_ );
  }

  nav_msgs::Odometry odom;
  odom.header.stamp.sec = time_now.sec;
  odom.header.stamp.nsec = time_now.nsec;
  odom.header.frame_id = "odom";
  odom.child_frame_id = "base_footprint";
  odom.pose.pose.position.x = odom_pose_[0];
  odom.pose.pose.position.y = odom_pose_[1];
  odom.pose.pose.position.z = 0;

  btQuaternion qt;
  qt.setEuler(0,0,odom_pose_[2]);

  odom.pose.pose.orientation.x = qt.getX();
  odom.pose.pose.orientation.y = qt.getY();
  odom.pose.pose.orientation.z = qt.getZ();
  odom.pose.pose.orientation.w = qt.getW();

  double pose_cov[36] = { 1e-3, 0, 0, 0, 0, 0,
                          0, 1e-3, 0, 0, 0, 0,
                          0, 0, 1e6, 0, 0, 0,
                          0, 0, 0, 1e6, 0, 0,
                          0, 0, 0, 0, 1e6, 0,
                          0, 0, 0, 0, 0, 1e3};

  memcpy( &odom.pose.covariance[0], pose_cov, sizeof(double)*36 );
  memcpy( &odom.twist.covariance[0], pose_cov, sizeof(double)*36 );

  odom.twist.twist.linear.x = 0;
  odom.twist.twist.linear.y = 0;
  odom.twist.twist.linear.z = 0;

  odom.twist.twist.angular.x = 0;
  odom.twist.twist.angular.y = 0;
  odom.twist.twist.angular.z = 0;

  odom_pub_.publish( odom );

  js_.header.stamp.sec = time_now.sec;
  js_.header.stamp.nsec = time_now.nsec;
  if (this->set_joints_[LEFT])
  {
    js_.position[0] = joints_[LEFT]->GetAngle(0).GetAsRadian();
    js_.velocity[0] = joints_[LEFT]->GetVelocity(0);
  }

  if (this->set_joints_[RIGHT])
  {
    js_.position[1] = joints_[RIGHT]->GetAngle(0).GetAsRadian();
    js_.velocity[1] = joints_[RIGHT]->GetVelocity(0);
  }

  if (this->set_joints_[FRONT_CASTOR_WHEEL])
  {
    js_.position[2] = joints_[FRONT_CASTOR_WHEEL]->GetAngle(0).GetAsRadian();
    js_.velocity[2] = joints_[FRONT_CASTOR_WHEEL]->GetVelocity(0);
  }

  if (this->set_joints_[FRONT_CASTOR_SWIVEL])
  {
    js_.position[3] = joints_[FRONT_CASTOR_SWIVEL]->GetAngle(0).GetAsRadian();
    js_.velocity[3] = joints_[FRONT_CASTOR_SWIVEL]->GetVelocity(0);
  }

  joint_state_pub_.publish( js_ );

  //timeout if didn't receive cmd in a while
  common::Time time_since_last_cmd = time_now - last_cmd_vel_time_;
  if (time_since_last_cmd.Double() > 0.6)
  {
    wheel_speed_[LEFT] = 0;
    wheel_speed_[RIGHT] = 0;
  }

}

void GazeboRosEklavya::OnCmdVel( const geometry_msgs::TwistConstPtr &msg)
{
  last_cmd_vel_time_ = this->my_world_->GetSimTime();
  double vr, va;
  vr = msg->linear.x;
  va = msg->angular.z;

  wheel_speed_[LEFT] = vr - va * (wheel_sep_) / 2;
  wheel_speed_[RIGHT] = vr + va * (wheel_sep_) / 2;
}

void GazeboRosEklavya::spin()
{
  while(ros::ok()) ros::spinOnce();
}

GZ_REGISTER_MODEL_PLUGIN(GazeboRosEklavya);

<commit_msg>controller working great<commit_after>//#include <boost/bind.hpp>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/JointState.h>
#include <geometry_msgs/Twist.h>
#include <eklavya_gazebo_plugins/gazebo_ros_eklavya.h>
#include <ros/time.h>
#include "sensors/SensorManager.hh"
//#include "sensors/RaySensor.hh"
using namespace gazebo;

enum {LEFT= 0, RIGHT=1, FRONT_CASTOR_WHEEL=2, FRONT_CASTOR_SWIVEL=3};

GazeboRosEklavya::GazeboRosEklavya()
{
  this->spinner_thread_ = new boost::thread( boost::bind( &GazeboRosEklavya::spin, this) );

  wheel_speed_ = new float[2];
  wheel_speed_[LEFT] = 0.0;
  wheel_speed_[RIGHT] = 0.0;

  set_joints_[0] = false;
  set_joints_[1] = false;
  set_joints_[2] = false;
  set_joints_[3] = false;
  joints_[0].reset();
  joints_[1].reset();
  joints_[2].reset();
  joints_[3].reset();
}

GazeboRosEklavya::~GazeboRosEklavya()
{
   rosnode_->shutdown();
   this->spinner_thread_->join();
   delete this->spinner_thread_;
  delete [] wheel_speed_;
  delete rosnode_;
}

void GazeboRosEklavya::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf )
{
  this->my_world_ = _parent->GetWorld();

  this->my_parent_ = _parent;
  if (!this->my_parent_)
  {
    ROS_FATAL("Gazebo_ROS_Eklavya controller requires a Model as its parent");
    return;
  }

  this->node_namespace_ = "";
  if (_sdf->HasElement("node_namespace"))
    this->node_namespace_ = _sdf->GetElement("node_namespace")->GetValueString() + "/";

  left_wheel_joint_name_ = "left_wheel_joint";
  if (_sdf->HasElement("left_wheel_joint"))
    left_wheel_joint_name_ = _sdf->GetElement("left_wheel_joint")->GetValueString();

  right_wheel_joint_name_ = "right_wheel_joint";
  if (_sdf->HasElement("right_wheel_joint"))
    right_wheel_joint_name_ = _sdf->GetElement("right_wheel_joint")->GetValueString();

  front_castor_wheel_joint_name_ = "front_castor_wheel_joint";
  if (_sdf->HasElement("front_castor_wheel_joint"))
    front_castor_wheel_joint_name_ = _sdf->GetElement("front_castor_wheel_joint")->GetValueString();

  front_castor_swivel_joint_name_ = "front_castor_swivel_joint";
  if (_sdf->HasElement("front_castor_swivel_joint"))
    front_castor_swivel_joint_name_ = _sdf->GetElement("front_castor_swivel_joint")->GetValueString();

  wheel_sep_ = 0.34;
  if (_sdf->HasElement("wheel_separation"))
    wheel_sep_ = _sdf->GetElement("wheel_separation")->GetValueDouble();

  wheel_sep_ = 0.34;
  if (_sdf->HasElement("wheel_separation"))
    wheel_sep_ = _sdf->GetElement("wheel_separation")->GetValueDouble();

  wheel_diam_ = 0.15;
  if (_sdf->HasElement("wheel_diameter"))
    wheel_diam_ = _sdf->GetElement("wheel_diameter")->GetValueDouble();

  torque_ = 10.0;
  if (_sdf->HasElement("torque"))
    torque_ = _sdf->GetElement("torque")->GetValueDouble();

  // Get then name of the parent model
  std::string modelName = _sdf->GetParent()->GetValueString("name");

  // Listen to the update event. This event is broadcast every
  // simulation iteration.
  this->updateConnection = event::Events::ConnectWorldUpdateStart(
      boost::bind(&GazeboRosEklavya::UpdateChild, this));
  gzdbg << "plugin model name: " << modelName << "\n";

  if (!ros::isInitialized())
  {
    int argc = 0;
    char** argv = NULL;
    ros::init(argc, argv, "gazebo_eklavya", ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
  }

  rosnode_ = new ros::NodeHandle( node_namespace_ );

  cmd_vel_sub_ = rosnode_->subscribe("/cmd_vel", 1, &GazeboRosEklavya::OnCmdVel, this );
  odom_pub_ = rosnode_->advertise<nav_msgs::Odometry>("/odom", 1);

  joint_state_pub_ = rosnode_->advertise<sensor_msgs::JointState>("/joint_states", 1);

  js_.name.push_back( left_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( right_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( front_castor_wheel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  js_.name.push_back( front_castor_swivel_joint_name_ );
  js_.position.push_back(0);
  js_.velocity.push_back(0);
  js_.effort.push_back(0);

  prev_update_time_ = 0;
  last_cmd_vel_time_ = 0;

  //TODO: fix this

  joints_[LEFT] = my_parent_->GetJoint(left_wheel_joint_name_);
  joints_[RIGHT] = my_parent_->GetJoint(right_wheel_joint_name_);
  joints_[FRONT_CASTOR_WHEEL] = my_parent_->GetJoint(front_castor_wheel_joint_name_);
  joints_[FRONT_CASTOR_SWIVEL] = my_parent_->GetJoint(front_castor_swivel_joint_name_);

  if (joints_[LEFT]) set_joints_[LEFT] = true;
  if (joints_[RIGHT]) set_joints_[RIGHT] = true;
  if (joints_[FRONT_CASTOR_WHEEL]) set_joints_[FRONT_CASTOR_WHEEL] = true;
  if (joints_[FRONT_CASTOR_SWIVEL]) set_joints_[FRONT_CASTOR_SWIVEL] = true;

  //initialize time and odometry position
  prev_update_time_ = last_cmd_vel_time_ = this->my_world_->GetSimTime();
  odom_pose_[0] = 0.0;
  odom_pose_[1] = 0.0;
  odom_pose_[2] = 0.0;
}

void GazeboRosEklavya::UpdateChild()
{
  common::Time time_now = this->my_world_->GetSimTime();
  common::Time step_time = time_now - prev_update_time_;
  prev_update_time_ = time_now;

  double wd, ws;
  double d1, d2;
  double dr, da;

  wd = wheel_diam_;
  ws = wheel_sep_;

  d1 = d2 = 0;
  dr = da = 0;

  // Distance travelled by front wheels
  if (set_joints_[LEFT])
    d1 = step_time.Double() * (wd / 2) * joints_[LEFT]->GetVelocity(0);
  if (set_joints_[RIGHT])
    d2 = step_time.Double() * (wd / 2) * joints_[RIGHT]->GetVelocity(0);

  // Can see NaN values here, just zero them out if needed
  if (isnan(d1)) {
    ROS_WARN_THROTTLE(0.1, "Gazebo ROS Eklavya plugin. NaN in d1. Step time: %.2f. WD: %.2f. Velocity: %.2f", step_time.Double(), wd, joints_[LEFT]->GetVelocity(0));
    d1 = 0;
  }

  if (isnan(d2)) {
    ROS_WARN_THROTTLE(0.1, "Gazebo ROS Eklavya plugin. NaN in d2. Step time: %.2f. WD: %.2f. Velocity: %.2f", step_time.Double(), wd, joints_[RIGHT]->GetVelocity(0));
    d2 = 0;
  }

  dr = (d1 + d2) / 2;
  da = (d2 - d1) / ws;

  // Compute odometric pose
  odom_pose_[0] += dr * cos( odom_pose_[2] );
  odom_pose_[1] += dr * sin( odom_pose_[2] );
  odom_pose_[2] += da;

  // Compute odometric instantaneous velocity
  odom_vel_[0] = dr / step_time.Double();
  odom_vel_[1] = 0.0;
  odom_vel_[2] = da / step_time.Double();

  if (set_joints_[LEFT])
  {
    joints_[LEFT]->SetVelocity( 0, wheel_speed_[LEFT] / (wd/2.0) );
    joints_[LEFT]->SetMaxForce( 0, torque_ );
  }
  if (set_joints_[RIGHT])
  {
    joints_[RIGHT]->SetVelocity( 0, wheel_speed_[RIGHT] / (wd / 2.0) );
    joints_[RIGHT]->SetMaxForce( 0, torque_ );
  }
// getting data for base_footprint to odom transform
  math::Pose pose = this->my_parent_->GetState().GetPose();

  btQuaternion qt1(pose.rot.x, pose.rot.y, pose.rot.z, pose.rot.w);
 // btVector3 vt(pose.pos.x, pose.pos.y, pose.pos.z);

  //tf::Transform base_footprint_to_odom(qt1, vt);
 // transform_broadcaster_->sendTransform(tf::StampedTransform(base_footprint_to_odom,current_time,odom_frame,base_footprint_frame));
// publish odom topic
  nav_msgs::Odometry odom;
  odom.header.stamp.sec = time_now.sec;
  odom.header.stamp.nsec = time_now.nsec;
  odom.header.frame_id = "odom";
  odom.child_frame_id = "base_footprint";
  odom.pose.pose.position.x = pose.pos.x;//odom_pose_[0];
  odom.pose.pose.position.y = pose.pos.y;//odom_pose_[1];
  odom.pose.pose.position.z = 0;

  btQuaternion qt;
  qt.setEuler(0,0,odom_pose_[2]);

  odom.pose.pose.orientation.x = pose.rot.x;//qt.getX();
  odom.pose.pose.orientation.y = pose.rot.y;//qt.getY();
  odom.pose.pose.orientation.z = pose.rot.z;//qt.getZ();
  odom.pose.pose.orientation.w = pose.rot.w;//qt.getW();

  double pose_cov[36] = { 1e-3, 0, 0, 0, 0, 0,
                          0, 1e-3, 0, 0, 0, 0,
                          0, 0, 1e6, 0, 0, 0,
                          0, 0, 0, 1e6, 0, 0,
                          0, 0, 0, 0, 1e6, 0,
                          0, 0, 0, 0, 0, 1e3};

  memcpy( &odom.pose.covariance[0], pose_cov, sizeof(double)*36 );
  memcpy( &odom.twist.covariance[0], pose_cov, sizeof(double)*36 );

  odom.twist.twist.linear.x = 0;
  odom.twist.twist.linear.y = 0;
  odom.twist.twist.linear.z = 0;

  odom.twist.twist.angular.x = 0;
  odom.twist.twist.angular.y = 0;
  odom.twist.twist.angular.z = 0;

  odom_pub_.publish( odom );

  js_.header.stamp.sec = time_now.sec;
  js_.header.stamp.nsec = time_now.nsec;
  if (this->set_joints_[LEFT])
  {
    js_.position[0] = joints_[LEFT]->GetAngle(0).GetAsRadian();
    js_.velocity[0] = joints_[LEFT]->GetVelocity(0);
  }

  if (this->set_joints_[RIGHT])
  {
    js_.position[1] = joints_[RIGHT]->GetAngle(0).GetAsRadian();
    js_.velocity[1] = joints_[RIGHT]->GetVelocity(0);
  }

  if (this->set_joints_[FRONT_CASTOR_WHEEL])
  {
    js_.position[2] = joints_[FRONT_CASTOR_WHEEL]->GetAngle(0).GetAsRadian();
    js_.velocity[2] = joints_[FRONT_CASTOR_WHEEL]->GetVelocity(0);
  }

  if (this->set_joints_[FRONT_CASTOR_SWIVEL])
  {
    js_.position[3] = joints_[FRONT_CASTOR_SWIVEL]->GetAngle(0).GetAsRadian();
    js_.velocity[3] = joints_[FRONT_CASTOR_SWIVEL]->GetVelocity(0);
  }

  joint_state_pub_.publish( js_ );

  //timeout if didn't receive cmd in a while
  common::Time time_since_last_cmd = time_now - last_cmd_vel_time_;
  if (time_since_last_cmd.Double() > 0.6)
  {
    wheel_speed_[LEFT] = 0;
    wheel_speed_[RIGHT] = 0;
  }

}

void GazeboRosEklavya::OnCmdVel( const geometry_msgs::TwistConstPtr &msg)
{
  last_cmd_vel_time_ = this->my_world_->GetSimTime();
  double vr, va;
  vr = msg->linear.x;
  va = msg->angular.z;

  wheel_speed_[LEFT] = vr + va * (wheel_sep_) / 2;
  wheel_speed_[RIGHT] = vr - va * (wheel_sep_) / 2;
}

void GazeboRosEklavya::spin()
{
  while(ros::ok()) ros::spinOnce();
}

GZ_REGISTER_MODEL_PLUGIN(GazeboRosEklavya);

<|endoftext|>


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

#include "seasocks/StringUtil.h"

#include <cctype>
#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <cstring>

namespace seasocks {

char* skipWhitespace(char* str) {
    while (isspace(*str))
        ++str;
    return str;
}

char* skipNonWhitespace(char* str) {
    while (*str && !isspace(*str)) {
        ++str;
    }
    return str;
}

char* shift(char*& str) {
    if (str == nullptr) {
        return nullptr;
    }
    char* startOfWord = skipWhitespace(str);
    if (*startOfWord == 0) {
        str = startOfWord;
        return nullptr;
    }
    char* endOfWord = skipNonWhitespace(startOfWord);
    if (*endOfWord != 0) {
        *endOfWord++ = 0;
    }
    str = endOfWord;
    return startOfWord;
}

std::string trimWhitespace(const std::string& str) {
    auto* start = str.c_str();
    while (isspace(*start))
        ++start;
    auto* end = &str.back();
    while (end >= start && isspace(*end))
        --end;
    return std::string(start, end - start + 1);
}

std::string getLastError() {
    char errbuf[1024];
    const auto ignore = strerror_r(errno, errbuf, sizeof(errbuf));
    static_cast<void>(ignore);
    return errbuf;
}

std::string formatAddress(const sockaddr_in& address) {
    char ipBuffer[24];
    sprintf(ipBuffer,
            "%d.%d.%d.%d:%d",
            (address.sin_addr.s_addr >> 0) & 0xff,
            (address.sin_addr.s_addr >> 8) & 0xff,
            (address.sin_addr.s_addr >> 16) & 0xff,
            (address.sin_addr.s_addr >> 24) & 0xff,
            htons(address.sin_port));
    return ipBuffer;
}

std::vector<std::string> split(const std::string& input, char splitChar) {
    if (input.empty())
        return std::vector<std::string>();
    std::vector<std::string> result;
    size_t pos = 0;
    size_t newPos;
    while ((newPos = input.find(splitChar, pos)) != std::string::npos) {
        result.push_back(input.substr(pos, newPos - pos));
        pos = newPos + 1;
    }
    result.push_back(input.substr(pos));
    return result;
}

void replace(std::string& string, const std::string& find,
             const std::string& replace) {
    if (find.empty()) {
        return;
    }

    size_t pos = 0;
    const size_t findLen = find.length();
    const size_t replaceLen = replace.length();
    while ((pos = string.find(find, pos)) != std::string::npos) {
        string = string.substr(0, pos) + replace + string.substr(pos + findLen);
        pos += replaceLen;
    }
}

bool caseInsensitiveSame(const std::string& lhs, const std::string& rhs) {
    return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
}

std::string webtime(time_t time) {
    struct tm timeValue;
    gmtime_r(&time, &timeValue);
    char buf[1024];
    // Wed, 20 Apr 2011 17:31:28 GMT
    strftime(buf, sizeof(buf) - 1, "%a, %d %b %Y %H:%M:%S %Z", &timeValue);
    return buf;
}

std::string now() {
    return webtime(time(nullptr));
}

}
<commit_msg>Braces added to single line statements.<commit_after>// Copyright (c) 2013-2017, Matt Godbolt
// 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.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include "seasocks/StringUtil.h"

#include <cctype>
#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <cstring>

namespace seasocks {

char* skipWhitespace(char* str) {
    while (isspace(*str)) {
        ++str;
    }
    return str;
}

char* skipNonWhitespace(char* str) {
    while (*str && !isspace(*str)) {
        ++str;
    }
    return str;
}

char* shift(char*& str) {
    if (str == nullptr) {
        return nullptr;
    }
    char* startOfWord = skipWhitespace(str);
    if (*startOfWord == 0) {
        str = startOfWord;
        return nullptr;
    }
    char* endOfWord = skipNonWhitespace(startOfWord);
    if (*endOfWord != 0) {
        *endOfWord++ = 0;
    }
    str = endOfWord;
    return startOfWord;
}

std::string trimWhitespace(const std::string& str) {
    auto* start = str.c_str();
    while (isspace(*start)) {
        ++start;
    }
    auto* end = &str.back();
    while (end >= start && isspace(*end)) {
        --end;
    }
    return std::string(start, end - start + 1);
}

std::string getLastError() {
    char errbuf[1024];
    const auto ignore = strerror_r(errno, errbuf, sizeof(errbuf));
    static_cast<void>(ignore);
    return errbuf;
}

std::string formatAddress(const sockaddr_in& address) {
    char ipBuffer[24];
    sprintf(ipBuffer,
            "%d.%d.%d.%d:%d",
            (address.sin_addr.s_addr >> 0) & 0xff,
            (address.sin_addr.s_addr >> 8) & 0xff,
            (address.sin_addr.s_addr >> 16) & 0xff,
            (address.sin_addr.s_addr >> 24) & 0xff,
            htons(address.sin_port));
    return ipBuffer;
}

std::vector<std::string> split(const std::string& input, char splitChar) {
    if (input.empty()) {
        return {};
    }

    std::vector<std::string> result;
    size_t pos = 0;
    size_t newPos;
    while ((newPos = input.find(splitChar, pos)) != std::string::npos) {
        result.push_back(input.substr(pos, newPos - pos));
        pos = newPos + 1;
    }
    result.push_back(input.substr(pos));
    return result;
}

void replace(std::string& string, const std::string& find, const std::string& replace) {
    if (find.empty()) {
        return;
    }

    size_t pos = 0;
    const size_t findLen = find.length();
    const size_t replaceLen = replace.length();
    while ((pos = string.find(find, pos)) != std::string::npos) {
        string = string.substr(0, pos) + replace + string.substr(pos + findLen);
        pos += replaceLen;
    }
}

bool caseInsensitiveSame(const std::string& lhs, const std::string& rhs) {
    return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
}

std::string webtime(time_t time) {
    struct tm timeValue;
    gmtime_r(&time, &timeValue);
    char buf[1024];
    // Wed, 20 Apr 2011 17:31:28 GMT
    strftime(buf, sizeof(buf) - 1, "%a, %d %b %Y %H:%M:%S %Z", &timeValue);
    return buf;
}

std::string now() {
    return webtime(time(nullptr));
}

}
<|endoftext|>


<commit_before>// this file defines the itkBasicFiltersTest for the test driver
// and all it expects is that you have a function called RegisterTests
#include <iostream>
#include "itkTestMain.h"

void RegisterTests()
{
REGISTER_TEST(itkModifiedTimeTest );
REGISTER_TEST(itkAdaptorComparisonTest );
REGISTER_TEST(itkAffineTransformTest );
REGISTER_TEST(itkArrayTest );
REGISTER_TEST(itkArray2DTest );
REGISTER_TEST(itkAutoPointerTest );
REGISTER_TEST(itkAzimuthElevationToCartesianTransformTest );
REGISTER_TEST(itkBinaryThresholdImageFunctionTest );
REGISTER_TEST(itkBoundingBoxTest );
REGISTER_TEST(itkBSplineDeformableTransformTest );
REGISTER_TEST(itkBSplineInterpolationWeightFunctionTest );
REGISTER_TEST(itkBSplineKernelFunctionTest );
REGISTER_TEST(itkByteSwapTest );
REGISTER_TEST(itkCenteredRigid2DTransformTest );
REGISTER_TEST(itkCenteredAffineTransformTest );
REGISTER_TEST(itkConstNeighborhoodIteratorTest );
REGISTER_TEST(itkConstShapedNeighborhoodIteratorTest );
REGISTER_TEST(itkCovariantVectorGeometryTest );
REGISTER_TEST(itkDataTypeTest );
REGISTER_TEST(itkDynamicMeshTest );
REGISTER_TEST(itkEuler2DTransformTest );
REGISTER_TEST(itkEuler3DTransformTest );
REGISTER_TEST(itkExceptionObjectTest );
REGISTER_TEST(itkFixedArrayTest );
REGISTER_TEST(itkHashTableTest );
REGISTER_TEST(itkImageAdaptorTest );
REGISTER_TEST(itkImageIteratorTest );
REGISTER_TEST(itkImageIteratorsForwardBackwardTest );
REGISTER_TEST(itkImageIteratorWithIndexTest );
REGISTER_TEST(itkImageLinearIteratorTest );
REGISTER_TEST(itkImageRandomIteratorTest );
REGISTER_TEST(itkImageRegionTest );
REGISTER_TEST(itkImageRegionExclusionIteratorWithIndexTest );
REGISTER_TEST(itkImageReverseIteratorTest );
REGISTER_TEST(itkImageSliceIteratorTest );
REGISTER_TEST(itkIteratorTests );
REGISTER_TEST(itkLightObjectTest );
REGISTER_TEST(itkLevelSetFunctionTest );
REGISTER_TEST(itkMatrixTest );
REGISTER_TEST(itkMapContainerTest );
REGISTER_TEST(itkMeanImageFunctionTest );
REGISTER_TEST(itkMemoryLeakTest );
REGISTER_TEST(itkMeshTest );
REGISTER_TEST(itkMeshFstreamTest );
REGISTER_TEST(itkNeighborhoodTest );
REGISTER_TEST(itkNeighborhoodIteratorTest );
REGISTER_TEST(itkNeighborhoodOperatorTest );
REGISTER_TEST(itkNumericTraitsTest );
REGISTER_TEST(itkObjectStoreTest );
REGISTER_TEST(itkPeriodicBoundaryConditionTest );
REGISTER_TEST(itkPixelAccessTest );
REGISTER_TEST(itkPointGeometryTest );
REGISTER_TEST(itkPointSetTest );
REGISTER_TEST(itkRGBPixelTest );
REGISTER_TEST(itkRGBInterpolateImageFunctionTest );
REGISTER_TEST(itkRGBToVectorImageAdaptorTest );
REGISTER_TEST(itkRigid2DTransformTest );
REGISTER_TEST(itkRigid3DTransformTest );
REGISTER_TEST(itkRigid3DPerspectiveTransformTest );
REGISTER_TEST(itkScalarToRGBPixelFunctorTest );
REGISTER_TEST(itkShapedNeighborhoodIteratorTest );
REGISTER_TEST(itkSimilarity2DTransformTest );
REGISTER_TEST(itkSliceIteratorTest );
REGISTER_TEST(itkSpatialFunctionTest );
REGISTER_TEST(itkSmartPointerTest );
REGISTER_TEST(itkSTLContainerAdaptorTest );
REGISTER_TEST(itkTimeProbesTest );
REGISTER_TEST(itkTransformTest );
REGISTER_TEST(itkThreadDefsTest );
REGISTER_TEST(itkTranslationTransformTest );
REGISTER_TEST(itkVarianceImageFunctionTest );
REGISTER_TEST(itkVectorGeometryTest );
REGISTER_TEST(itkVersorTest );
REGISTER_TEST(itkVersorRigid3DTransformTest );
REGISTER_TEST(itkVectorTest );
REGISTER_TEST(itkVectorInterpolateImageFunctionTest );
REGISTER_TEST(itkVectorToRGBImageAdaptorTest );
REGISTER_TEST(itkScaleTransformTest );
REGISTER_TEST(itkSplineKernelTransformTest );
REGISTER_TEST(itkEllipsoidInteriorExteriorSpatialFunctionTest );
REGISTER_TEST(itkSymmetricEllipsoidInteriorExteriorSpatialFunctionTest );
REGISTER_TEST(itkSystemInformationTest );
REGISTER_TEST(itkMetaDataDictionaryTest );
REGISTER_TEST(itkSTLThreadTest );
}
<commit_msg>FIX: Unregistered itkSystemInformaitonTest because it is it's own executable.<commit_after>// this file defines the itkBasicFiltersTest for the test driver
// and all it expects is that you have a function called RegisterTests
#include <iostream>
#include "itkTestMain.h"

void RegisterTests()
{
REGISTER_TEST(itkModifiedTimeTest );
REGISTER_TEST(itkAdaptorComparisonTest );
REGISTER_TEST(itkAffineTransformTest );
REGISTER_TEST(itkArrayTest );
REGISTER_TEST(itkArray2DTest );
REGISTER_TEST(itkAutoPointerTest );
REGISTER_TEST(itkAzimuthElevationToCartesianTransformTest );
REGISTER_TEST(itkBinaryThresholdImageFunctionTest );
REGISTER_TEST(itkBoundingBoxTest );
REGISTER_TEST(itkBSplineDeformableTransformTest );
REGISTER_TEST(itkBSplineInterpolationWeightFunctionTest );
REGISTER_TEST(itkBSplineKernelFunctionTest );
REGISTER_TEST(itkByteSwapTest );
REGISTER_TEST(itkCenteredRigid2DTransformTest );
REGISTER_TEST(itkCenteredAffineTransformTest );
REGISTER_TEST(itkConstNeighborhoodIteratorTest );
REGISTER_TEST(itkConstShapedNeighborhoodIteratorTest );
REGISTER_TEST(itkCovariantVectorGeometryTest );
REGISTER_TEST(itkDataTypeTest );
REGISTER_TEST(itkDynamicMeshTest );
REGISTER_TEST(itkEuler2DTransformTest );
REGISTER_TEST(itkEuler3DTransformTest );
REGISTER_TEST(itkExceptionObjectTest );
REGISTER_TEST(itkFixedArrayTest );
REGISTER_TEST(itkHashTableTest );
REGISTER_TEST(itkImageAdaptorTest );
REGISTER_TEST(itkImageIteratorTest );
REGISTER_TEST(itkImageIteratorsForwardBackwardTest );
REGISTER_TEST(itkImageIteratorWithIndexTest );
REGISTER_TEST(itkImageLinearIteratorTest );
REGISTER_TEST(itkImageRandomIteratorTest );
REGISTER_TEST(itkImageRegionTest );
REGISTER_TEST(itkImageRegionExclusionIteratorWithIndexTest );
REGISTER_TEST(itkImageReverseIteratorTest );
REGISTER_TEST(itkImageSliceIteratorTest );
REGISTER_TEST(itkIteratorTests );
REGISTER_TEST(itkLightObjectTest );
REGISTER_TEST(itkLevelSetFunctionTest );
REGISTER_TEST(itkMatrixTest );
REGISTER_TEST(itkMapContainerTest );
REGISTER_TEST(itkMeanImageFunctionTest );
REGISTER_TEST(itkMemoryLeakTest );
REGISTER_TEST(itkMeshTest );
REGISTER_TEST(itkMeshFstreamTest );
REGISTER_TEST(itkNeighborhoodTest );
REGISTER_TEST(itkNeighborhoodIteratorTest );
REGISTER_TEST(itkNeighborhoodOperatorTest );
REGISTER_TEST(itkNumericTraitsTest );
REGISTER_TEST(itkObjectStoreTest );
REGISTER_TEST(itkPeriodicBoundaryConditionTest );
REGISTER_TEST(itkPixelAccessTest );
REGISTER_TEST(itkPointGeometryTest );
REGISTER_TEST(itkPointSetTest );
REGISTER_TEST(itkRGBPixelTest );
REGISTER_TEST(itkRGBInterpolateImageFunctionTest );
REGISTER_TEST(itkRGBToVectorImageAdaptorTest );
REGISTER_TEST(itkRigid2DTransformTest );
REGISTER_TEST(itkRigid3DTransformTest );
REGISTER_TEST(itkRigid3DPerspectiveTransformTest );
REGISTER_TEST(itkScalarToRGBPixelFunctorTest );
REGISTER_TEST(itkShapedNeighborhoodIteratorTest );
REGISTER_TEST(itkSimilarity2DTransformTest );
REGISTER_TEST(itkSliceIteratorTest );
REGISTER_TEST(itkSpatialFunctionTest );
REGISTER_TEST(itkSmartPointerTest );
REGISTER_TEST(itkSTLContainerAdaptorTest );
REGISTER_TEST(itkTimeProbesTest );
REGISTER_TEST(itkTransformTest );
REGISTER_TEST(itkThreadDefsTest );
REGISTER_TEST(itkTranslationTransformTest );
REGISTER_TEST(itkVarianceImageFunctionTest );
REGISTER_TEST(itkVectorGeometryTest );
REGISTER_TEST(itkVersorTest );
REGISTER_TEST(itkVersorRigid3DTransformTest );
REGISTER_TEST(itkVectorTest );
REGISTER_TEST(itkVectorInterpolateImageFunctionTest );
REGISTER_TEST(itkVectorToRGBImageAdaptorTest );
REGISTER_TEST(itkScaleTransformTest );
REGISTER_TEST(itkSplineKernelTransformTest );
REGISTER_TEST(itkEllipsoidInteriorExteriorSpatialFunctionTest );
REGISTER_TEST(itkSymmetricEllipsoidInteriorExteriorSpatialFunctionTest );
//This is a separate executable REGISTER_TEST(itkSystemInformationTest );
REGISTER_TEST(itkMetaDataDictionaryTest );
REGISTER_TEST(itkSTLThreadTest );
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
#include <list>
#include <fstream>
#include <vector>
#include "gnuplot_i.hpp"

#define GNUPLOT_PATH "C:/gnuplot/bin"

using namespace std;

double start, stop;
double h;
double (*funk)(double);

double simpson(double x1, double x2){ //Nie dziala
    double result;
    double I_Ti = h*(funk(x1)+funk(x2))/2;
    double I_Pi = h*funk(x1);
    //result = (1.0/3.0)*h*(funk(x1)+4*funk((x1+x2)/2)+funk(x2));
    //result = h*funk((x1+x2)/2);
    //result = I_Ti;
    result = (2.0/3.0)*I_Pi+(1.0/3.0)*I_Ti;
    result = abs(result);
    cout << "Simpson " << result << endl;
    return result;
}

double newton(){

    double integral = 0;
    double d =start;
    double buf = start;
    while(d<stop){
        double buf = d;
        d+=h;
        if(d>stop) break;
        integral+=simpson(buf,d);
    }

    integral+=simpson(buf,stop);
    return integral;
}

void wypiszWektor(vector<double> w){
    for(int i=0; i< w.size(); i++){
        cout << w[i] << " ";
    }

    cout << endl;
}

void wypiszWektor(vector<double> w, string opis){
    cout << "\n" << opis << ": ";
    wypiszWektor(w);
}

double sinus(double x){
    return sin(x);
}

double power(double base, double exp){
    return pow(base, exp);
}

double horner(double wsp[],int st, double x)
{
  if(st==0){
    return wsp[0];}
  return x*horner(wsp,st-1,x)+wsp[st];
}

double wielomianprosty(double a, double b, double c, double d, double x){
    return a*x*x*x -b*x*x +c*x -d;
}

double *wspolczynniki;
int stopien;

int main()
{
    Gnuplot::set_GNUPlotPath( GNUPLOT_PATH );

    cout << "Wybierz funkcje: \n1. Sinus\n2. Wykladnicza\n3. Wielomian \n4. Wielomian przykladowy \n> ";
    int wybor;

    cin >> wybor;

    switch(wybor){
    case 1:
        funk=sinus;
        break;
    case 2:
        funk=[](double x) -> double {return power(2,x);};
        break;
    case 3:
        cout<<"Podaj stopien wielomianu: ";
        cin>>stopien;
        wspolczynniki = new double [stopien+1];
        //wczytanie wspolczynnikow
        for(int i=0;i<=stopien;i++)
        {
          cout<<"Podaj wspolczynnik stojacy przy potedze "<<stopien-i<<": ";
          cin>>wspolczynniki[i];
        }
        funk=[](double x) -> double {return horner(wspolczynniki,stopien,x);};
        break;
    case 4:
        funk=[](double x) -> double {return wielomianprosty(2,3,2,1.05,x);};
        break;
    default:
        return 0;
    }

    cout << "Podaj poczatek i koniec przedzialu: ";
    cin >> start >> stop;

    Gnuplot main_plot;

    main_plot.set_title( "Wykres" );
    main_plot.set_xlabel( "X" );
    main_plot.set_ylabel( "Y" );

    main_plot.set_grid();
    main_plot.set_xrange( start , stop ) ;
    main_plot.set_yrange(-2,2);
    main_plot.set_style( "lines" );
    int precyzja = 10000;
    double skok = (stop-start)/precyzja;
    vector<double> x;
    vector<double> y;
    for(double d=start; d<=stop;d+=skok){
        x.push_back(d);
        y.push_back(funk(d));
    }

    main_plot.plot_xy( x, y, "Wykres funkcji." );

    cout << "Podaj dokladnosc calkowania: ";
    cin >> h;

    cout << newton() << endl;

    getchar();
    getchar();
    return 0;
}

<commit_msg>Przygotowanie na Czebyszewa.<commit_after>#include <iostream>
#include <cmath>
#include <list>
#include <fstream>
#include <vector>
#include "gnuplot_i.hpp"

#define GNUPLOT_PATH "C:/gnuplot/bin"

using namespace std;

double start, stop;
double h;
double (*funk)(double);
bool metodaNewt = true;

double simpson(double x1, double x2){ //Nie dziala
    double result;
    double I_Ti = h*(funk(x1)+funk(x2))/2;
    double I_Pi = h*funk(x1);
    //result = (1.0/3.0)*h*(funk(x1)+4*funk((x1+x2)/2)+funk(x2));
    //result = h*funk((x1+x2)/2);
    //result = I_Ti;
    result = (2.0/3.0)*I_Pi+(1.0/3.0)*I_Ti;
    result = abs(result);
    cout << "Simpson " << result << endl;
    return result;
}

double newton(){

    double integral = 0;
    double d =start;
    double buf = start;
    while(d<stop){
        double buf = d;
        d+=h;
        if(d>stop) break;
        integral+=simpson(buf,d);
    }

    integral+=simpson(buf,stop);
    return integral;
}

void wypiszWektor(vector<double> w){
    for(int i=0; i< w.size(); i++){
        cout << w[i] << " ";
    }

    cout << endl;
}

void wypiszWektor(vector<double> w, string opis){
    cout << "\n" << opis << ": ";
    wypiszWektor(w);
}

double sinus(double x){
    return sin(x);
}

double power(double base, double exp){
    return pow(base, exp);
}

double horner(double wsp[],int st, double x)
{
  if(st==0){
    return wsp[0];}
  return x*horner(wsp,st-1,x)+wsp[st];
}

double wielomianprosty(double a, double b, double c, double d, double x){
    return a*x*x*x -b*x*x +c*x -d;
}

double *wspolczynniki;
int stopien;

void wybierzFunk(){
    cout << "Wybierz funkcje: \n1. Sinus\n2. Wykladnicza\n3. Wielomian \n4. Wielomian przykladowy \n> ";
    int wybor;

    cin >> wybor;

    switch(wybor){
    case 1:
        funk=sinus;
        break;
    case 2:
        funk=[](double x) -> double {return power(2,x);};
        break;
    case 3:
        cout<<"Podaj stopien wielomianu: ";
        cin>>stopien;
        wspolczynniki = new double [stopien+1];
        //wczytanie wspolczynnikow
        for(int i=0;i<=stopien;i++)
        {
          cout<<"Podaj wspolczynnik stojacy przy potedze "<<stopien-i<<": ";
          cin>>wspolczynniki[i];
        }
        funk=[](double x) -> double {return horner(wspolczynniki,stopien,x);};
        break;
    case 4:
        funk=[](double x) -> double {return wielomianprosty(2,3,2,1.05,x);};
        break;
    default:
        throw string("Function not found");
    }
}

int main()
{
    Gnuplot::set_GNUPlotPath( GNUPLOT_PATH );

    try{
        wybierzFunk();
    } catch (string s){
        cout << s << endl;
        return 0;
    }

    {
        cout << "Wybierz metode: \n1. Newtona-Cotesa\n2. Gaussa-Czebyszewa\n> ";
        int wybor;

        cin >> wybor;
        if (wybor == 2) metodaNewt = false;
        else if (wybor != 1)
        {
            cout << "Method not found\n";
            return 0;
        }
    }

    if (metodaNewt)
    {
        cout << "Podaj poczatek i koniec przedzialu: ";
        cin >> start >> stop;

        Gnuplot main_plot;

        main_plot.set_title( "Wykres" );
        main_plot.set_xlabel( "X" );
        main_plot.set_ylabel( "Y" );

        main_plot.set_grid();
        main_plot.set_xrange( start , stop ) ;
        main_plot.set_yrange(-2,2);
        main_plot.set_style( "lines" );
        int precyzja = 10000;
        double skok = (stop-start)/precyzja;
        vector<double> x;
        vector<double> y;
        for(double d=start; d<=stop;d+=skok){
            x.push_back(d);
            y.push_back(funk(d));
        }

        main_plot.plot_xy( x, y, "Wykres funkcji." );

        cout << "Podaj dokladnosc calkowania: ";
        cin >> h;

        cout << newton() << endl;

        getchar();
        getchar();
    }
    else
    {
        cout << "To be done \n";
    }
    return 0;
}

<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <string>

#include <bh_config_parser.hpp>
#include <bh_ir.hpp>
#include <bh_opcode.h>
#include <bh_extmethod.hpp>
#include <jitk/statistics.hpp>

namespace bohrium {
namespace component {

class ComponentImpl; // Forward declaration

/** A Component in Bohrium is a shared library that implement a specific functionality.
 * Requirements:
 *  - A component must be compiled into a shared library e.g. .so, .dylib, or .dll.
 *
 *	- A component has to implement the ComponentImpl class; specifically,
 *	  the execute() method, which the Bridge calls when it wants to execute a BhIR,
 *	  and the extmethod() method, which the Bridge calls when it wants to register
 *	  a new extended method.
 *
 *  - A component has to implement two C compatible functions, create() and destroy(),
 *    which a parent component (or the bridge) can call to create or destroy an instance
 *    of the component. The ComponentFace class makes it easy for a parent to retrieve and
 *    use these two functions.
 */

/** Representation of a component interface */
class ComponentFace {
private:
    // Shared library handle, which is null when the component is uninitiated
    void *_lib_handle;

    // Pointer to the implementation of the component, which is null when the component is uninitiated
    ComponentImpl *_implementation;

    // Function pointer to the component's create function
    ComponentImpl *(*_create)(unsigned int);

    // Function pointer to the component's destroy function
    void (*_destroy)(ComponentImpl *component);

public:
    /** Constructor that takes the path to the shared library and the stack level of the component to interface
     *
     * @param lib_path    The path to the shared library of the component to interface
     * @param stack_level The stack level of the component of the component to interface
     */
    ComponentFace(const std::string &lib_path, int stack_level);

    /** Default constructor which create an uninitiated component interface */
    ComponentFace() : _lib_handle(nullptr), _implementation(nullptr){};

    // We only support the move assignment operator
    ComponentFace(const ComponentFace &other) = delete;
    ComponentFace(ComponentFace &&other) = delete;

    ~ComponentFace();

    /** Move constructor, which we need to make sure that `other` is left uninitiated */
    ComponentFace& operator=(ComponentFace&& other) {
        _lib_handle = other._lib_handle;
        _implementation = other._implementation;
        _create = other._create;
        _destroy = other._destroy;
        other._lib_handle = nullptr;
        other._implementation = nullptr;
        other._create = nullptr;
        other._destroy = nullptr;
        return *this;
    };

    virtual bool initiated() const;

    virtual void execute(BhIR *bhir);

    virtual void extmethod(const std::string &name, bh_opcode opcode);

    virtual std::string message(const std::string &msg);

    virtual void *getMemoryPointer(bh_base &base, bool copy2host, bool force_alloc, bool nullify);

    virtual void setMemoryPointer(bh_base *base, bool host_ptr, void *mem);

    virtual void *getDeviceContext();

    virtual void setDeviceContext(void *device_context);
};

// Representation of a component implementation, which is an abstract class
// that all Bohrium components should implement
class ComponentImpl {
protected:
    // Flag that indicate whether the component is enabled or disabled.
    // When disabled, the component should pass through instructions untouched to its child
    bool disabled = false;
public:

    // The level in the runtime stack starting a -1, which is the bridge,
    // 0 is the first component in the stack list, 1 is the second component etc.
    const int stack_level;
    // The configure file
    const ConfigParser config;

    // The interface of the child. Notice, the child might not exist i.e. `child.exist() == false`
    ComponentFace child;

    // Constructor
    ComponentImpl(int stack_level) : stack_level(stack_level), config(stack_level) {
        std::string child_lib_path = config.getChildLibraryPath();
        if (not child_lib_path.empty()) { // Has a child
            child = ComponentFace{ComponentImpl::config.getChildLibraryPath(), stack_level + 1};
        }
    }

    virtual ~ComponentImpl() {}; // NB: a destructor implementation must exist

    /** Execute a BhIR (graph of instructions)
     *
     * @bhir  The BhIR to execute
     * Throws exceptions on error
     */
    virtual void execute(BhIR *bhir) {
        child.execute(bhir);
    };

    /** Register a new extension method.
     *
     * @name   Name of the function
     * @opcode Opcode for the new function.
     * Throws exceptions on error
     */
    virtual void extmethod(const std::string &name, bh_opcode opcode) {
        child.extmethod(name, opcode);
    }

    /** Send and receive a message through the component stack
     *
     * @msg    The message to send
     * @return The received message
     * Throws exceptions on error
     */
    virtual std::string message(const std::string &msg) {
        return child.message(msg);
    }

    /** Get data pointer from the first VE in the runtime stack
     * NB: this doesn't include a flush
     *
     * @base         The base array that owns the data
     * @copy2host    Always copy the memory to main memory
     * @force_alloc  Force memory allocation
     * @nullify      Set the data pointer to NULL after returning
     * @return       The data pointer (NB: might point to device memory)
     * Throws exceptions on error
     */
    virtual void *getMemoryPointer(bh_base &base, bool copy2host, bool force_alloc, bool nullify) {
        return child.getMemoryPointer(base, copy2host, force_alloc, nullify);
    }

    /** Set data pointer in the first VE in the runtime stack
     * NB: The component will deallocate the memory when encountering a BH_FREE.
     *     Also, this doesn't include a flush
     *
     * @base      The base array that will own the data
     * @host_ptr  The pointer points to the host memory (main memory) as opposed to device memory
     * @mem       The data pointer
     * Throws exceptions on error
     */
    virtual void setMemoryPointer(bh_base *base, bool host_ptr, void *mem) {
        return child.setMemoryPointer(base, host_ptr, mem);
    }

    /** Get the device handle, such as OpenCL's cl_context, of the first VE in the runtime stack.
     * If the first VE isn't a device, NULL is returned.
     *
     * @return  The device handle
     * Throws exceptions on error
     */
    virtual void *getDeviceContext() {
        return child.getDeviceContext();
    }

    /** Set the device context, such as CUDA's context, of the first VE in the runtime stack.
     * If the first VE isn't a device, nothing happens
     *
     * @device_context  The new device context
     * Throws exceptions on error
     */
    virtual void setDeviceContext(void *device_context) {
        child.setDeviceContext(device_context);
    }
};

// Representation of a vector engine component
// All vector engines should inherit from this class
class ComponentVE : public ComponentImpl {
public:
    // Known extension methods
    std::map<bh_opcode, extmethod::ExtmethodFace> extmethods;

    // The child's known extension methods
    std::set<bh_opcode> child_extmethods;

    // Trivial constructor
    ComponentVE(int stack_level) : ComponentImpl(stack_level) {}
};

}} //namespace bohrium::component
<commit_msg>component: now takes the initiate_child argument<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <string>

#include <bh_config_parser.hpp>
#include <bh_ir.hpp>
#include <bh_opcode.h>
#include <bh_extmethod.hpp>
#include <jitk/statistics.hpp>

namespace bohrium {
namespace component {

class ComponentImpl; // Forward declaration

/** A Component in Bohrium is a shared library that implement a specific functionality.
 * Requirements:
 *  - A component must be compiled into a shared library e.g. .so, .dylib, or .dll.
 *
 *	- A component has to implement the ComponentImpl class; specifically,
 *	  the execute() method, which the Bridge calls when it wants to execute a BhIR,
 *	  and the extmethod() method, which the Bridge calls when it wants to register
 *	  a new extended method.
 *
 *  - A component has to implement two C compatible functions, create() and destroy(),
 *    which a parent component (or the bridge) can call to create or destroy an instance
 *    of the component. The ComponentFace class makes it easy for a parent to retrieve and
 *    use these two functions.
 */

/** Representation of a component interface */
class ComponentFace {
private:
    // Shared library handle, which is null when the component is uninitiated
    void *_lib_handle;

    // Pointer to the implementation of the component, which is null when the component is uninitiated
    ComponentImpl *_implementation;

    // Function pointer to the component's create function
    ComponentImpl *(*_create)(unsigned int);

    // Function pointer to the component's destroy function
    void (*_destroy)(ComponentImpl *component);

public:
    /** Constructor that takes the path to the shared library and the stack level of the component to interface
     *
     * @param lib_path    The path to the shared library of the component to interface
     * @param stack_level The stack level of the component of the component to interface
     */
    ComponentFace(const std::string &lib_path, int stack_level);

    /** Default constructor which create an uninitiated component interface */
    ComponentFace() : _lib_handle(nullptr), _implementation(nullptr) {};

    // We only support the move assignment operator
    ComponentFace(const ComponentFace &other) = delete;

    ComponentFace(ComponentFace &&other) = delete;

    ~ComponentFace();

    /** Move constructor, which we need to make sure that `other` is left uninitiated */
    ComponentFace &operator=(ComponentFace &&other) {
        _lib_handle = other._lib_handle;
        _implementation = other._implementation;
        _create = other._create;
        _destroy = other._destroy;
        other._lib_handle = nullptr;
        other._implementation = nullptr;
        other._create = nullptr;
        other._destroy = nullptr;
        return *this;
    };

    virtual bool initiated() const;

    virtual void execute(BhIR *bhir);

    virtual void extmethod(const std::string &name, bh_opcode opcode);

    virtual std::string message(const std::string &msg);

    virtual void *getMemoryPointer(bh_base &base, bool copy2host, bool force_alloc, bool nullify);

    virtual void setMemoryPointer(bh_base *base, bool host_ptr, void *mem);

    virtual void *getDeviceContext();

    virtual void setDeviceContext(void *device_context);
};

// Representation of a component implementation, which is an abstract class
// that all Bohrium components should implement
class ComponentImpl {
protected:
    // Flag that indicate whether the component is enabled or disabled.
    // When disabled, the component should pass through instructions untouched to its child
    bool disabled = false;
public:

    // The level in the runtime stack starting a -1, which is the bridge,
    // 0 is the first component in the stack list, 1 is the second component etc.
    const int stack_level;
    // The configure file
    const ConfigParser config;

    // The interface of the child. Notice, the child might not exist i.e. `child.exist() == false`
    ComponentFace child;

    /** Constructor for a new component
     *
     * @param stack_level     The stack level of the new component
     * @param initiate_child  Flag: initiate the child (if any)
     */
    explicit ComponentImpl(int stack_level, bool initiate_child = true) : stack_level(stack_level),
                                                                          config(stack_level) {
        std::string child_lib_path = config.getChildLibraryPath();
        if (initiate_child and not child_lib_path.empty()) { // Has a child
            child = ComponentFace{ComponentImpl::config.getChildLibraryPath(), stack_level + 1};
        }
    }

    virtual ~ComponentImpl() = default; // NB: a destructor implementation must exist

    /** Execute a BhIR (graph of instructions)
     *
     * @bhir  The BhIR to execute
     * Throws exceptions on error
     */
    virtual void execute(BhIR *bhir) {
        child.execute(bhir);
    };

    /** Register a new extension method.
     *
     * @name   Name of the function
     * @opcode Opcode for the new function.
     * Throws exceptions on error
     */
    virtual void extmethod(const std::string &name, bh_opcode opcode) {
        child.extmethod(name, opcode);
    }

    /** Send and receive a message through the component stack
     *
     * @msg    The message to send
     * @return The received message
     * Throws exceptions on error
     */
    virtual std::string message(const std::string &msg) {
        return child.message(msg);
    }

    /** Get data pointer from the first VE in the runtime stack
     * NB: this doesn't include a flush
     *
     * @base         The base array that owns the data
     * @copy2host    Always copy the memory to main memory
     * @force_alloc  Force memory allocation
     * @nullify      Set the data pointer to NULL after returning
     * @return       The data pointer (NB: might point to device memory)
     * Throws exceptions on error
     */
    virtual void *getMemoryPointer(bh_base &base, bool copy2host, bool force_alloc, bool nullify) {
        return child.getMemoryPointer(base, copy2host, force_alloc, nullify);
    }

    /** Set data pointer in the first VE in the runtime stack
     * NB: The component will deallocate the memory when encountering a BH_FREE.
     *     Also, this doesn't include a flush
     *
     * @base      The base array that will own the data
     * @host_ptr  The pointer points to the host memory (main memory) as opposed to device memory
     * @mem       The data pointer
     * Throws exceptions on error
     */
    virtual void setMemoryPointer(bh_base *base, bool host_ptr, void *mem) {
        return child.setMemoryPointer(base, host_ptr, mem);
    }

    /** Get the device handle, such as OpenCL's cl_context, of the first VE in the runtime stack.
     * If the first VE isn't a device, NULL is returned.
     *
     * @return  The device handle
     * Throws exceptions on error
     */
    virtual void *getDeviceContext() {
        return child.getDeviceContext();
    }

    /** Set the device context, such as CUDA's context, of the first VE in the runtime stack.
     * If the first VE isn't a device, nothing happens
     *
     * @device_context  The new device context
     * Throws exceptions on error
     */
    virtual void setDeviceContext(void *device_context) {
        child.setDeviceContext(device_context);
    }
};

// Representation of a vector engine component
// All vector engines should inherit from this class
class ComponentVE : public ComponentImpl {
public:
    // Known extension methods
    std::map<bh_opcode, extmethod::ExtmethodFace> extmethods;

    // The child's known extension methods
    std::set<bh_opcode> child_extmethods;

    // Trivial constructor
    ComponentVE(int stack_level) : ComponentImpl(stack_level) {}
};

}
} //namespace bohrium::component
<|endoftext|>