// A gearbox for the drivetrain.
//
// Copyright (C) 2001-2019 Sam Varner
//
// This file is part of Vamos Automotive Simulator.
//
// Vamos is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vamos is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vamos. If not, see <http://www.gnu.org/licenses/>.
#include "Transmission.hpp"
#include <cassert>
using namespace Vamos_Body;
Transmission::Transmission(int forward_gears, double first_ratio, double last_ratio)
: m_forward_gears(forward_gears),
m_reverse_gears(1)
{
assert(forward_gears > 1);
// Add gears with equally spaced inverse ratios.
double first_inv = 1.0 / first_ratio;
double last_inv = 1.0 / last_ratio;
double increment = (first_inv - last_inv) / (forward_gears - 1);
m_gear_ratios[0] = 0.0;
for (int i = 1; i <= forward_gears; ++i)
m_gear_ratios[i] = 1.0 / (first_inv - increment * i);
// Put the ratio for reverse midway between first and second.
m_gear_ratios[-1] = -0.5 * (m_gear_ratios[1] + m_gear_ratios[2]);
}
Transmission::Transmission(const std::vector<std::pair<int, double>>& gears)
: m_forward_gears(0), m_reverse_gears(0)
{
for (auto gear : gears)
m_gear_ratios.insert(gear);
m_gear_ratios[0] = 0.0;
// Count the consecutive forward and reverse gears.
for (int key = 1; m_gear_ratios.count(key) == 1; ++key)
++m_forward_gears;
for (int key = -1; m_gear_ratios.count(key) == 1; ++key)
++m_reverse_gears;
}
void Transmission::shift(int gear)
{
assert(m_gear_ratios.count(gear) == 1);
m_gear = gear;
}
double Transmission::get_gear_ratio(int gear) const
{
assert(m_gear_ratios.count(gear) == 1);
return m_gear_ratios.at(gear);
}
double Transmission::get_torque(double drag) const
{
return drag * m_gear_ratios.at(m_gear);
}
int Transmission::get_gear() const
{
return m_gear;
}
int Transmission::num_forward_gears() const
{
return m_forward_gears;
}
int Transmission::num_reverse_gears() const
{
return m_reverse_gears;
}
void Transmission::set_driveshaft_speed(double driveshaft_speed)
{
m_clutch_speed = driveshaft_speed * m_gear_ratios[m_gear];
}
double Transmission::get_clutch_speed() const
{
return m_clutch_speed;
}