CARLA
AckermannController.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
7 #include "AckermannController.h"
8 #include "CarlaWheeledVehicle.h"
9 
10 // =============================================================================
11 // -- Constructor and destructor -----------------------------------------------
12 // =============================================================================
13 
15 
16 // =============================================================================
17 // -- FAckermannController -----------------------------------------------------
18 // =============================================================================
19 
22 
23  Settings.SpeedKp = SpeedController.Kp;
24  Settings.SpeedKi = SpeedController.Ki;
25  Settings.SpeedKd = SpeedController.Kd;
26 
30 
31  return Settings;
32 }
33 
35  SpeedController.Kp = Settings.SpeedKp;
36  SpeedController.Ki = Settings.SpeedKi;
37  SpeedController.Kd = Settings.SpeedKd;
38 
42 }
43 
45  UserTargetPoint = AckermannControl;
46 
51  TargetJerk = FMath::Abs(UserTargetPoint.Jerk);
52 
53 }
54 
56  // Reset controllers
59 
60  // Reset control parameters
61  Steer = 0.0f;
62  Throttle = 0.0f;
63  Brake = 0.0f;
64  bReverse = false;
65 
68 
71 
72  // Reset vehicle state
73  VehicleSpeed = 0.0f;
74  VehicleAcceleration = 0.0f;
75 
76  LastVehicleSpeed = 0.0f;
78 }
79 
81  TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
82 
83  // Lateral Control
85 
86  // Longitudinal Control
87  bool bStopped = RunControlFullStop();
88  if (!bStopped) {
93  }
94 
95  // Update control command
96  Control.Steer = Steer / VehicleMaxSteering;
97  Control.Throttle = FMath::Clamp(Throttle, 0.0f, 1.0f);
98  Control.Brake = FMath::Clamp(Brake, 0.0f, 1.0f);
99  Control.bReverse = bReverse;
100 }
101 
103  if (FMath::Abs(TargetSteerSpeed) < 0.001) {
104  Steer = TargetSteer;
105  } else {
106  float SteerDelta = TargetSteerSpeed * DeltaTime;
107  if (FMath::Abs(TargetSteer - VehicleSteer) < SteerDelta) {
108  Steer = TargetSteer;
109  } else {
110  float SteerDirection = (TargetSteer > VehicleSteer) ? 1.0f : -1.0f;
111  Steer = VehicleSteer + SteerDirection * (TargetSteerSpeed * DeltaTime);
112  }
113 
114  }
115 }
116 
118  // From this velocity on full brake is turned on
119  float FullStopEpsilon = 0.1; //[m/s]
120 
121  if (FMath::Abs(VehicleSpeed) < FullStopEpsilon && FMath::Abs(UserTargetPoint.Speed) < FullStopEpsilon) {
122  Brake = 1.0;
123  Throttle = 0.0;
124  return true;
125  }
126  return false;
127 }
128 
130  // From this position on it is allowed to switch to reverse gear
131  float StandingStillEpsilon = 0.1; // [m/s]
132 
133  if (FMath::Abs(VehicleSpeed) < StandingStillEpsilon) {
134  // Standing still, change of driving direction allowed
135  if (UserTargetPoint.Speed < 0) {
136  // Change of driving direction to reverse.
137  bReverse = true;
138  } else if (UserTargetPoint.Speed >= 0) {
139  // Change of driving direction to forward.
140  bReverse = false;
141  }
142  } else {
143  if (FMath::Sign(VehicleSpeed) * FMath::Sign(UserTargetPoint.Speed) == -1) {
144  // Requested for change of driving direction.
145  // First we have to come to full stop before changing driving direction
146  TargetSpeed = 0.0;
147  }
148  }
149 
150 }
151 
155 
156  // Clipping borders
157  float ClippingLowerBorder = -FMath::Abs(TargetAcceleration);
158  float ClippingUpperBorder = FMath::Abs(TargetAcceleration);
159  if (FMath::Abs(TargetAcceleration) < 0.0001f) {
160  // Per definition of AckermannDrive: if zero, then use max value
161  ClippingLowerBorder = -MaxDecel;
162  ClippingUpperBorder = MaxAccel;
163  }
166  ClippingLowerBorder, ClippingUpperBorder);
167 }
168 
172 
173  // Clipping borders
175  AccelControlPedalTarget = FMath::Clamp(AccelControlPedalTarget, -1.0f, 1.0f);
176 
177 }
178 
180 
181  if (AccelControlPedalTarget < 0.0f) {
182  if (bReverse) {
183  Throttle = FMath::Abs(AccelControlPedalTarget);
184  Brake = 0.0f;
185  } else {
186  Throttle = 0.0f;
187  Brake = FMath::Abs(AccelControlPedalTarget);
188  }
189  } else {
190  if (bReverse) {
191  Throttle = 0.0f;
192  Brake = FMath::Abs(AccelControlPedalTarget);
193  } else {
194  Throttle = FMath::Abs(AccelControlPedalTarget);
195  Brake = 0.0f;
196  }
197  }
198 }
199 
201  TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
202 
205 
206  // Update simulation state
207  DeltaTime = Vehicle->GetWorld()->GetDeltaSeconds();
208 
209  // Update Vehicle state
211  VehicleSpeed = Vehicle->GetVehicleForwardSpeed() / 100.0f; // From cm/s to m/s
212  float CurrentAcceleration = (VehicleSpeed - LastVehicleSpeed) / DeltaTime;
213  // Apply an average filter for the acceleration.
214  VehicleAcceleration = (4.0f*LastVehicleAcceleration + CurrentAcceleration) / 5.0f;
215 }
216 
218  VehicleMaxSteering = FMath::DegreesToRadians(Vehicle->GetMaximumSteerAngle());
219 }
float GetVehicleForwardSpeed() const
Forward speed in cm/s. Might be negative if goes backwards.
void SetTargetPoint(const FVehicleAckermannControl &AckermannControl)
float GetMaximumSteerAngle() const
Get the maximum angle at which the front wheel can steer.
void ApplySettings(const FAckermannControllerSettings &Settings)
void UpdateVehiclePhysics(const ACarlaWheeledVehicle *Vehicle)
void UpdateVehicleState(const ACarlaWheeledVehicle *Vehicle)
const FVehicleControl & GetVehicleControl() const
Vehicle control currently applied to this vehicle.
void RunLoop(FVehicleControl &Control)
void Reset()
void SetTargetPoint(float Point)
FAckermannControllerSettings GetSettings() const
FVehicleAckermannControl UserTargetPoint
float Run(float Input, float DeltaTime)
Base class for CARLA wheeled vehicles.