-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Expand file tree
/
Copy pathVehicle.cs
More file actions
389 lines (323 loc) · 14.3 KB
/
Copy pathVehicle.cs
File metadata and controls
389 lines (323 loc) · 14.3 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
using System;
using AirSimUnity.DroneStructs;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using UnityEditor;
using UnityEngine;
namespace AirSimUnity {
/*
* The base class for all the vehicle models in the simulation. Holds the data to communicate between AirLib and Unity.
* An implementation of IVehicleInterface with all the contracts required by VehicleCompanion.
*/
[RequireComponent(typeof(Rigidbody))]
public abstract class Vehicle : MonoBehaviour, IVehicleInterface {
protected Vector3 position;
protected Quaternion rotation;
protected Vector3 scale3D = Vector3.one;
protected AirSimPose poseFromAirLib;
protected AirSimPose currentPose;
protected CollisionInfo collisionInfo;
protected AirSimRCData rcData;
protected bool resetVehicle;
protected float time_scale = 1.0f;
protected bool timeScale_changed = false;
protected bool isApiEnabled = false;
protected bool isServerStarted = false;
bool print_log_messages_ = true;
protected readonly List<DataCaptureScript> captureCameras = new List<DataCaptureScript>();
protected AutoResetEvent captureResetEvent;
protected IAirSimInterface airsimInterface;
protected bool isCapturingImages = false;
protected ImageRequest imageRequest;
protected ImageResponse imageResponse;
private bool isDrone;
private static bool isSegmentationUpdated;
private bool calculateRayCast = false;
private Vector3 startVec;
private Vector3 endVec;
private RaycastHit hitInfo;
private bool hitResult;
[SerializeField] string vehicleName;
private Rigidbody vehicleRigidBody;
private void Awake()
{
vehicleRigidBody = GetComponent(type: typeof(Rigidbody)) as Rigidbody;
}
//Ensure to call this method as the first statement, from derived class `Start()` method.
protected void Start() {
isDrone = this is Drone ? true : false;
if (isDrone) {
vehicleRigidBody.useGravity = false;
}
InitializeVehicle();
airsimInterface = VehicleCompanion.GetVehicleCompanion(vehicleName, this);
isServerStarted = true;
AirSimGlobal.Instance.Weather.AttachToVehicle(this);
}
//Ensure to call this method as the first statement, from derived class `FixedUpdate()` method.
protected void FixedUpdate() {
if (isServerStarted)
{
DataManager.SetToAirSim(transform.position, ref currentPose.position);
DataManager.SetToAirSim(transform.rotation, ref currentPose.orientation);
}
}
//Ensure to call this method as the last statement, from derived class `LateUpdate()` method.
protected void LateUpdate() {
if (isServerStarted)
{
if (timeScale_changed)
{
Time.timeScale = time_scale;
timeScale_changed = false;
}
if (isSegmentationUpdated)
{
UpdateSegmentationView();
isSegmentationUpdated = false;
}
if (isCapturingImages)
{
var captureCamera = captureCameras.Find(element => element.GetCameraName() == imageRequest.camera_name);
imageResponse = captureCamera.GetImageBasedOnRequest(imageRequest);
captureResetEvent.Set(); //Release the GetSimulationImages thread with the image response.
isCapturingImages = false;
}
if (calculateRayCast)
{
hitResult = Physics.Linecast(startVec, endVec, out hitInfo);
calculateRayCast = false;
}
if (Input.GetKeyDown(KeyCode.T))
{
print_log_messages_ = !print_log_messages_;
}
}
}
protected void OnCollisionEnter(Collision collision) {
if (isServerStarted)
{
collisionInfo.has_collided = true;
collisionInfo.object_id = -1;
collisionInfo.collision_count++;
collisionInfo.object_name = collision.collider.name;
DataManager.SetToAirSim(collision.contacts[0].normal, ref collisionInfo.normal);
DataManager.SetToAirSim(collision.contacts[0].point, ref collisionInfo.impact_point);
collisionInfo.position = currentPose.position;
collisionInfo.penetration_depth = collision.contacts[0].separation;
collisionInfo.object_name = collision.collider.name;
collisionInfo.time_stamp = DataManager.GetCurrentTimeInMilli();
airsimInterface.InvokeCollisionDetectionInAirSim(vehicleName, collisionInfo);
}
}
protected void OnCollisionStay(Collision collision) {
if (isServerStarted)
{
collisionInfo.has_collided = true;
collisionInfo.object_id = -1;
collisionInfo.collision_count++;
collisionInfo.object_name = collision.collider.name;
DataManager.SetToAirSim(collision.contacts[0].normal, ref collisionInfo.normal);
DataManager.SetToAirSim(collision.contacts[0].point, ref collisionInfo.impact_point);
collisionInfo.position = currentPose.position;
collisionInfo.penetration_depth = collision.contacts[0].separation;
collisionInfo.object_name = collision.collider.name;
collisionInfo.time_stamp = DataManager.GetCurrentTimeInMilli();
}
}
protected void OnCollisionExit() {
if (isServerStarted)
{
collisionInfo.has_collided = false;
}
}
//Define the recording data that needs to be saved in the airsim_rec file for Toggle Recording button
public abstract DataRecorder.ImageData GetRecordingData();
public void ResetVehicle()
{
resetVehicle = true;
}
public virtual AirSimVector GetVelocity()
{
var rigidBody = GetComponent<Rigidbody>();
return new AirSimVector(rigidBody.velocity.x, rigidBody.velocity.y, rigidBody.velocity.z);
}
public bool SetPose(AirSimPose pose, bool ignore_collision) {
poseFromAirLib = pose;
return true;
}
public AirSimPose GetPose() {
return currentPose;
}
public UnityTransform GetTransform()
{
return new UnityTransform(new AirSimQuaternion(currentPose.orientation.x, currentPose.orientation.y, currentPose.orientation.z, currentPose.orientation.w),
new AirSimVector(currentPose.position.x, currentPose.position.y, currentPose.position.z),
new AirSimVector(scale3D.x, scale3D.y, scale3D.z));
}
public RayCastHitResult GetRayCastHit(AirSimVector start, AirSimVector end)
{
DataManager.SetToUnity(start, ref startVec);
DataManager.SetToUnity(end, ref endVec);
calculateRayCast = true;
int count = 500; // wait for max 0.5 second
while(calculateRayCast && count > 0)
{
count--;
}
return new RayCastHitResult(hitResult, hitInfo.distance);
}
public bool Pause(float timeScale)
{
time_scale = timeScale;
timeScale_changed = true;
return true;
}
public CollisionInfo GetCollisionInfo() {
return collisionInfo;
}
public AirSimRCData GetRCData() {
return rcData;
}
public DataCaptureScript GetCameraCapture(string cameraName) {
DataCaptureScript recordCam = captureCameras[0];
foreach (DataCaptureScript camCapture in captureCameras.Where(camCapture => camCapture.GetCameraName() == cameraName))
{
recordCam = camCapture;
break;
}
return recordCam;
}
public ImageResponse GetSimulationImages(ImageRequest request) {
imageResponse.reset();
if (!captureCameras.Find(element => element.GetCameraName() == request.camera_name))
{
return imageResponse;
}
imageRequest = request;
isCapturingImages = true;
captureResetEvent.WaitOne();
return imageResponse;
}
public bool SetEnableApi(bool enableApi) {
isApiEnabled = enableApi;
return true;
}
public CameraInfo GetCameraInfo(string cameraName) {
CameraInfo info = new CameraInfo();
foreach (DataCaptureScript capture in captureCameras.Where(camCapture => camCapture.GetCameraName() == cameraName)) {
info.fov = capture.GetFOV();
info.pose = capture.GetPose();
return info;
}
return info;
}
public bool SetCameraPose(string cameraName, AirSimPose pose) {
foreach (DataCaptureScript capture in captureCameras.Where(camCapture => camCapture.GetCameraName() == cameraName)) {
capture.SetPose(pose);
return true;
}
return false;
}
public bool SetCameraFoV(string cameraName, float fov_degrees)
{
foreach (DataCaptureScript capture in captureCameras.Where(capture => capture.GetCameraName() == cameraName))
{
capture.SetFoV(fov_degrees);
return true;
}
return false;
}
public bool SetDistortionParam(string cameraName, string paramName, float value)
{
// not implemented
return false;
}
public bool GetDistortionParams(string cameraName)
{
// not implemented
return false;
}
public bool PrintLogMessage(string message, string messageParams, string vehicleName, int severity) {
if (!print_log_messages_)
return true;
switch (severity)
{
case 1:
Debug.LogWarning(message + " " + messageParams + " Vehicle=" + vehicleName);
break;
case 2:
Debug.LogError(message + " " + messageParams + " Vehicle=" + vehicleName);
break;
default:
Debug.Log(message + " " + messageParams + " Vehicle=" + vehicleName);
break;
}
return true;
}
public static bool SetSegmentationObjectId(string objectName, int objectId, bool isNameRegex) {
int finalId = ((objectId + 2) << 16) | ((objectId + 1) << 8) | objectId;
bool result = CameraFiltersScript.SetSegmentationId(objectName, finalId, isNameRegex);
isSegmentationUpdated = result;
return result;
}
public static int GetSegmentationObjectId(string objectName) {
return CameraFiltersScript.GetSegmentationId(objectName);
}
public virtual bool SetRotorSpeed(int rotorIndex, RotorInfo rotorInfo) {
throw new NotImplementedException("This is supposed to be implemented in Drone sub class");
}
public virtual bool SetCarControls(CarStructs.CarControls controls) {
throw new NotImplementedException("This is supposed to be implemented in Car sub class");
}
public virtual CarStructs.CarState GetCarState() {
throw new NotImplementedException("This is supposed to be implemented in Car sub class");
}
/****************** Methods for vehicle management **************************/
private void InitializeVehicle() {
//Setting the initial get pose(HomePoint in AirLib) values to that of vehicle's location in the scene for initial setup in AirLib
DataManager.SetToAirSim(transform.position, ref currentPose.position);
DataManager.SetToAirSim(transform.rotation, ref currentPose.orientation);
collisionInfo.SetDefaultValues();
SetUpCameras();
captureResetEvent = new AutoResetEvent(false);
}
private GameObject FindChildWithTag(GameObject parent, string tag) {
GameObject child = null;
foreach(Transform transform in parent.transform) {
if(transform.CompareTag(tag)) {
child = transform.gameObject;
break;
}
}
return child;
}
//Register all the capture cameras in the scene for recording and data capture.
//Make sure every camera is a child of a gameobject with tag "CaptureCameras"
private void SetUpCameras() {
GameObject this_vehicle = GameObject.Find(this.name);
GameObject camerasParent = FindChildWithTag(this_vehicle, "CaptureCameras");
if (!camerasParent) {
Debug.LogWarning("No Cameras found in the scene to capture data");
return;
}
for (int i = 0; i < camerasParent.transform.childCount; i++) {
DataCaptureScript camCapture = camerasParent.transform.GetChild(i).GetComponent<DataCaptureScript>();
captureCameras.Add(camCapture);
camCapture.SetUpCamera(camCapture.GetCameraName(), isDrone);
}
}
private void UpdateSegmentationView() {
GameObject viewCameras = GameObject.FindGameObjectWithTag("ViewCameras");
if (viewCameras) {
foreach (CameraFiltersScript viewCam in viewCameras.GetComponentsInChildren<CameraFiltersScript>()) {
if (viewCam.effect != ImageType.Segmentation) {
continue;
}
viewCam.SetShaderEffect(ImageType.Segmentation);
}
}
}
}
}