Utilities.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "Utilities.h"
  9. #include "WheelControllerComponent.h"
  10. #include <AzCore/Component/ComponentApplicationBus.h>
  11. #include <AzCore/Component/Entity.h>
  12. #include <AzCore/std/string/string.h>
  13. #include <HingeJointComponent.h>
  14. #include <PhysX/Joint/PhysXJointRequestsBus.h>
  15. namespace ROS2::VehicleDynamics::Utilities
  16. {
  17. AxleConfiguration Create2WheelAxle(
  18. AZ::EntityId leftWheel, AZ::EntityId rightWheel, AZStd::string tag, float wheelRadius, bool steering, bool drive)
  19. {
  20. VehicleDynamics::AxleConfiguration axleConfiguration;
  21. axleConfiguration.m_axleWheels.push_back(leftWheel);
  22. axleConfiguration.m_axleWheels.push_back(rightWheel);
  23. axleConfiguration.m_axleTag = AZStd::move(tag);
  24. axleConfiguration.m_isSteering = steering;
  25. axleConfiguration.m_isDrive = drive;
  26. axleConfiguration.m_wheelRadius = wheelRadius;
  27. return axleConfiguration;
  28. }
  29. AxleConfiguration CreateFrontSteerAndDriveAxle(AZ::EntityId leftWheel, AZ::EntityId rightWheel, float wheelRadius)
  30. {
  31. return Create2WheelAxle(leftWheel, rightWheel, "Front", wheelRadius, true, true);
  32. }
  33. AxleConfiguration CreateRearDriveAxle(AZ::EntityId leftWheel, AZ::EntityId rightWheel, float wheelRadius)
  34. {
  35. return Create2WheelAxle(leftWheel, rightWheel, "Rear", wheelRadius, false, true);
  36. }
  37. AZStd::vector<VehicleDynamics::SteeringDynamicsData> GetAllSteeringEntitiesData(const VehicleConfiguration& vehicleConfig)
  38. {
  39. AZStd::vector<VehicleDynamics::SteeringDynamicsData> steeringEntitiesAndAxis;
  40. for (const auto& axle : vehicleConfig.m_axles)
  41. {
  42. if (!axle.m_isSteering)
  43. { // Only steering axles will have steering entities
  44. continue;
  45. }
  46. for (const auto& wheel : axle.m_axleWheels)
  47. {
  48. if (!wheel.IsValid())
  49. {
  50. AZ_Warning("GetAllSteeringEntitiesData", false, "Wheel entity in axle %s is invalid, ignoring", axle.m_axleTag.c_str());
  51. continue;
  52. }
  53. AZ::Entity* wheelEntity = nullptr;
  54. AZ::ComponentApplicationBus::BroadcastResult(wheelEntity, &AZ::ComponentApplicationRequests::FindEntity, wheel);
  55. if (!wheelEntity)
  56. {
  57. AZ_Warning("GetAllSteeringEntitiesData", false, "Wheel entity in axle %s is null, ignoring", axle.m_axleTag.c_str());
  58. continue;
  59. }
  60. auto* controllerComponent = wheelEntity->FindComponent<WheelControllerComponent>();
  61. if (!controllerComponent)
  62. {
  63. AZ_Warning(
  64. "GetAllSteeringEntitiesData",
  65. false,
  66. "Missing a WheelController in wheel entity %s, ignoring",
  67. wheel.ToString().c_str());
  68. continue;
  69. }
  70. AZ::EntityId steeringEntity = controllerComponent->m_steeringEntity;
  71. if (!steeringEntity.IsValid())
  72. {
  73. AZ_Warning(
  74. "GetAllSteeringEntitiesData",
  75. false,
  76. "Steering entity specified for WheelController in entity %s is invalid, ignoring",
  77. wheel.ToString().c_str());
  78. continue;
  79. }
  80. const float steeringScale = controllerComponent->m_steeringScale;
  81. PhysX::HingeJointComponent* hingeComponent{ nullptr };
  82. AZ::Entity* steeringEntityptr{ nullptr };
  83. AZ::ComponentApplicationBus::BroadcastResult(
  84. steeringEntityptr, &AZ::ComponentApplicationRequests::FindEntity, steeringEntity);
  85. AZ_Assert(steeringEntityptr, "Cannot find a steering entity for %s", steeringEntity.ToString().c_str());
  86. hingeComponent = steeringEntityptr->FindComponent<PhysX::HingeJointComponent>();
  87. if (!hingeComponent)
  88. {
  89. AZ_Warning(
  90. "GetAllSteeringEntitiesData",
  91. false,
  92. "Steering entity specified for WheelController in entity %s does not not have HingeJointComponent, ignoring",
  93. wheel.ToString().c_str());
  94. continue;
  95. }
  96. VehicleDynamics::SteeringDynamicsData steeringData;
  97. steeringData.m_steeringScale = steeringScale;
  98. steeringData.m_steeringEntity = steeringEntity;
  99. steeringData.m_hingeJoint = hingeComponent->GetId();
  100. steeringEntitiesAndAxis.push_back(steeringData);
  101. }
  102. }
  103. return steeringEntitiesAndAxis;
  104. }
  105. AZStd::vector<VehicleDynamics::WheelDynamicsData> GetAllDriveWheelsData(const VehicleConfiguration& vehicleConfig)
  106. {
  107. AZStd::vector<VehicleDynamics::WheelDynamicsData> driveWheelEntities;
  108. for (const AxleConfiguration& axle : vehicleConfig.m_axles)
  109. {
  110. if (!axle.m_isDrive)
  111. { // Get only drive wheels, which are attached to a drive axle
  112. continue;
  113. }
  114. for (const AZ::EntityId& wheel : axle.m_axleWheels)
  115. {
  116. if (!wheel.IsValid())
  117. {
  118. AZ_Warning("GetAllSteeringEntitiesData", false, "Wheel entity in axle %s is invalid, ignoring", axle.m_axleTag.c_str());
  119. continue;
  120. }
  121. AZ::Entity* wheelEntity = nullptr;
  122. AZ::ComponentApplicationBus::BroadcastResult(wheelEntity, &AZ::ComponentApplicationRequests::FindEntity, wheel);
  123. if (!wheelEntity)
  124. {
  125. AZ_Warning("GetAllSteeringEntitiesData", false, "Wheel entity in axle %s is null, ignoring", axle.m_axleTag.c_str());
  126. continue;
  127. }
  128. auto* controllerComponent = wheelEntity->FindComponent<WheelControllerComponent>();
  129. if (!controllerComponent)
  130. {
  131. AZ_Warning(
  132. "GetAllDriveWheelsData",
  133. false,
  134. "Wheel entity for axle %s is missing a WheelController component, ignoring",
  135. axle.m_axleTag.c_str());
  136. continue;
  137. }
  138. PhysX::HingeJointComponent* hingeComponent{ nullptr };
  139. hingeComponent = wheelEntity->FindComponent<PhysX::HingeJointComponent>();
  140. if (!hingeComponent)
  141. {
  142. AZ_Warning(
  143. "GetAllDriveWheelsData",
  144. false,
  145. "Wheel entity for axle %s is missing a HingeJointComponent component, ignoring",
  146. axle.m_axleTag.c_str());
  147. continue;
  148. }
  149. VehicleDynamics::WheelDynamicsData wheelData;
  150. wheelData.m_wheelEntity = wheel;
  151. wheelData.m_hingeJoint = hingeComponent->GetId();
  152. wheelData.m_wheelRadius = axle.m_wheelRadius;
  153. driveWheelEntities.push_back(wheelData);
  154. }
  155. }
  156. return driveWheelEntities;
  157. }
  158. AZ::EntityComponentIdPair GetWheelPhysxHinge(const AZ::EntityId wheelEntityId)
  159. {
  160. AZ::Entity* wheelEntity = nullptr;
  161. AZ::ComponentApplicationBus::BroadcastResult(wheelEntity, &AZ::ComponentApplicationRequests::FindEntity, wheelEntityId);
  162. if (!wheelEntity)
  163. {
  164. AZ_Warning("GetWheelDynamicData", false, "Entity %s was not found", wheelEntityId.ToString().c_str());
  165. return AZ::EntityComponentIdPair();
  166. }
  167. PhysX::HingeJointComponent* hingeComponent{ nullptr };
  168. hingeComponent = wheelEntity->FindComponent<PhysX::HingeJointComponent>();
  169. if (!hingeComponent)
  170. {
  171. AZ_Warning("GetWheelDynamicData", false, "Entity %s has no PhysX::HingeJointComponent", wheelEntityId.ToString().c_str());
  172. return AZ::EntityComponentIdPair();
  173. }
  174. return AZ::EntityComponentIdPair(wheelEntityId, hingeComponent->GetId());
  175. }
  176. } // namespace ROS2::VehicleDynamics::Utilities