Verified Commit edb696b9 authored by Sebastian Höffner's avatar Sebastian Höffner
Browse files

statics to avoid losing references in WebGL-Coroutines

 – Simulation working!
parent 1cf20bd4
......@@ -225,8 +225,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 5a96a403731ec4d79ba6b98094537821, type: 3}
m_Name:
m_EditorClassIdentifier:
boundsMin: {x: -1.55, y: -0.05, z: -1.55}
boundsMax: {x: 1.55, y: 1.35, z: 1.55}
resolution: {x: 0.05, y: 0.05, z: 0.05}
--- !u!4 &917209558
Transform:
......@@ -252,6 +250,7 @@ GameObject:
m_Component:
- component: {fileID: 1309245142}
- component: {fileID: 1309245141}
- component: {fileID: 1309245143}
m_Layer: 2
m_Name: DLU
m_TagString: Untagged
......@@ -275,6 +274,7 @@ MonoBehaviour:
captureVideo: 1
timeoutAfterSeconds: 40
occupancyGrid: {fileID: 0}
schemaExecutor: {fileID: 0}
--- !u!4 &1309245142
Transform:
m_ObjectHideFlags: 0
......@@ -290,3 +290,15 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1309245143
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1309245140}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3fe91f163c0534463a99fb7807b3dc2a, type: 3}
m_Name:
m_EditorClassIdentifier:
......@@ -9,9 +9,11 @@ namespace dlu
public abstract class Communication : MonoBehaviour
{
public SceneController sceneController;
private GameObject dluGameObject;
void Awake()
protected void Awake()
{
dluGameObject = GameObject.Find("DLU");
if (sceneController == null)
{
sceneController = GetComponent<SceneController>();
......@@ -23,6 +25,7 @@ public abstract class Communication : MonoBehaviour
protected void HandleRequest(JSONObject requestObject)
{
Debug.Log($"[Communication] DLU GameObject: {dluGameObject}");
string command = requestObject["Command"];
Debug.Log($"[Communication] Command: '{command}'");
JSONObject error = new JSONObject();
......@@ -52,13 +55,14 @@ public abstract class Communication : MonoBehaviour
}
catch(ArgumentNullException)
{
Debug.Log($"Using default resolution of {resolution}");
Debug.Log($"[Communication] Using default resolution of {resolution}");
}
JSONArray exclude = requestObject["exclude"] != null ? requestObject["exclude"] as JSONArray : new JSONArray();
StartCoroutine(sceneController.GenerateOccupancyGrid(resolution, exclude, ReplyToRequest, requestObject));
break;
case "SIMULATE_SCENE":
JSONArray instructions = requestObject["instructions"] != null ? requestObject["instructions"] as JSONArray : new JSONArray();
Debug.Log($"[Communication] Starting RunSimulation Coroutine");
StartCoroutine(sceneController.RunSimulation(instructions, ReplyToRequest, requestObject));
break;
default:
......
......@@ -38,6 +38,7 @@ public class DirectCommunication : Communication
string responseString = base.ComposeReply(response, originalRequest);
byte[] responseArray = Encoding.UTF8.GetBytes(responseString);
#if !UNITY_EDITOR
Debug.Log($"[DirectCommunication] Replying with message:\n{responseString.Substring(0, responseString.Length > 50 ? 50 : responseString.Length - 1)}");
Reply(responseArray, responseString.Length);
#else
Debug.Log("[DirectCommunication] Would reply using jslib");
......
using UnityEngine;
using UnityEditor;
using System.Linq;
using SimpleJSON;
using System.IO;
namespace dlu
{
[CustomEditor(typeof(SchemaExecutor))]
public class SchemaExecutorEditor : Editor
{
private string GenerateExampleTrajectory()
{
JSONArray array = new JSONArray();
JSONObject exampleTrajectory = new JSONObject();
array.Add(exampleTrajectory);
JSONObject simObject = new JSONObject();
exampleTrajectory["trajectory"] = simObject;
simObject["object"] = "cup_0";
JSONArray path = new JSONArray();
simObject["trajectory"] = path;
JSONObject pose1 = new JSONObject();
JSONObject position1 = new JSONObject();
position1["x"] = -1.28697800636292f;
position1["y"] = 0.446957409381866f;
position1["z"] = 0.86613804101944f;
pose1["position"] = position1;
JSONObject orientation1 = new JSONObject();
orientation1["x"] = -0.395544409751892f;
orientation1["y"] = -0.00130454241298139f;
orientation1["z"] = -0.918443620204926f;
orientation1["w"] = -0.00205645314417779f;
pose1["orientation"] = orientation1;
JSONObject pose2 = new JSONObject();
JSONObject position2 = new JSONObject();
position2["x"] = -1.2f;
position2["y"] = 0.42f;
position2["z"] = 0.25f;
pose2["position"] = position2;
JSONObject orientation2 = new JSONObject();
orientation2["x"] = 0f;
orientation2["y"] = 0f;
orientation2["z"] = 0f;
orientation2["w"] = 1f;
pose2["orientation"] = orientation2;
path.Add(pose1);
path.Add(pose2);
return array.ToString();
}
public override void OnInspectorGUI()
{
base.DrawDefaultInspector();
string json = EditorGUILayout.TextArea(GenerateExampleTrajectory());
if (Application.isPlaying) {
if (GUILayout.Button("Run test"))
{
SchemaExecutor se = (SchemaExecutor) target;
JSONArray command = JSONNode.Parse(json) as JSONArray;
se.RunTestSimulation(command);
}
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 7ef57879575d54034b0a01a0fb130a65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -13,11 +13,9 @@ public class SceneController : MonoBehaviour
{
private JSONArray instruction;
public string contextScene = "Kitchen";
private Func<string, IEnumerator> replyToRequest;
private Dictionary<string, bool> actionParticipants;
private List<string> metaLog;
string metaLogPhase = "UNDEFINED";
private static List<string> metaLog;
private static string metaLogPhase;
public bool captureVideo = false;
public static bool recordTrajectories = false;
......@@ -26,14 +24,25 @@ public class SceneController : MonoBehaviour
private int timeToTimeout = 0;
public OccupancyGrid occupancyGrid;
public SchemaExecutor schemaExecutor = null;
public static GameObject dluGameObject = null;
private static Func<JSONObject, JSONObject, IEnumerator> replyToRequestSimulation;
private static JSONObject originalRequestSimulation;
public void Awake()
{
SceneController.metaLogPhase = "UNKNOWN";
SceneManager.sceneLoaded += RefreshSemanticLabelsOnSceneLoad;
if (schemaExecutor == null)
{
schemaExecutor = gameObject.GetComponent<SchemaExecutor>();
}
}
public void Start()
{
Debug.Log($"[SceneController] DLU GameObject: {SceneController.dluGameObject}");
if (!SceneManager.GetSceneByName(contextScene).isLoaded)
{
SceneManager.LoadSceneAsync(contextScene, LoadSceneMode.Additive);
......@@ -50,9 +59,13 @@ public class SceneController : MonoBehaviour
void Update()
{
if (metaLog != null)
if (SceneController.recordTrajectories)
{
metaLog.Add(metaLogPhase);
if(SceneController.metaLog == null)
{
SceneController.metaLog = new List<string>();
}
SceneController.metaLog.Add(SceneController.metaLogPhase);
}
}
......@@ -132,24 +145,46 @@ public class SceneController : MonoBehaviour
public IEnumerator GetContext(Func<JSONObject, JSONObject, IEnumerator> replyRequest, JSONObject originalRequest)
{
JSONObject response = JSONHandler.instance.GenerateContextJSON();
// Should better wait until context screenshot is available, but this works good enough
// yield return new WaitForSeconds(3);
yield return replyRequest(response, originalRequest);
}
public IEnumerator RunSimulation(JSONArray instructions, Func<JSONObject, JSONObject, IEnumerator> replyToRequest, JSONObject originalRequest)
{
recordTrajectories = true;
SceneController.recordTrajectories = true;
Debug.Log("[SceneController] RunSimulation called");
if (replyToRequest == null)
{
Debug.Log("[SceneController] replyToRequest is null");
}
SceneController.replyToRequestSimulation = replyToRequest;
SceneController.originalRequestSimulation = originalRequest;
schemaExecutor.RunSimulation(instructions, replyToRequest, originalRequest, this);
yield return null;
}
public void FinishSimulation(JSONArray instructions, Func<JSONObject, JSONObject, IEnumerator> replyToRequest, JSONObject originalRequest) {
Debug.Log("[SceneController] Finishing simulation");
JSONObject response = new JSONObject();
response.Add("trajectories.log", GetSchemasimLog());
response.Add("context", JSONHandler.instance.GenerateContextJSON());
response.Add("result", "Success!");
recordTrajectories = false;
yield return replyToRequest(response, originalRequest);
SceneController.recordTrajectories = false;
if (replyToRequest == null)
{
Debug.Log("[SceneController] Falling back to static replyToRequest");
replyToRequest = SceneController.replyToRequestSimulation;
}
if (originalRequest == null)
{
Debug.Log("[SceneController] Falling back to static originalRequest");
originalRequest = SceneController.originalRequestSimulation;
}
StartCoroutine(replyToRequest(response, originalRequest));
}
private JSONArray GetSchemasimLog()
{
Debug.Log("[SceneController::GetSchemasimLog] Preparing schemasim log");
Dictionary<string, List<JSONObject>> logs = new Dictionary<string, List<JSONObject>>();
int count = 0;
......@@ -179,6 +214,10 @@ public class SceneController : MonoBehaviour
logs.Add(ii.name, logData);
}
Debug.Log("[SceneController::GetSchemasimLog] Gathered individual logs");
Debug.Log("[SceneController::GetSchemasimLog] Gathering meta log");
JSONArray logRows = new JSONArray();
for (int t = 0; t < count; ++t)
{
......@@ -187,10 +226,13 @@ public class SceneController : MonoBehaviour
{
row.Add(log.Key, log.Value[t]);
}
row.Add("LOG_PHASE", t < metaLog.Count ? metaLog[t] : "UNKNOWN");
row.Add("LOG_PHASE", t < SceneController.metaLog.Count ? SceneController.metaLog[t] : "UNKNOWN");
logRows.Add(row);
}
metaLog = null;
SceneController.metaLog = null;
Debug.Log("[SceneController::GetSchemasimLog] Generated JSON log");
return logRows;
}
}
......
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using SimpleJSON;
using System;
using System.Collections;
using System.Collections.Generic;
namespace dlu
{
public class SchemaExecutor : MonoBehaviour
{
private static Dictionary<string, GameObject> namedObjects = null;
private static List<GameObject> animatedObjects = null;
private static bool animating;
private JSONArray instructions;
private Func<JSONObject, JSONObject, IEnumerator> replyToRequest;
private JSONObject originalRequest;
private static SceneController sceneController;
private static List<Vector3[]> paths = null;
public static GameObject dluGameObject = null;
void Awake()
{
SchemaExecutor.namedObjects = new Dictionary<string, GameObject>();
SchemaExecutor.animatedObjects = new List<GameObject>();
SchemaExecutor.paths = new List<Vector3[]>();
}
void Start()
{
SchemaExecutor.dluGameObject = GameObject.Find("DLU");
SchemaExecutor.sceneController = SchemaExecutor.dluGameObject.GetComponent<SceneController>();
Debug.Log($"[SchemaExecutor] DLU GameObject: {dluGameObject}");
}
void RefreshDictionary()
{
Debug.Log("[SchemaExecutor] Refreshing dictionary");
InstanceIdentifier[] instances = GameObject.FindObjectsOfType<InstanceIdentifier>();
SchemaExecutor.namedObjects = new Dictionary<string, GameObject>(instances.Length);
foreach (InstanceIdentifier ii in instances)
{
SchemaExecutor.namedObjects[ii.name] = ii.gameObject;
}
Debug.Log("[SchemaExecutor] Refreshed dictionary");
}
void Update()
{
if (SchemaExecutor.animating && SchemaExecutor.animatedObjects.Count == 0)
{
Debug.Log("[SchemaExecutor] Finished all animations. Sending response.");
SchemaExecutor.animating = false;
if (SchemaExecutor.sceneController != null)
{
SchemaExecutor.sceneController.FinishSimulation(instructions, replyToRequest, originalRequest);
}
else
{
Debug.Log("[SchemaExecutor] sceneController is null");
SceneController[] sc = GameObject.FindObjectsOfType<SceneController>();
if (sc.Length > 0)
{
Debug.Log("[SchemaExecutor] Found SceneController");
sc[0].FinishSimulation(instructions, replyToRequest, originalRequest);
}
else
{
Debug.Log("[SchemaExecutor] Could not find SceneController");
}
}
SchemaExecutor.paths.Clear();
}
}
private void Move(GameObject target, Vector3[] path)
{
Debug.Log($"[SchemaExecutor] Starting animation for {target}");
SchemaExecutor.animatedObjects.Add(target);
Debug.Log($"[SchemaExecutor] animatedObjects: {animatedObjects.Count}");
Debug.Log($"[SchemaExecutor] target: {target.name}");
Debug.Log($"[SchemaExecutor] oncompletetarget: {SchemaExecutor.dluGameObject}");
Debug.Log($"[SchemaExecutor] oncompleteparams: {target.name}");
Debug.Log($"[SchemaExecutor] paths: {paths.Count}");
Debug.Log($"[SchemaExecutor] path items: {path.Length}");
iTween.MoveTo(target,
iTween.Hash("path", path,
"easeType", "easeInOutExpo",
"oncomplete", "Done",
"oncompletetarget", SchemaExecutor.dluGameObject,
"oncompleteparams", target));
SchemaExecutor.paths.Add(path);
Debug.Log($"[SchemaExecutor] Animation started for {target}");
}
private Vector3[] AsPath(JSONArray path)
{
Vector3[] pathVec = new Vector3[path.Count];
for (int i = 0; i < path.Count; ++i)
{
pathVec[i] = new Vector3(path[i]["position"]["x"],
path[i]["position"]["y"],
path[i]["position"]["z"]);
}
return pathVec;
}
public void RunTestSimulation(JSONArray testJson)
{
RunSimulation(testJson, null, null, null);
}
public void RunSimulation(JSONArray instructions, Func<JSONObject, JSONObject, IEnumerator> replyToRequest, JSONObject originalRequest, SceneController sceneController)
{
Debug.Log("[SchemaExecutor] RunSimulation called");
this.instructions = instructions;
this.replyToRequest = replyToRequest;
this.originalRequest = originalRequest;
SchemaExecutor.sceneController = sceneController;
RefreshDictionary();
Debug.Log("[SchemaExecutor] Initializing animatedObjects");
SchemaExecutor.animatedObjects = new List<GameObject>(instructions.Count);
foreach (JSONObject instruction in instructions)
{
if (instruction["trajectory"] != null) {
string objName = instruction["trajectory"]["object"];
if (objName == null) {
Debug.Log("[SchemaExecutor] Missing trajectory.object in instructions JSON");
continue;
}
GameObject target = namedObjects[objName];
Debug.Log($"[SchemaExecutor] Moving {target.name}");
Move(target, AsPath(instruction["trajectory"]["trajectory"] as JSONArray));
} else {
Debug.Log($"[SchemaExecutor] Unhandeled instruction {instruction.ToString()}");
}
}
SchemaExecutor.animating = true;
}
public void Done(GameObject gameObject)
{
Debug.Log($"[SchemaExecutor] Animation for {gameObject} done.");
SchemaExecutor.animatedObjects.Remove(gameObject);
}
void OnDrawGizmos()
{
if (paths != null) {
foreach (Vector3[] path in paths)
{
iTween.DrawPathGizmos(path);
}
}
}
}
} // namespace dlu
\ No newline at end of file
fileFormatVersion: 2
guid: 3fe91f163c0534463a99fb7807b3dc2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment