浏览代码

[AIRO-284] add quick demo (#92)

* add quick demo scene and script

* updated tutorials
/devin-main-fix
GitHub 3 年前
当前提交
7c09f240
共有 14 个文件被更改,包括 680 次插入23 次删除
  1. 8
      tutorials/pick_and_place/0_ros_setup.md
  2. 3
      tutorials/pick_and_place/PickAndPlaceProject/ProjectSettings/ProjectSettings.asset
  3. 14
      tutorials/pick_and_place/README.md
  4. 2
      tutorials/pick_and_place/Scripts/SourceDestinationPublisher.cs
  5. 2
      tutorials/pick_and_place/Scripts/TrajectoryPlanner.cs
  6. 5
      tutorials/pick_and_place/docker/Dockerfile
  7. 344
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Scenes/DemoScene.unity
  8. 7
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Scenes/DemoScene.unity.meta
  9. 8
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts.meta
  10. 5
      tutorials/pick_and_place/docker/tutorial
  11. 61
      tutorials/pick_and_place/quick_demo.md
  12. 233
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts/Demo.cs
  13. 11
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts/Demo.cs.meta

8
tutorials/pick_and_place/0_ros_setup.md


1. Start the newly built Docker container:
```docker
docker run -it --rm -p 10000:10000 -p 5005:5005 unity-robotics:pick-and-place
docker run -it --rm -p 10000:10000 -p 5005:5005 unity-robotics:pick-and-place /bin/bash
1. Source your ROS workspace:
```bash
source devel/setup.bash
```
The ROS workspace is now ready to accept commands!

3
tutorials/pick_and_place/PickAndPlaceProject/ProjectSettings/ProjectSettings.asset


scriptingRuntimeVersion: 1
gcIncremental: 1
gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform: {}
apiCompatibilityLevelPerPlatform:
Standalone: 3
m_RenderingPath: 1
m_MobileRenderingPath: 1
metroPackageName: Template_3D

14
tutorials/pick_and_place/README.md


This tutorial is designed such that you do not need prior experience with Unity or C# in order to follow the scene setup steps, and you do not need prior robotics experience to get started with ROS integration. The tutorial is divided into high-level phases, from basic Unity and ROS initial setup through executing a pick-and-place task.
**Want to skip the tutorial and run the full demo? Check out our [Quick Demo](quick_demo.md)**
**Table of Contents**
### Pick-and-Place Tutorial
---
## Requirements

```
---
## [Part 0: ROS Setup](0_ros_setup.md)
<img src="img/0_docker.png" width="400"/>

---
## [Part 1: Create Unity scene with imported URDF](1_urdf.md)
<img src="img/1_end.gif" width="400"/>

---
---
## [Part 3: Pick-and-Place](3_pick_and_place.md)

2
tutorials/pick_and_place/Scripts/SourceDestinationPublisher.cs


/// <summary>
///
/// </summary>
void Awake()
void Start()
{
// Get ROS connection static instance
ros = ROSConnection.instance;

2
tutorials/pick_and_place/Scripts/TrajectoryPlanner.cs


/// Find all robot joints in Awake() and add them to the jointArticulationBodies array.
/// Find left and right finger joints and assign them to their respective articulation body objects.
/// </summary>
void Awake()
void Start()
{
// Get ROS connection static instance
ros = ROSConnection.instance;

5
tutorials/pick_and_place/docker/Dockerfile


COPY ./ROS/src/ros_tcp_endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint
COPY ./docker/set-up-workspace /setup.sh
COPY docker/tutorial /
RUN dos2unix /setup.sh && chmod +x /setup.sh && /setup.sh && rm /setup.sh
RUN dos2unix /tutorial /setup.sh && chmod +x /setup.sh && /setup.sh && rm /setup.sh
ENTRYPOINT ["/bin/bash"]
ENTRYPOINT ["/tutorial"]

344
tutorials/pick_and_place/PickAndPlaceProject/Assets/Scenes/DemoScene.unity


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &740283001
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 740283003}
- component: {fileID: 740283002}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &740283002
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 740283001}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &740283003
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 740283001}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &1442615935
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1442615937}
- component: {fileID: 1442615936}
m_Layer: 0
m_Name: Demo
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1442615936
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1442615935}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 985aa258640044abeb31b39efba08ea3, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1442615937
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1442615935}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0.86, z: 0.108267225}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2131306806
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2131306809}
- component: {fileID: 2131306808}
- component: {fileID: 2131306807}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &2131306807
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2131306806}
m_Enabled: 1
--- !u!20 &2131306808
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2131306806}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &2131306809
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2131306806}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

7
tutorials/pick_and_place/PickAndPlaceProject/Assets/Scenes/DemoScene.unity.meta


fileFormatVersion: 2
guid: b51a2f002143e4b29a388f9213209978
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts.meta


fileFormatVersion: 2
guid: 2de28984775bd450da317306900054b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

5
tutorials/pick_and_place/docker/tutorial


#!/bin/bash
source $ROS_WORKSPACE/devel/setup.bash
echo "ROS_IP: $(hostname -i)" > $ROS_WORKSPACE/src/niryo_moveit/config/params.yaml
exec "$@"

61
tutorials/pick_and_place/quick_demo.md


# Pick-and-Place Tutorial: Quick Demo
This part uses scripts to automatically set up and run the Niryo One pick-and-place demo in the Unity Editor.
**Table of Contents**
- [Prerequisites](#prerequisites)
- [Start ROS](#start-ros)
- [Start Demo](#start-demo)
## Prerequisites
1. Clone this repo to a location on your local machine:
```bash
git clone --recurse-submodules https://github.com/Unity-Technologies/Unity-Robotics-Hub.git
```
1. Install [Docker Engine](https://docs.docker.com/engine/install/)
1. Install [Unity Hub](https://unity3d.com/get-unity/download).
1. Go to the [Unity 2020.2 Beta website](https://unity3d.com/unity/beta/2020.2.0b9) to install this project's version of Unity: **2020.2.0b9**.
## Start ROS
1. Follow the [Option A: Use Docker](0_ros_setup.md#option-a-use-docker) to start a new ROS docker container
2. Run the following command to start ROS services
```bash
roslaunch niryo_moveit part_3.launch
```
## Start Demo
1. Open Unity Hub and click the "Add" button in the top right of the "Projects" tab on Unity Hub, and navigate to and select the PickAndPlaceProject directory (`./Unity-Robotics-Hub/tutorials/pick_and_place/PickAndPlaceProject/`) to add the tutorial project to your Hub.
![](img/hub_addproject.png)
1. Click the newly added project to open it.
1. Look for the `DemoScene` in the Project browser in the Assets/Scenes directory, and double-click to open it.
1. Click the `Play` button to watch the full demo.
> Note: the planning process will take about ten seconds before the Niryo One starts to move
> Note: several game objects will be created in the Hierarchy window at runtime
>
> * **Table**: the table where the robot stands on; instantiated from the Table prefab
> * **Target**: the cube that the robot is going to pick up; instantiated from the Target prefab
> * **TargetPlacement**: the area that the target cube will be placed; instantiation of the TargetPlacement prefab
> * **niryo_one**: the Niryo One robot imported from URDF
> * **ROSConnect**: the object that operates ROS communication
> * **Publisher**: the object that publish joint configurations to the ROS network for planning
> Note: the configurations of ROS communication can be found in the Inspector window of ROSConnect object
>
> * Joint configurations are published to ROS nodes running in the Docker container (127.0.0.1:10000)
> * ROS nodes in the Docker container will be notified that Unity's IP address is 127.0.0.1:5005
### If you'd now like to follow the full tutorial to learn how to build the pick-and-place simulation from scratch, proceed to [Part 1](1_urdf.md).

233
tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts/Demo.cs


#if UNITY_EDITOR
using Microsoft.CSharp;
using RosMessageGeneration;
using RosSharp;
using RosSharp.Control;
using RosSharp.Urdf.Editor;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;
public class Demo : MonoBehaviour
{
public string hostIP = "127.0.0.1";
public string overrideUnityIP = "127.0.0.1";
public bool generateRosMessages = true;
public bool deleteRosMessagesAfterSimulation = true;
string prefabDirectory = "Assets/Prefabs";
string prefabSuffix = ".prefab";
string tableName = "Table";
string targetName = "Target";
string targetPlacementName = "TargetPlacement";
string cameraName = "Main Camera";
Vector3 cameraPosition = new Vector3(0, 1.4f, -0.7f);
Quaternion cameraRotation = Quaternion.Euler(new Vector3(45, 0, 0));
string urdfRelativeFilepath = "URDF/niryo_one/niryo_one.urdf";
string niryoOneName = "niryo_one";
string baseLinkName = "base_link";
float controllerStiffness = 10000;
float controllerDamping = 100;
float controllerForceLimit = 1000;
float controllerSpeed = 30;
float controllerAcceleration = 10;
string rosMessagesDirectory = "Assets/RosMessages";
string rosSrcDirectory = "../ROS/src";
string msgDirectory = "msg";
string srvDirectory = "srv";
string moveitMsgPackageName = "moveit_msgs";
string niryoMoveitPackageName = "niryo_moveit";
string robotTrajectoryMessageFileName = "RobotTrajectory.msg";
string moverServiceFileName = "MoverService.srv";
string scriptPattern = "*.cs";
string externalScriptsDirectory = "../Scripts";
string scriptsDirectory = "Assets/Scripts";
string rosConnectName = "ROSConnect";
string publisherName = "Publisher";
int hostPort = 10000;
int unityPort = 5005;
int awaitDataMaxRetries = 10;
int awaitDataSleepSeconds = 1;
string trajectoryPlannerType = "TrajectoryPlanner";
string rosServiceName = "niryo_moveit";
bool hasPublished = false;
Assembly assembly;
ROSConnection rosConnection;
void Awake()
{
EditorApplication.LockReloadAssemblies();
SetupScene();
SetupRos();
CreateTrajectoryPlannerPubliser();
}
void Update()
{
// Make sure to publish only once in the demo
if (!hasPublished)
{
dynamic publisher = GameObject.Find(publisherName).GetComponent(assembly.GetType(trajectoryPlannerType));
publisher.PublishJoints();
hasPublished = true;
}
}
void OnApplicationQuit()
{
if (deleteRosMessagesAfterSimulation)
{
Directory.Delete(rosMessagesDirectory, recursive: true);
File.Delete($"{rosMessagesDirectory}.meta");
}
EditorApplication.UnlockReloadAssemblies();
}
// Tutorial Part 1
private void SetupScene()
{
// Instantiate the table, target, and target placement
GameObject table = InstantiatePrefab(tableName);
GameObject target = InstantiatePrefab(targetName);
GameObject targetPlacement = InstantiatePrefab(targetPlacementName);
// Adjust main camera
GameObject camera = GameObject.Find(cameraName);
camera.transform.position = cameraPosition;
camera.transform.rotation = cameraRotation;
// Import Niryo One with URDF importer
string urdfFilepath = Path.Combine(Application.dataPath, urdfRelativeFilepath);
ImportRobot(urdfFilepath, ImportSettings.convexDecomposer.unity);
// Adjust robot parameters
Controller controller = GameObject.Find(niryoOneName).GetComponent<Controller>();
controller.stiffness = controllerStiffness;
controller.damping = controllerDamping;
controller.forceLimit = controllerForceLimit;
controller.speed = controllerSpeed;
controller.acceleration = controllerAcceleration;
GameObject.Find(baseLinkName).GetComponent<ArticulationBody>().immovable = true;
}
// Tutorial Part 2 without the Publisher object
private void SetupRos()
{
if (generateRosMessages)
{
// Generate ROS messages
MessageAutoGen.GenerateSingleMessage(
Path.Combine(rosSrcDirectory, moveitMsgPackageName, msgDirectory, robotTrajectoryMessageFileName),
rosMessagesDirectory, moveitMsgPackageName);
MessageAutoGen.GenerateDirectoryMessages(
Path.Combine(rosSrcDirectory, niryoMoveitPackageName, msgDirectory),
rosMessagesDirectory);
// Generate ROS services
ServiceAutoGen.GenerateSingleService(
Path.Combine(rosSrcDirectory, niryoMoveitPackageName, srvDirectory, moverServiceFileName),
rosMessagesDirectory, niryoMoveitPackageName);
}
// Recompile ROS message scripts and external scripts
List<string> scripts = new List<string>();
scripts.AddRange(Directory.GetFiles(rosMessagesDirectory, scriptPattern, SearchOption.AllDirectories));
scripts.AddRange(Directory.GetFiles(externalScriptsDirectory));
RecompileScripts(scripts.ToArray());
// Create RosConnect
GameObject rosConnect = new GameObject(rosConnectName);
rosConnection = rosConnect.AddComponent<ROSConnection>();
rosConnection.rosIPAddress = hostIP;
rosConnection.rosPort = hostPort;
rosConnection.overrideUnityIP = overrideUnityIP;
rosConnection.unityPort = unityPort;
rosConnection.awaitDataMaxRetries = awaitDataMaxRetries;
rosConnection.awaitDataSleepSeconds = awaitDataSleepSeconds;
}
private void CreateTrajectoryPlannerPubliser()
{
GameObject publisher = new GameObject(publisherName);
dynamic planner = publisher.AddComponent(assembly.GetType(trajectoryPlannerType));
planner.rosServiceName = rosServiceName;
planner.niryoOne = GameObject.Find(niryoOneName);
planner.target = GameObject.Find(targetName);
planner.targetPlacement = GameObject.Find(targetPlacementName);
}
private GameObject InstantiatePrefab(string name)
{
string filepath = Path.Combine(prefabDirectory, $"{name}{prefabSuffix}");
GameObject gameObject = Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(filepath));
gameObject.name = name;
return gameObject;
}
private void ImportRobot(string urdfFilepath, ImportSettings.convexDecomposer convexDecomposer)
{
// Import Niryo One by URDF Importer
ImportSettings settings = new ImportSettings
{
choosenAxis = ImportSettings.axisType.yAxis,
convexMethod = convexDecomposer,
};
UrdfRobotExtensions.Create(urdfFilepath, settings);
}
// Credit to https://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime
// and https://gamedev.stackexchange.com/questions/130268/how-do-i-compile-a-c-script-at-runtime-and-attach-it-as-a-component-to-a-game-o
private void RecompileScripts(string[] filepaths)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
foreach (Assembly unityAssembly in AppDomain.CurrentDomain.GetAssemblies())
{
parameters.ReferencedAssemblies.Add(unityAssembly.Location);
}
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
string[] texts = new string[filepaths.Length];
for (int i = 0; i < filepaths.Length; i ++)
{
texts[i] = File.ReadAllText(filepaths[i]);
}
CompilerResults results = provider.CompileAssemblyFromSource(parameters, texts);
checkCompileErrors(results);
// Update the assembly
assembly = results.CompiledAssembly;
}
private void checkCompileErrors(CompilerResults results)
{
if (results.Errors.HasErrors)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
stringBuilder.AppendLine($"Error {error.ErrorNumber} {error.ErrorText}");
}
throw new InvalidOperationException(stringBuilder.ToString());
}
}
}
#endif

11
tutorials/pick_and_place/PickAndPlaceProject/Assets/Scripts/Demo.cs.meta


fileFormatVersion: 2
guid: 985aa258640044abeb31b39efba08ea3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存