Skip to content

Commit

Permalink
feat: spawn npc from rviz (#118)
Browse files Browse the repository at this point in the history
Signed-off-by: SujayAmberkar <[email protected]>
  • Loading branch information
SujayAmberkar authored Jul 19, 2024
1 parent 2a71ad6 commit 3b16514
Show file tree
Hide file tree
Showing 48 changed files with 917 additions and 15 deletions.
63 changes: 52 additions & 11 deletions Assets/AWSIM/Scenes/Main/AutowareSimulation.unity
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 1911152051}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
Expand Down Expand Up @@ -247,6 +248,11 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 58d73df60b244d146bdf5f5896f78355, type: 3}
--- !u!4 &10387859 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 9027057600357292003, guid: 58d73df60b244d146bdf5f5896f78355, type: 3}
m_PrefabInstance: {fileID: 10387858}
m_PrefabAsset: {fileID: 0}
--- !u!1 &12639409
GameObject:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -1104,9 +1110,9 @@ RectTransform:
- {fileID: 598773923}
m_Father: {fileID: 2100303025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 96.25, y: -80}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 96.25, y: 0}
m_SizeDelta: {x: 192.5, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &129670042
Expand Down Expand Up @@ -1574,6 +1580,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 203643521}
- component: {fileID: 203643522}
m_Layer: 0
m_Name: Environment
m_TagString: Untagged
Expand All @@ -1600,6 +1607,35 @@ Transform:
- {fileID: 113080103}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &203643522
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 203643520}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 134fb5ad0cefe76c8895739ca367180b, type: 3}
m_Name:
m_EditorClassIdentifier:
dummyPerceptionTopic: /simulation/dummy_perception_publisher/object_info
qosSettings:
ReliabilityPolicy: 0
DurabilityPolicy: 0
HistoryPolicy: 0
Depth: 0
npcPedestrianPrefab: {fileID: 500668027104458449, guid: 27e8a3736efefa447b1f65b33b30908a, type: 3}
npcCarPrefabs:
- {fileID: 6604874415271597525, guid: 7e772e9ad7eb79040be629d8d04542ab, type: 3}
- {fileID: 3333523281254186578, guid: 589cf2e451adab34eb1332da5701195a, type: 3}
- {fileID: 714549001370495616, guid: d0094c5a0e9fb6148873c658dbc61a89, type: 3}
- {fileID: 536101250511469494, guid: 433e715a84edbae418fe585f802f3918, type: 3}
npcBusPrefabs:
- {fileID: 6850358619771218631, guid: 9bc315af95865dd4bbf4a8f716791609, type: 3}
npcPedestrianParent: {fileID: 1822423795}
npcVehicleParent: {fileID: 10387859}
despawnTime: 20
--- !u!1 &221280047
GameObject:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -5355,9 +5391,9 @@ RectTransform:
- {fileID: 1317468420}
m_Father: {fileID: 2100303025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 96.25, y: -230}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 96.25, y: 0}
m_SizeDelta: {x: 192.5, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1194537306
Expand Down Expand Up @@ -6426,9 +6462,9 @@ RectTransform:
- {fileID: 1021800942}
m_Father: {fileID: 2100303025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 96.25, y: -345}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 96.25, y: 0}
m_SizeDelta: {x: 192.5, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1427845714
Expand Down Expand Up @@ -7518,8 +7554,8 @@ RectTransform:
- {fileID: 4359775064103456631}
m_Father: {fileID: 2100303025}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 96.25, y: 0}
m_SizeDelta: {x: 192.5, y: 0}
m_Pivot: {x: 0.5, y: 1}
Expand Down Expand Up @@ -7780,6 +7816,11 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1814292294}
m_CullTransparentMesh: 1
--- !u!4 &1822423795 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 1041813114, guid: 58d73df60b244d146bdf5f5896f78355, type: 3}
m_PrefabInstance: {fileID: 10387858}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1826199770
GameObject:
m_ObjectHideFlags: 0
Expand Down
8 changes: 8 additions & 0 deletions Assets/AWSIM/Scripts/NPCs/RvizNPCSpawner.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions Assets/AWSIM/Scripts/NPCs/RvizNPCSpawner/NPCMovement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NPCMovement : MonoBehaviour
{
private float velocity = 0;
Rigidbody rb;
Vector3 forwardMovement;
Vector3 currentVelocity;
void Start()
{
rb = GetComponent<Rigidbody>();
}

public void Initialize(float velocity)
{
this.velocity = velocity;
}

void Update()
{

if (rb != null)
{
rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
forwardMovement = transform.forward * velocity;
currentVelocity = rb.velocity;
rb.velocity = new Vector3(forwardMovement.x, rb.velocity.y, forwardMovement.z);
}
}
}
11 changes: 11 additions & 0 deletions Assets/AWSIM/Scripts/NPCs/RvizNPCSpawner/NPCMovement.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

183 changes: 183 additions & 0 deletions Assets/AWSIM/Scripts/NPCs/RvizNPCSpawner/RVIZNPCSpawner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ROS2;


namespace AWSIM
{
/// <summary>
/// This class subscribes to the /simulation/dummy_perception_publisher/object_info topic
/// and spawn an NPC pedestrian or vehicle based on the value of "Label"
/// </summary>
public class RVIZNPCSpawner : MonoBehaviour
{
// collision layer
private const int NPC_LAYER = 12;

[Header("ROS Config")]
[SerializeField] string dummyPerceptionTopic = "/simulation/dummy_perception_publisher/object_info";
[SerializeField] QoSSettings qosSettings = new QoSSettings();

[Header("NPC Prefabs")]
[SerializeField] GameObject npcPedestrianPrefab;
[SerializeField] GameObject[] npcCarPrefabs;
[SerializeField] GameObject[] npcBusPrefabs;

[Header("NPC Config")]
public Transform npcPedestrianParent;
public Transform npcVehicleParent;
[SerializeField] float despawnTime = 30;

private bool _willSpawnNpc = false;
private bool _willDespawnAllNPCs = false;
private int _npcLabel;
private float _npcVelocity;
private Quaternion _npcSpawnRotation;
private Vector3 _npcSpawnPosition;
private List<GameObject> _spawnedNPCs = new List<GameObject>();

// Subscriber
ISubscription<dummy_perception_publisher.msg.Object> dummyPerceptionSubscriber;

void Start()
{
// Initialize the ROS2 node and create the subscription
dummyPerceptionSubscriber
= SimulatorROS2Node.CreateSubscription<dummy_perception_publisher.msg.Object>(
dummyPerceptionTopic, OnObjectInfoReceived, qosSettings.GetQoSProfile());
}

private void FixedUpdate()
{
if (_willSpawnNpc)
{
// check where the ground collider is and spawn the NPC above the ground
Vector3 rayOrigin = new Vector3(_npcSpawnPosition.x, 1000.0f, _npcSpawnPosition.z);
Vector3 rayDirection = Vector3.down;

if (Physics.Raycast(rayOrigin, rayDirection, out RaycastHit hit, Mathf.Infinity))
{
_npcSpawnPosition = new Vector3(_npcSpawnPosition.x, hit.point.y + 1.33f, _npcSpawnPosition.z);
if (_npcLabel == 7)
{
SpawnPedestrians(_npcSpawnPosition, _npcSpawnRotation);
}
else
{
SpawnVehicles(_npcSpawnPosition, _npcSpawnRotation, _npcLabel);
}
}
else
{
Debug.LogWarning("No mesh or collider detected on target location. Please ensure that the target location is on a mesh or collider.");
}

_willSpawnNpc = false;
}

if (_willDespawnAllNPCs)
{
DespawnAllNPCs();
_willDespawnAllNPCs = false;
}
}

/// <summary>
/// Callback method to handle incoming ROS messages
/// </summary>
/// <param name="msg">Received Object message</param>
void OnObjectInfoReceived(dummy_perception_publisher.msg.Object msg)
{
if (msg.Classification.Label == 0)
{
// despawn all the rviz NPCs
Debug.Log("delete spawned NPCs");
_willDespawnAllNPCs = true;
return;
}
_willSpawnNpc = true;
_npcSpawnPosition = ROS2Utility.RosMGRSToUnityPosition(msg.Initial_state.Pose_covariance.Pose.Position);
_npcSpawnRotation = ROS2Utility.RosToUnityRotation(msg.Initial_state.Pose_covariance.Pose.Orientation);
_npcLabel = msg.Classification.Label;
_npcVelocity = (float)msg.Initial_state.Twist_covariance.Twist.Linear.X;
}

/// <summary>
/// Method to spawn NPC Pedestrians
/// </summary>
private void SpawnPedestrians(Vector3 spawnPoint, Quaternion spawnOrientation)
{
GameObject npcPedestrian = Instantiate(npcPedestrianPrefab, new Vector3(spawnPoint.x, spawnPoint.y, spawnPoint.z), spawnOrientation, npcPedestrianParent);
SimplePedestrianWalkerController walker = npcPedestrian.AddComponent<SimplePedestrianWalkerController>();
_spawnedNPCs.Add(npcPedestrian);

walker.GetType().GetField("duration", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(walker, 30);
walker.GetType().GetField("speed", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(walker, _npcVelocity);
StartCoroutine(DespawnNPC(npcPedestrian, despawnTime));
}

/// <summary>
/// Method to spawn NPC vehicles
/// </summary>
private void SpawnVehicles(Vector3 spawnPoint, Quaternion spawnOrientation, int vehicleType)
{
GameObject vehiclePrefab = npcCarPrefabs[Random.Range(0, npcCarPrefabs.Length - 1)];
if (vehicleType == 3)
{
vehiclePrefab = npcBusPrefabs[Random.Range(0, npcBusPrefabs.Length)];
}

GameObject npcVehicle = Instantiate(vehiclePrefab, new Vector3(spawnPoint.x, spawnPoint.y, spawnPoint.z), spawnOrientation, npcVehicleParent);
_spawnedNPCs.Add(npcVehicle);

SetNPCLayer(npcVehicle, NPC_LAYER);

// make the vehicle move a constant velocity
NPCMovement npcMovement = npcVehicle.AddComponent<NPCMovement>();
npcMovement.Initialize(_npcVelocity);

StartCoroutine(DespawnNPC(npcVehicle, despawnTime));
}

/// <summary>
/// Recursively set layer of the NPC and its children to layer 12: "NPC Vehicle"
/// </summary>
private void SetNPCLayer(GameObject obj, int newLayer)
{
obj.layer = newLayer;

foreach (Transform child in obj.transform)
{
SetNPCLayer(child.gameObject, newLayer);
}
}

/// <summary>
/// Despawn NPC after a delay
/// </summary>
private IEnumerator DespawnNPC(GameObject npc, float delay)
{
yield return new WaitForSeconds(delay);
Destroy(npc);
}

/// <summary>
/// Despawn all NPCs
/// </summary>
private void DespawnAllNPCs()
{
foreach (var npc in _spawnedNPCs)
{
Destroy(npc);
}
_spawnedNPCs.Clear();
}

void OnDestroy()
{
// Clean up the subscription when the GameObject is destroyed
SimulatorROS2Node.RemoveSubscription<dummy_perception_publisher.msg.Object>(dummyPerceptionSubscriber);
}
}
}
11 changes: 11 additions & 0 deletions Assets/AWSIM/Scripts/NPCs/RvizNPCSpawner/RVIZNPCSpawner.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Loading

0 comments on commit 3b16514

Please sign in to comment.