├── README.md ├── Scripts ├── Billboard.cs ├── Button.cs ├── ClearManager.cs ├── CursorFeedback.cs ├── CursorManager.cs ├── DirectionIndicator.cs ├── GazeManager.cs ├── GazeStabilizer.cs ├── GestureAction.cs ├── GestureManager.cs ├── HandsManager.cs ├── Interactible.cs ├── InteractibleManager.cs ├── PADManager.cs ├── ResetManager.cs ├── Singleton.cs ├── Source.cs ├── SpatialMapping.cs ├── TapToPlace.cs ├── TextManager.cs └── tipText.cs └── holoROS.zip /README.md: -------------------------------------------------------------------------------- 1 | # holoROS 2 | 3 | ROS integration with HoloLens 4 | 5 | This project aimed the integration between ROS and the Microsoft augmented reality glass, HoloLens. The goal was to be able to access and obtain full control of a ROS node from HL. The chosen node was the turtlesim, a default node that mostly ROS users have access. 6 | The idea was to build a HL application that could simulate and control the turtlesim node using HL features. HL apps are built and deployed to the device using Unity, so the environment needed to be built using this game engine. The turtlesim environment built in Unity consists in: 7 | 8 | • A background plane that simulates the 2D blue plane where the turtle can move in ROS. 9 | 10 | • A cube that simulates the turtle. 11 | 12 | • 3 buttons responsible for connecting/disconnecting, clearing and resetting. 13 | 14 | • A DPAD, an additional option for moving the turtle 15 | 16 | In this application some HL features are being used. The gesture manipulator applied on the cube is responsible for the movement. Gazing on the DPAD can also move the cube. The select gesture on the connector button is responsible for starting and finishing a ROS connection, on the reset button can take the cube to the initial position and on the clear button can clear the ROS turtle path. A select gesture can also be applied in the plane, while there is no connection with ROS, so that the user can place the turtlesim environment around the world. 17 | The connection between HL and ROS is made through Rosbridge. Rosbridge provides a JSON API to ROS functionality for non-ROS programs. In this project we are accessing the ROS service “teleport_absolute” to move the cube, where the turtle position in ROS is constantly updated based on the cube position in the simulated ROS environment running on HL. To clear the ROS environment, we are accessing the ROS service “clean”. 18 | It is also possible to access ROS and move the turtle while on Unity Play mode. Press “C” to connect with ROS, move the turtle with WASD, press “E” to disconnect, “I” to return to the initial position and “R” to clear. 19 | Instructions 20 | To run this project, you will need: 21 | 22 | • Unity Hololens 5.4.0b16-HTP 23 | 24 | • Linux running ROS (I am using ROS Jade running on a Ubuntu VM mounted on HyperV-Manager). 25 | 26 | • Microsoft HoloLens device or emulator 27 | 28 | • holoROS.zip folder 29 | 30 | 1) Configure and open the Unity Project: 31 | 32 | • Extract the holoROS folder. 33 | 34 | • Open Unity. 35 | 36 | • Select Open. 37 | 38 | • Select the holoROS folder you previously extracted. 39 | 40 | • Unity will open the project. There is a scene ready to go. 41 | 42 | • Select the Scenes folder and double-click the holoConnection scene. 43 | 44 | • The scene will load. 45 | 46 | • In Unity select File > Build Settings. 47 | 48 | • Select Windows Store in the Platform list and click Switch Platform. 49 | 50 | • Set SDK to Universal 10 and Build Type to D3D. 51 | 52 | • Check Unity C# Projects. 53 | 54 | • If there isn’t any scene loaded, click Add Open Scenes to add the scene. 55 | 56 | • Close the Build Settings window. 57 | 58 | • Go to Edit > Project Settings > Player 59 | 60 | • In the “Other Settings” tab, find “Rendering” to make sure “Use 16-bit Depth Buffers” and “Virtual Reality Supported” are checked and “Windows Holographic” is added. 61 | 62 | • In the “Publishing Settings” tab, find “Capabilities” to make sure “InternetClient”, “InternetClientServer”, “PrivateNetworkClientServer” and “SpatialPerception” are checked. 63 | 64 | • Go to Edit > Project Settings > Quality 65 | 66 | • Make sure Windows Store App level is set to Fastest. 67 | 68 | 2) ROS IP address 69 | 70 | • Before deploying your app to HoloLens or running in Unity play mode, remember to check your VM ROS IP address. 71 | 72 | • With ROS installed and running, open a terminal and type “ifconfig”. You should see and use the first provided “inet addr” on your code. 73 | 74 | • To do this, simply change the value of the “host” variable on Source.cs (Scripts folder) for the desired value. 75 | 76 | 3) ROS Commands 77 | 78 | • With ROS installed, running and the right IP address configured you should run the following commands on ROS terminal before trying a connection: (Note: Rosbridge package need to be installed. For further information, visit: http://wiki.ros.org/rosbridge_suite) 79 | 80 | • source /opt/ros/jade/setup.bash (Using ROS Jade) 81 | 82 | • roscore 83 | 84 | • *new terminal* 85 | 86 | • rosmake turtlesim 87 | 88 | • rosrun turtlesim turtlesim_node 89 | 90 | • *new terminal* 91 | 92 | • roslaunch rosbridge_server rosbridge_websocket.launch 93 | 94 | 4) Connecting and running on HoloLens or Unity Play Mode 95 | 96 | After all the previous steps implemented you should be able to connect and access ROS from HoloLens or Unity Play Mode. Since this HL app is deployed through Unity, it is easier to test the connection in Unity Play mode before deploying it to HL, but you can directly deploy the Unity project to HL without step a). 97 | 98 | a) Connecting and running on Unity Play Mode 99 | 100 | • In Unity, press the play button to enter in Unity Play Mode. You should see the rosturtle environment with a white plane, the connector, reset and clear button and the DPAD. 101 | 102 | • Now, press “C” to connect. If everything works fine, you should see that the plane turned to blue, a cube appeared in the center of the plane, the connector button is now highlighted and you can see in the Rosbridge node on ROS that now we have a client connected. 103 | 104 | • As you use WASD you should be able to move the turtle. 105 | 106 | • To clean the path left by the turtle, press “R”. 107 | 108 | • To return to the initial position, press “I”. 109 | 110 | • If you wish to disconnect from the ROS environment, press “E” or exit Unity play mode. After that, you should be able to see in the Rosbridge node on ROS that a client disconnected. 111 | 112 | b) Connecting and running on HoloLens 113 | 114 | • In Unity select File > Build Settings. 115 | 116 | • Click Build 117 | 118 | • In the file explorer window that appears, create a New Folder named "App". 119 | 120 | • Single click the App Folder. 121 | 122 | • Press Select Folder. 123 | 124 | • When Unity is done, a File Explorer window will appear. 125 | 126 | • Open the App folder. 127 | 128 | • Open (double click) holoConnection.sln. 129 | 130 | • Using the top toolbar in Visual Studio, change the target from Debug to Release and from ARM to X86. 131 | 132 | • Click on the arrow next to the Device button, and select Remote Device. 133 | 134 | • Set the Address to the name or IP address of your HoloLens. If you do not know your device IP address, look in Settings > Network & Internet > Advanced Options or ask Cortana "Hey Cortana, What's my IP address?" 135 | 136 | • Leave the Authentication Mode set to Universal. 137 | 138 | • Click Select 139 | 140 | • Click Debug > Start Without debugging or press Ctrl + F5. If this is the first time deploying to your device, you will need to pair it with Visual Studio. 141 | 142 | • The project will now build, deploy to your HoloLens, and then run. 143 | 144 | • Put on your HoloLens and look around to see your new holograms. Try to look to a “cleaner” environment so that the hologram does not appear behind a wall or other obstacle from the beginning. 145 | 146 | • You should see the rosturtle environment with a white plane, the connector, reset and clear button, the DPAD and virtual meshes draw around you. 147 | 148 | • While we are not connected, if you perform a Select gesture in the white plane, we enter in the placing mode. You should now be able to place the rosturtle environment in a specific location by gazing at it, using the Select gesture and then moving to a new location, and using the Select gesture again. Try to place the environment in a position where none of its area gets compromised by the virtual meshes. The movement of the cube/turtle can be compromised by interferences with unwanted meshes particles. 149 | 150 | • After placing the environment in a desired position, perform a select gesture in the connector button. If everything works fine, you should see that the plane turned to blue, a cube appeared in the center of the plane, the connector button is now highlighted and you can see in the Rosbridge node on ROS that now we have a client connected. 151 | 152 | • Now you are able to move the cube. For this, you have two options: 153 | 154 | • Gazing at the DPAD: Gaze at the arrows and see how the turtle moves in the hologram and ROS simultaneously, accordingly to the arrow you are gazing. 155 | 156 | • Gesture action: If you gaze at the cube, four arrows should appear around the cursor to indicate that the program will now respond to Manipulation events. Lower your index finger down to your thumb, and keep them pinched together. As you move your hand around, the cube will move too, as the ROS turtle. Raise your index finger to stop manipulating the cube. 157 | 158 | • To clean the path left by the turtle, perform a select gesture on the clear button on the top of the plane. 159 | 160 | • To return to the initial position, perform a select gesture on the reset button on the top of the plane. 161 | 162 | • If you wish to disconnect from the ROS environment, perform another select gesture in the connector button that is now highlighted. After that, the button and the plane should return to its standard state and you should be able to see in the Rosbridge node in ROS that a client disconnected. While disconnected you can enter in placing mode and place the environment anywhere you want (as long it is in a position where none of its area gets compromised by the virtual meshes) and connect to ROS again. 163 | 164 | Gabriel Santos Solia 165 | 166 | Doubts? gabriel.solia@gmail.com 167 | -------------------------------------------------------------------------------- /Scripts/Billboard.cs: -------------------------------------------------------------------------------- 1 | //Based on the class originated from github.com/Microsoft/HoloToolkit-Unity/ 2 | //The Billboard class implements the behaviors needed to keep the ROS environment oriented towards the user. 3 | 4 | using UnityEngine; 5 | 6 | namespace Scripts 7 | { 8 | public enum PivotAxis 9 | { 10 | // Rotate about all axes. 11 | Free, 12 | // Rotate about an individual axis. 13 | X, 14 | Y 15 | } 16 | 17 | public class Billboard : MonoBehaviour 18 | { 19 | // The axis about which the object will rotate. 20 | [Tooltip("Specifies the axis about which the object will rotate (Free rotates about both X and Y).")] 21 | public PivotAxis PivotAxis = PivotAxis.Free; 22 | 23 | // Overrides the cached value of the GameObject's default rotation. 24 | public Quaternion DefaultRotation { get; private set; } 25 | 26 | private void Awake() 27 | { 28 | // Cache the GameObject's default rotation. 29 | DefaultRotation = gameObject.transform.rotation; 30 | } 31 | // The billboard logic is performed in FixedUpdate to update the object 32 | // with the player independent of the frame rate. This allows the object to 33 | // remain correctly rotated even if the frame rate drops. 34 | private void FixedUpdate() 35 | { 36 | // Get a Vector that points from the Camera to the Target. 37 | Vector3 directionToTarget = Camera.main.transform.position - gameObject.transform.position; 38 | 39 | // Adjust for the pivot axis. 40 | switch (PivotAxis) 41 | { 42 | case PivotAxis.X: 43 | directionToTarget.x = gameObject.transform.position.x; 44 | break; 45 | 46 | case PivotAxis.Y: 47 | directionToTarget.y = gameObject.transform.position.y; 48 | break; 49 | 50 | case PivotAxis.Free: 51 | default: 52 | break; 53 | } 54 | 55 | // Calculate and apply the rotation required to reorient the object and apply the default rotation to the result. 56 | gameObject.transform.rotation = Quaternion.LookRotation(-directionToTarget) * DefaultRotation; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Scripts/Button.cs: -------------------------------------------------------------------------------- 1 | //Based on the class originated from github.com/Microsoft/HoloToolkit-Unity/ 2 | //The button class controls the state of all the button used in the project. 3 | 4 | using UnityEngine; 5 | using Scripts; 6 | using UnityEngine.Events; 7 | 8 | public class Button : Singleton