[go: up one dir, main page]

Menu

[8286ad]: / body / Suspension.cpp  Maximize  Restore  History

Download this file

140 lines (124 with data), 5.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// 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 "Suspension.hpp"
#include "Wheel.hpp"
#include "../geometry/Constants.hpp"
#include "../geometry/Numeric.hpp"
#include "../media/Ac3d.hpp"
#include <cassert>
using namespace Vamos_Body;
using namespace Vamos_Geometry;
// Note that all angles are stored as right-hand rotations. As a result, m_camber for a
// wheel on the right side of the car follows the common convention that positive camber
// means that the wheel leans away from the centerline. For the wheel on the left,
// m_camber is contrary to convention.
//----------------------------------------------------------------------------------------
Suspension::Suspension(const Three_Vector& position,
Direction side_of_car, bool is_steered,
double camber, double caster, double toe,
double spring_constant, double bounce, double rebound, double travel,
double max_compression_velocity, std::shared_ptr<Wheel> wheel)
: Particle(0.0, position),
m_side(side_of_car),
m_is_steered(is_steered),
m_spring_constant(spring_constant),
m_bounce(bounce),
m_rebound(rebound),
m_travel(travel),
m_max_compression_velocity(max_compression_velocity),
mp_wheel(wheel)
{
auto symmetric_angle = [side_of_car](double degrees) {
return deg_to_rad(side_of_car == LEFT ? -1.0 : 1.0);
};
mp_wheel->rotate(Three_Vector::X * symmetric_angle(camber));
mp_wheel->rotate(Three_Vector::Y * deg_to_rad(caster)); // Same sign on both sides.
mp_wheel->rotate(Three_Vector::Z * symmetric_angle(toe));
m_static_position = mp_wheel->position();
m_static_orientation = mp_wheel->orientation();
}
void Suspension::propagate(double time)
{
// Set the wheel's position and orientation.
mp_wheel->set_position(m_static_position);
mp_wheel->set_orientation(m_static_orientation);
// Steering is about the wheel's z-axis.
mp_wheel->rotate(Three_Vector::Z * m_steer_angle);
mp_wheel->propagate(time);
if (m_displacement <= 0.0)
return reset();
// Get the suspension force to apply to the chassis.
double d = mp_wheel->displacement();
double spring_force = m_spring_constant * d;
double v = mp_wheel->velocity().z;
double damp = v > 0.0 ? m_bounce : m_rebound;
double damp_force = damp * v;
double anti_roll_force = m_anti_roll_suspension ?
m_anti_roll_k * (d - m_anti_roll_suspension->mp_wheel->displacement()) : 0.0;
//!! Apply the wheel's force in z.
//!! Apply the wheel's force and impulse in x-y.
m_force = rotate_out((spring_force + damp_force + anti_roll_force) * Three_Vector::Z
+ mp_wheel->force());
//!! Torque should be applied at the hub.
m_torque = rotate_out(mp_wheel->torque());
//!!Orient the hinge, set the force to the component of tire force in the x-y plane.
}
void Suspension::anti_roll(Suspension* other, double spring_constant)
{
m_anti_roll_suspension = other;
m_anti_roll_k = spring_constant;
m_anti_roll_suspension->m_anti_roll_suspension = this;
m_anti_roll_suspension->m_anti_roll_k = m_anti_roll_k;
}
void Suspension::steer(double degree_angle)
{
if (m_is_steered)
m_steer_angle = deg_to_rad(degree_angle);
}
void Suspension::reset()
{
Particle::reset();
mp_wheel->set_position(m_static_position);
mp_wheel->set_orientation(m_static_orientation);
}
void Suspension::set_model(std::string file_name, double scale, const Three_Vector& translation,
const Three_Vector& rotation)
{
auto position = translation;
auto orientation = rotation;
if (m_side == LEFT)
{
// Make the right and left sides symmetric.
position.y *= -1.0;
orientation.x *= -1.0;
orientation.y *= -1.0;
}
auto model = Vamos_Media::Ac3d(file_name, scale, Three_Vector(), orientation);
m_models.emplace_back(Suspension_Model{model.build(), position});
}
void Suspension::draw()
{
for (const auto& model : m_models)
{
glPushMatrix();
double d = mp_wheel->displacement();
glTranslatef(position().x + model.position.x, position().y + model.position.y,
position().z + model.position.z - d);
double angle = rad_to_deg(std::atan2(-d, model.position.y));
glRotatef(angle, 1.0, 0.0, 0.0);
glCallList(model.display_list);
glPopMatrix();
}
}