浏览代码

Add linter (#227)

* Add linter and pre-commit hooks

* Formatting

* Remove setting up ruby
/dev-backup
GitHub 3 年前
当前提交
ce803d3b
共有 38 个文件被更改,包括 366 次插入240 次删除
  1. 2
      .github/PULL_REQUEST_TEMPLATE.md
  2. 2
      .gitignore
  3. 14
      CONTRIBUTING.md
  4. 10
      README.md
  5. 2
      faq.md
  6. 28
      tutorials/pick_and_place/0_ros_setup.md
  7. 22
      tutorials/pick_and_place/1_urdf.md
  8. 58
      tutorials/pick_and_place/2_ros_tcp.md
  9. 30
      tutorials/pick_and_place/3_pick_and_place.md
  10. 34
      tutorials/pick_and_place/4_pick_and_place.md
  11. 4
      tutorials/pick_and_place/PickAndPlaceProject/Assets/Tests/EditMode/PickAndPlaceMessageGenerationtests.cs
  12. 2
      tutorials/pick_and_place/PickAndPlaceProject/Assets/URDF/niryo_one/niryo_one_urdf/README.md
  13. 8
      tutorials/pick_and_place/README.md
  14. 6
      tutorials/pick_and_place/ROS/src/niryo_moveit/README.md
  15. 2
      tutorials/pick_and_place/ROS/src/niryo_one_urdf/README.md
  16. 16
      tutorials/pick_and_place/Scripts/SourceDestinationPublisher.cs
  17. 30
      tutorials/pick_and_place/Scripts/TrajectoryPlanner.cs
  18. 26
      tutorials/pick_and_place/Scripts_Part4/RealSimPickAndPlace.cs
  19. 12
      tutorials/pick_and_place/moveit_file_descriptions.md
  20. 10
      tutorials/pick_and_place/quick_demo.md
  21. 6
      tutorials/quick_setup.md
  22. 2
      tutorials/ros_unity_integration/network.md
  23. 8
      tutorials/ros_unity_integration/publisher.md
  24. 8
      tutorials/ros_unity_integration/server_endpoint.md
  25. 2
      tutorials/ros_unity_integration/service.md
  26. 10
      tutorials/ros_unity_integration/setup.md
  27. 4
      tutorials/ros_unity_integration/subscriber.md
  28. 4
      tutorials/ros_unity_integration/unity_scripts/RosPublisherExample.cs
  29. 4
      tutorials/ros_unity_integration/unity_scripts/RosServiceExample.cs
  30. 36
      tutorials/ros_unity_integration/unity_scripts/RosSubscriberExample.cs
  31. 4
      tutorials/ros_unity_integration/unity_scripts/RosUnityServiceExample.cs
  32. 22
      tutorials/ros_unity_integration/unity_service.md
  33. 42
      tutorials/urdf_importer/urdf_appendix.md
  34. 10
      tutorials/urdf_importer/urdf_tutorial.md
  35. 75
      .editorconfig
  36. 32
      .pre-commit-config.yaml
  37. 19
      .github/workflows/pre-commit.yaml

2
.github/PULL_REQUEST_TEMPLATE.md


## Testing and Verification
Please describe the tests that you ran to verify your changes. Please also provide instructions, ROS packages, and Unity project files as appropriate so we can reproduce the test environment.
Please describe the tests that you ran to verify your changes. Please also provide instructions, ROS packages, and Unity project files as appropriate so we can reproduce the test environment.
### Test Configuration:
- Unity Version: [e.g. Unity 2020.2.0f1]

2
.gitignore


.swp
.idea
.vscode/
tutorials/pick_and_place/PickAndPlaceProject/Packages/packages-lock.json
tutorials/pick_and_place/PickAndPlaceProject/Packages/packages-lock.json

14
CONTRIBUTING.md


# Contribution Guidelines
Thank you for your interest in contributing to Unity Robotics! To facilitate your
contributions, we've outlined a brief set of guidelines to ensure that your extensions
Thank you for your interest in contributing to Unity Robotics! To facilitate your
contributions, we've outlined a brief set of guidelines to ensure that your extensions
can be easily integrated.
## Communication

All Python code should follow the [PEP 8 style guidelines](https://pep8.org/).
All C# code should follow the [Microsoft C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions).
Additionally, the [Unity Coding package](https://docs.unity3d.com/Packages/com.unity.coding@0.1/manual/index.html)
can be used to format, encode, and lint your code according to the standard Unity
development conventions. Be aware that these Unity conventions will supersede the
All C# code should follow the [Microsoft C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions).
Additionally, the [Unity Coding package](https://docs.unity3d.com/Packages/com.unity.coding@0.1/manual/index.html)
can be used to format, encode, and lint your code according to the standard Unity
development conventions. Be aware that these Unity conventions will supersede the
Microsoft C# Coding Conventions where applicable.
Please note that even if the code you are changing does not adhere to these guidelines,

## Contribution review
Once you have a change ready following the above ground rules, simply make a
Once you have a change ready following the above ground rules, simply make a
pull request in GitHub.

10
README.md


| [Quick Installation Instructions](tutorials/quick_setup.md) | Brief steps on installing the Unity Robotics packages |
| [Pick-and-Place Demo](tutorials/pick_and_place/README.md) | A complete end-to-end demonstration, including how to set up the Unity environment, how to import a robot from URDF, and how to set up two-way communication with ROS for control |
| [ROS–Unity Integration](tutorials/ros_unity_integration/README.md) | A set of component-level tutorials showing how to set up communication between ROS and Unity |
| [URDF Importer](tutorials/urdf_importer/urdf_tutorial.md) | Steps on using the Unity package for loading [URDF](http://wiki.ros.org/urdf) files |
| [URDF Importer](tutorials/urdf_importer/urdf_tutorial.md) | Steps on using the Unity package for loading [URDF](http://wiki.ros.org/urdf) files |
| [Articulations Robot Demo](https://github.com/Unity-Technologies/articulations-robot-demo) | A robot simulation demonstrating Unity's new physics solver (no ROS dependency)

- (August 26, 2020)
Announcing Unity Robotic Simulation [blog post](https://unity.com/solutions/automotive-transportation-manufacturing/robotics)
- (May 20, 2020)
Use articulation bodies to easily prototype industrial designs with realistic motion and behavior [blog post](https://blogs.unity3d.com/2020/05/20/use-articulation-bodies-to-easily-prototype-industrial-designs-with-realistic-motion-and-behavior/)
Use articulation bodies to easily prototype industrial designs with realistic motion and behavior [blog post](https://blogs.unity3d.com/2020/05/20/use-articulation-bodies-to-easily-prototype-industrial-designs-with-realistic-motion-and-behavior/)
### More from Unity

## Community and Feedback
The Unity Robotics projects are open-source and we encourage and welcome contributions.
If you wish to contribute, be sure to review our [contribution guidelines](CONTRIBUTING.md)
The Unity Robotics projects are open-source and we encourage and welcome contributions.
If you wish to contribute, be sure to review our [contribution guidelines](CONTRIBUTING.md)
and [code of conduct](CODE_OF_CONDUCT.md).
## Support

For feature requests, bugs, or other issues, please file a [GitHub issue](https://github.com/Unity-Technologies/Unity-Robotics-Hub/issues) using the provided templates and the Robotics team will investigate as soon as possible.
For any other questions or feedback, connect directly with the
For any other questions or feedback, connect directly with the
Robotics team at [unity-robotics@unity3d.com](mailto:unity-robotics@unity3d.com).
## License

2
faq.md


---
Two of the Unity Robotics repos (URDF Importer and TCP Connector) have been forked from the [Siemens ROS# repo](https://github.com/siemens/ros-sharp).
In the URDF Importer we have added the functionality to instantiate a robot from URDF into a Unity scene with [Articulation Body](https://docs.unity3d.com/2020.2/Documentation/Manual/class-ArticulationBody.html) components on their corresponding joints.
In the URDF Importer we have added the functionality to instantiate a robot from URDF into a Unity scene with [Articulation Body](https://docs.unity3d.com/2020.2/Documentation/Manual/class-ArticulationBody.html) components on their corresponding joints.
Aside from facilitating communication with the TCP Endpoint, the TCP Connector contains the `MessageGeneration` code from ROS#. We added the extra functionality that when generating a C# class from a ROS message, functions are also generated that will serialize and deserialize the messages as ROS would internally.

28
tutorials/pick_and_place/0_ros_setup.md


# Pick-and-Place Tutorial: Part 0
This part provides two options for setting up your ROS workspace: using Docker, or manually setting up a catkin workspace.
**Table of Contents**
- [Option A: Use Docker](#option-a-use-docker)
- [Option B: Manual Setup](#option-b-manual-setup)

docker build -t unity-robotics:pick-and-place -f docker/Dockerfile .
```
> Note: The provided Dockerfile uses the [ROS Melodic base Image](https://hub.docker.com/_/ros/). Building the image will install the necessary packages, copy the [provided ROS packages and submodules](ROS/) to the container, and build the catkin workspace.
1. Start the newly built Docker container:
> Note: The provided Dockerfile uses the [ROS Melodic base Image](https://hub.docker.com/_/ros/). Building the image will install the necessary packages, copy the [provided ROS packages and submodules](ROS/) to the container, and build the catkin workspace.
1. Start the newly built Docker container:
When this is complete, it will print: `Successfully tagged unity-robotics:pick-and-place`. This console should open into a bash shell at the ROS workspace root, e.g. `root@8d88ed579657:/catkin_ws#`.
When this is complete, it will print: `Successfully tagged unity-robotics:pick-and-place`. This console should open into a bash shell at the ROS workspace root, e.g. `root@8d88ed579657:/catkin_ws#`.
The ROS workspace is now ready to accept commands!

1. Navigate to the `/PATH/TO/Unity-Robotics-Hub/tutorials/pick_and_place/ROS` directory of this downloaded repo.
1. Navigate to the `/PATH/TO/Unity-Robotics-Hub/tutorials/pick_and_place/ROS` directory of this downloaded repo.
- If you cloned the project and forgot to use `--recurse-submodules`, or if any submodule in this directory doesn't have content, you can run the command `git submodule update --init --recursive` to download packages for Git submodules.
- If you cloned the project and forgot to use `--recurse-submodules`, or if any submodule in this directory doesn't have content, you can run the command `git submodule update --init --recursive` to download packages for Git submodules.
1. The provided files require the following packages to be installed. ROS Melodic users should run the following commands if the packages are not already present:
```bash

1. If you have not already built and sourced the ROS workspace since importing the new ROS packages, navigate to your ROS workplace, and run `catkin_make && source devel/setup.bash`. Ensure there are no errors.
1. The ROS parameters will need to be set to your configuration in order to allow the server endpoint to fetch values for the TCP connection, stored in `src/niryo_moveit/config/params.yaml`. From your ROS workspace, assign the ROS IP in this `yaml` file:
```bash
echo "ROS_IP: $(hostname -I)" > src/niryo_moveit/config/params.yaml
```

```yaml
ROS_IP: <your ROS IP>
```
e.g.
```yaml

## Troubleshooting
- Building the Docker image may throw an `Could not find a package configuration file provided by...` exception if one or more of the directories in ROS/ appears empty. Try downloading the submodules again via `git submodule update --init --recursive`.
- If the ROS TCP handshake fails (e.g. `ROS-Unity server listening...` printed on the Unity side but no `ROS-Unity Handshake received` on the ROS side), the ROS IP may not have been set correctly in the params.yaml file. Try running `echo "ROS_IP: $(hostname -I)" > src/niryo_moveit/config/params.yaml` in a terminal from your ROS workspace.
---

- Setting up a ROS workspace:
> Note: this tutorial has been tested with ROS Melodic as well as ROS Noetic.
- http://wiki.ros.org/ROS/Installation
- http://wiki.ros.org/ROS/Tutorials/InstallingandConfiguringROSEnvironment

22
tutorials/pick_and_place/1_urdf.md


```
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**.
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**.
1. Click the "Add" button in the top right of the "Projects" tab on Unity Hub, and navigate to and select the PickAndPlaceProject directory within this cloned repository (`/PATH/TO/Unity-Robotics-Hub/tutorials/pick_and_place/PickAndPlaceProject/`) to add the tutorial project to your Hub.
![](img/hub_addproject.png)

1. In the Unity Project window, navigate to `Assets/Prefabs`. Select the Table prefab, and click and drag it into the Hierarchy window. The table should appear in the Scene view. Then, select and drag the Target into the Hierarchy window, as well as the TargetPlacement. They should appear to sit on the table.
![](img/1_cube.png)
![](img/1_cube.png)
1. Select the `Main Camera` in the Hierarchy. Move the camera to a more convenient location for viewing the robot by assigning the `Main Camera`'s Position to `(0, 1.4, -0.7)`, and the Rotation to `(45, 0, 0)` in the Inspector, which can be found in the Transform component.

## Setting Up the Robot
## Setting Up the Robot
> Note: Presumably when you opened this project, the Package Manager automatically checked out and built the URDF-Importer package for you. You can double-check this now by looking for `Packages/URDF-Importer` in the Project window or by opening the Package Manager window. See the [Quick Setup](../quick_setup.md) steps for adding this package to your own project.

1. Find and select the URDF file in the Project window (`Assets/URDF/niryo_one/niryo_one.urdf`). From the menu, click `Assets -> Import Robot from URDF`, or in the Project window, right click on the selected file and click `Import Robot from URDF`.
> Note: The file extension may not appear in the Project window. The niryo_one.urdf file will appear in the root of the `Assets/URDF/niryo_one` directory.
> Note: Default mesh orientation is Y-up, which is supported by Unity, but some packages often use Z-up and X-up configuration.
> Note: VHACD algorithm produces higher quality convex hull for collision detection than the default algorithm.

1. Select the newly imported `niryo_one` object in the Scene Hierarchy, and from the Inspector window, find the Controller (Script) component. Set the Stiffness to `10000`, the Damping to `100` and `Force Limit` to `1000`. Set the Speed to `30` and the Acceleration to `10`.
> Note: You can find information on how these parameters are used in calculations by articulation bodies by referencing [this](https://github.com/Unity-Technologies/Unity-Robotics-Hub/blob/master/tutorials/urdf_importer/urdf_appendix.md#guide-to-write-your-own-controller) technical guide for writing a custom controller. For our purposes, these settings will allow the robot to stay in position without the joints slipping.
1. In the Hierarchy window, click the arrow to the left of the name to expand the GameObject tree, down to `niryo_one/world/base_link`. Toggle on `Immovable` for the `base_link`.
![](img/1_base.png)

1. Press the Play button at the top of the Unity Editor to enter Play Mode. If everything imported correctly, no errors should appear in the Console window. The robot arm should stay “mounted” to the table, and nothing should fall through the floor.
Using the Controller, joints can be selected using the arrow keys. Use the left/right arrow keys to navigate through the joints, where the selected index will be highlighted in red. Use the up/down arrow keys to control the selected joint movement. The Controller script on the niryo_one object will describe the actively `Selected Index` as well as the `Joint Name`.
![](img/1_end.gif)

## Troubleshooting
- If you are not seeing `Import Robot from URDF` in the `Assets` menu, check the console for compile errors. The project must compile correctly before the editor tools become available.
- If you are not seeing `Import Robot from URDF` in the `Assets` menu, check the console for compile errors. The project must compile correctly before the editor tools become available.
- If the robot appears loose/wiggly or is not moving with no console errors, ensure that the Stiffness and Damping values on the Controller script of the `niryo_one` object are set to `10000` and `100`, respectively.
---

58
tutorials/pick_and_place/2_ros_tcp.md


## The Unity Side
1. If you have not already completed the steps in [Part 0](0_ros_setup.md) to set up your ROS workspace and [Part 1](1_urdf.md) to set up the Unity project, do so now.
1. If you have not already completed the steps in [Part 0](0_ros_setup.md) to set up your ROS workspace and [Part 1](1_urdf.md) to set up the Unity project, do so now.
1. If the PickAndPlaceProject Unity project is not already open, select and open it from the Unity Hub.

![](img/2_menu.png)
In the ROS Message Browser window, click `Browse` next to the ROS message path. Navigate to and select the ROS directory of this cloned repository (`Unity-Robotics-Hub/tutorials/pick_and_place/ROS/`). This window will populate with all msg and srv files found in this directory.
In the ROS Message Browser window, click `Browse` next to the ROS message path. Navigate to and select the ROS directory of this cloned repository (`Unity-Robotics-Hub/tutorials/pick_and_place/ROS/`). This window will populate with all msg and srv files found in this directory.
1. Next, the custom message scripts for this tutorial will need to be generated.
1. Next, the custom message scripts for this tutorial will need to be generated.
1. Finally, now that the messages have been generated, we will create the service for moving the robot.
1. Finally, now that the messages have been generated, we will create the service for moving the robot.
Still in the ROS Message Browser window, expand `ROS/src/niryo_moveit/srv` to view the srv file listed. Next to srv, click `Build 1 srv`.
Still in the ROS Message Browser window, expand `ROS/src/niryo_moveit/srv` to view the srv file listed. Next to srv, click `Build 1 srv`.
- Two new C# scripts should populate the `Assets/RosMessages/NiryoMoveit/srv` directory: MMoverServiceRequest and MMoverServiceResponse. These files describe the expected input and output formats for the service requests and responses when calculating trajectories.
- Two new C# scripts should populate the `Assets/RosMessages/NiryoMoveit/srv` directory: MMoverServiceRequest and MMoverServiceResponse. These files describe the expected input and output formats for the service requests and responses when calculating trajectories.
> MessageGeneration generates two C# classes, a request and response, from a ROS srv file with protections for use of C# reserved keywords and conversion to C# datatypes. Learn more about [ROS Services](https://wiki.ros.org/Services).
You can now close the ROS Message Browser window.

}
```
> This function first takes in the current joint target values. Then, it grabs the poses of the `target` and the `targetPlacement` objects, adds them to the newly created message `sourceDestinationMessage`, and calls `Send()` to send this information to the ROS topic `topicName` (defined as `"SourceDestination_input"`).
> This function first takes in the current joint target values. Then, it grabs the poses of the `target` and the `targetPlacement` objects, adds them to the newly created message `sourceDestinationMessage`, and calls `Send()` to send this information to the ROS topic `topicName` (defined as `"SourceDestination_input"`).
1. Return to the Unity Editor. Now that the message contents have been defined and the publisher script added, it needs to be added to the Unity world to run its functionality.
1. Return to the Unity Editor. Now that the message contents have been defined and the publisher script added, it needs to be added to the Unity world to run its functionality.
Right click in the Hierarchy window and select "Create Empty" to add a new empty GameObject. Name it `Publisher`. Add the newly created SourceDestinationPublisher component to the Publisher GameObject by selecting the Publisher object. Click "Add Component" in the Inspector, and begin typing "SourceDestinationPublisher." Select the component when it appears.
Right click in the Hierarchy window and select "Create Empty" to add a new empty GameObject. Name it `Publisher`. Add the newly created SourceDestinationPublisher component to the Publisher GameObject by selecting the Publisher object. Click "Add Component" in the Inspector, and begin typing "SourceDestinationPublisher." Select the component when it appears.
1. Note that this component shows empty member variables in the Inspector window, which need to be assigned.
1. Note that this component shows empty member variables in the Inspector window, which need to be assigned.
1. Next, the ROS TCP connection needs to be created. Select `Robotics -> ROS Settings` from the top menu bar.
1. Next, the ROS TCP connection needs to be created. Select `Robotics -> ROS Settings` from the top menu bar.
In the ROS Settings window, the `ROS IP Address` should be the IP address of your ROS machine (*not* the one running Unity).

![](img/2_settings.png)
Opening the ROS Settings has created a ROSConnectionPrefab in `Assets/Resources` with the user-input settings. When the static `ROSConnection.instance` is referenced in a script, if a `ROSConnection` instance is not already present, the prefab will be instantiated in the Unity scene, and the connection will begin.
1. Next, we will add a UI element that will allow user input to trigger the `Publish()` function. In the Hierarchy window, right click to add a new UI > Button. Note that this will create a new Canvas parent as well.
1. Next, we will add a UI element that will allow user input to trigger the `Publish()` function. In the Hierarchy window, right click to add a new UI > Button. Note that this will create a new Canvas parent as well.
> Note: In case the Button does not start in the bottom left, it can be moved by setting the `Pos X` and `Pos Y` values in its Rect Transform component. For example, setting its Position to `(-200, -200, 0)` would set its position to the bottom right area of the screen.
> Note: In case the Button does not start in the bottom left, it can be moved by setting the `Pos X` and `Pos Y` values in its Rect Transform component. For example, setting its Position to `(-200, -200, 0)` would set its position to the bottom right area of the screen.
1. Select the newly made Button object, and scroll to see the Button component in the Inspector. Click the `+` button under the empty `OnClick()` header to add a new event. Select the `Publisher` object in the Hierarchy window and drag it into the new OnClick() event, where it says `None (Object)`. Click the dropdown where it says `No Function`. Select SourceDestinationPublisher > `Publish()`.
![](img/2_onclick.png)

roslaunch niryo_moveit part_2.launch
```
> Note: Running `roslaunch` automatically starts [ROS Core](http://wiki.ros.org/roscore) if it is not already running.
> Note: Running `roslaunch` automatically starts [ROS Core](http://wiki.ros.org/roscore) if it is not already running.
> Note: This launch file has been copied below for reference. The server_endpoint and trajectory_subscriber nodes are launched from this file, and the ROS params (set up in [Part 0](0_ros_setup.md)) are loaded from this command. The launch files for this project are available in the package's `launch` directory, i.e. `src/niryo_moveit/launch/`.

</launch>
```
This launch will print various messages to the console, including the set parameters and the nodes launched.
This launch will print various messages to the console, including the set parameters and the nodes launched.
ROS and Unity have now successfully connected!
![](img/2_echo.png)

- If the error `[rosrun] Found the following, but they're either not files, or not executable: server_endpoint.py` appears, the Python script may need to be marked as executable via `chmod +x Unity-Robotics-Hub/tutorials/pick_and_place/ROS/src/niryo_moveit/scripts/server_endpoint.py`.
- `...failed because unknown error handler name 'rosmsg'` This is due to a bug in an outdated package version. Try running `sudo apt-get update && sudo apt-get upgrade` to upgrade.
- If Unity fails to find a network connection, ensure that the ROS IP address is entered correctly as the ROS IP Address in the RosConnect in Unity, and that the `src/niryo_moveit/config/params.yaml` values are set correctly.
- If Unity fails to find a network connection, ensure that the ROS IP address is entered correctly as the ROS IP Address in the RosConnect in Unity, and that the `src/niryo_moveit/config/params.yaml` values are set correctly.
- If the ROS TCP handshake fails (e.g. `ROS-Unity server listening...` printed on the Unity side but no `ROS-Unity Handshake received` on the ROS side), the ROS IP may not have been set correctly in the params.yaml file. Try running `echo "ROS_IP: $(hostname -I)" > src/niryo_moveit/config/params.yaml` in a terminal from your ROS workspace.

- [TCP Endpoint](https://github.com/Unity-Technologies/ROS-TCP-Endpoint) package
- [Niryo One ROS stack](https://github.com/NiryoRobotics/niryo_one_ros)
- [MoveIt Msgs](https://github.com/ros-planning/moveit_msgs)
---
#### Proceed to [Part 3](3_pick_and_place.md).

30
tutorials/pick_and_place/3_pick_and_place.md


## The Unity Side
1. If you have not already completed the steps in [Part 1](1_urdf.md) to set up the Unity project and [Part 2](2_ros_tcp.md) to integrate ROS with Unity, do so now.
1. If you have not already completed the steps in [Part 1](1_urdf.md) to set up the Unity project and [Part 2](2_ros_tcp.md) to integrate ROS with Unity, do so now.
1. If the PickAndPlaceProject Unity project is not already open, select and open it from the Unity Hub.

{
MMoverServiceRequest request = new MMoverServiceRequest();
request.joints_input = CurrentJointConfig();
// Pick Pose
request.pick_pose = new MPose
{

{
var jointPositions = response.trajectories[poseIndex].joint_trajectory.points[jointConfigIndex].positions;
float[] result = jointPositions.Select(r=> (float)r * Mathf.Rad2Deg).ToArray();
for (int joint = 0; joint < jointArticulationBodies.Length; joint++)
{
var joint1XDrive = jointArticulationBodies[joint].xDrive;

if (poseIndex == (int)Poses.Grasp)
CloseGripper();
yield return new WaitForSeconds(poseAssignmentWait);
}
// Open Gripper at end of sequence

1. Return to Unity. Select the Publisher GameObject and add the `TrajectoryPlanner` script as a component.
1. Note that the TrajectoryPlanner component shows its member variables in the Inspector window, which need to be assigned.
1. Note that the TrajectoryPlanner component shows its member variables in the Inspector window, which need to be assigned.
Once again, drag and drop the `Target` and `TargetPlacement` objects onto the Target and Target Placement Inspector fields, respectively. Assign the `niryo_one` robot to the Niryo One field.
Once again, drag and drop the `Target` and `TargetPlacement` objects onto the Target and Target Placement Inspector fields, respectively. Assign the `niryo_one` robot to the Niryo One field.
![](img/3_target.gif)

> Note the file `src/niryo_moveit/scripts/mover.py`. This script holds the ROS-side logic for the MoverService. When the service is called, the function `plan_pick_and_place()` runs. This calls `plan_trajectory` on the current joint configurations (sent from Unity) to a destination pose (dependent on the phase of the pick-and-place task).
```python
def plan_trajectory(move_group, destination_pose, start_joint_angles):
def plan_trajectory(move_group, destination_pose, start_joint_angles):
current_joint_state = JointState()
current_joint_state.name = joint_names
current_joint_state.position = start_joint_angles

## ROS–Unity Communication
1. If you have not already completed the steps in [Part 0](0_ros_setup.md) to set up your ROS workspace, do so now.
1. If you have not already completed the steps in [Part 0](0_ros_setup.md) to set up your ROS workspace, do so now.
1. Open a new terminal window in the ROS workspace. Once again, source the workspace.
1. Open a new terminal window in the ROS workspace. Once again, source the workspace.
Then, run the following `roslaunch` in order to start roscore, set the ROS parameters, start the server endpoint, start the Mover Service node, and launch MoveIt.
Then, run the following `roslaunch` in order to start roscore, set the ROS parameters, start the server endpoint, start the Mover Service node, and launch MoveIt.
```bash
roslaunch niryo_moveit part_3.launch

> Note: This may print out various error messages such as `Failed to find 3D sensor plugin`. These messages are safe to ignore as long as the final message to the console is `You can start planning now!`.
1. Return to the Unity Editor and press Play. Press the UI Button to send the joint configurations to ROS, and watch the robot arm pick up and place the cube!
- The target object and placement positions can be moved around during runtime for different trajectory calculations.
1. Return to the Unity Editor and press Play. Press the UI Button to send the joint configurations to ROS, and watch the robot arm pick up and place the cube!
- The target object and placement positions can be moved around during runtime for different trajectory calculations.
![](img/0_pick_place.gif)
---

### Errors and Warnings
- If the motion planning script throws a `RuntimeError: Unable to connect to move_group action server 'move_group' within allotted time (5s)`, ensure the `roslaunch niryo_moveit part_3.launch` process launched correctly and has printed `You can start planning now!`.
- If Unity fails to find a network connection, ensure that the ROS IP address is entered correctly as the `ROS IP Address` in the RosConnect in Unity, and that the `src/niryo_moveit/config/params.yaml` values are set correctly.
- If Unity fails to find a network connection, ensure that the ROS IP address is entered correctly as the `ROS IP Address` in the RosConnect in Unity, and that the `src/niryo_moveit/config/params.yaml` values are set correctly.
### Miscellaneous Issues

34
tutorials/pick_and_place/4_pick_and_place.md


- [Add niryo_moveit Package](#add-niryo_moveit-package)
- [Execution](#execution)
# Niryo One Information
The best source of information for the Niryo One is the [User Manual](https://niryo.com/docs/niryo-one/user-manual/complete-user-manual/). It contains a lot of general information about the Niryo One, such as how to connect it to a network, how to log in to it, and how to use the Niryo One Studio desktop application.

```
From here we see that the `RobotMoveGoal.RobotMoveCommand.ToolCommand.cmd_type` variable will need to be `2` to close the gripper and `1` to open it.
From here we see that the `RobotMoveGoal.RobotMoveCommand.ToolCommand.cmd_type` variable will need to be `2` to close the gripper and `1` to open it.
# Differences From Part 3

```python
def send_trajectory_goal(client, trajectory):
```python
def send_tool_goal(client, gripper_command):
tool_command = ToolCommand()

tool_command.gripper_close_speed = GRIPPER_SPEED
return
```

```python
previous_ending_joint_angles = grasp_pose.trajectory.joint_trajectory.points[-1].positions
send_trajectory_goal(client, grasp_pose)

Using the same scene from [Part 3](3_pick_and_place.md), we are going to use a new script, `RealSimPickAndPlace.cs`, that mirrors a lot of the functionality of the `TrajectoryPlanner.cs` script.
Using the same scene from [Part 3](3_pick_and_place.md), we are going to use a new script, `RealSimPickAndPlace.cs`, that mirrors a lot of the functionality of the `TrajectoryPlanner.cs` script.
## Key Differences

{
var jointPositions = point.positions;
float[] result = jointPositions.Select(r=> (float)r * Mathf.Rad2Deg).ToArray();
// Set the joint values for every joint
for (int joint = 0; joint < jointArticulationBodies.Length; joint++)
{

1. Select the Publisher GameObject and add the `RealSimPickAndPlace` script as a component.
1. Note that the RealSimPickAndPlace component shows its member variables in the Inspector window, which need to be assigned.
1. Note that the RealSimPickAndPlace component shows its member variables in the Inspector window, which need to be assigned.
Once again, drag and drop the `Target` and `TargetPlacement` objects onto the Target and Target Placement Inspector fields, respectively. Assign the `niryo_one` robot to the Niryo One field.
Once again, drag and drop the `Target` and `TargetPlacement` objects onto the Target and Target Placement Inspector fields, respectively. Assign the `niryo_one` robot to the Niryo One field.
![](img/4_script.png)

- The two files that will need to be updated are `niryo_one.urdf.xacro` and `without_mesh_niryo_one.urdf.xacro` located in the `/home/niryo/catkin_ws/src/niryo_one_description/urdf/v2` directory.
- Look for the joint named `joint_world` and update the `origin`'s `xyz` to `0 0 0.63` to reflect that the simulated Niryo is placed at `0.63` on the Z axis.
```xml
<joint name="joint_world" type="fixed">
<parent link="world" />

4
tutorials/pick_and_place/PickAndPlaceProject/Assets/Tests/EditMode/PickAndPlaceMessageGenerationtests.cs


{
yield return new TestCaseData(Path.Combine(k_ROSDirectory, "moveit_msgs", "msg", "RobotTrajectory.msg"));
}
// Define directories of message files to be generated here
static IEnumerable<TestCaseData> MessageDirectories()
{

MessageAutoGen.GenerateDirectoryMessages(directoryToBuild, m_MessageGenOutputPath);
AssetDatabase.Refresh();
}
[Test]
[TestCaseSource(nameof(ServiceDirectories))]
public void TestServiceBuildDirectory_ThrowsNoExceptions(string directoryToBuild)

2
tutorials/pick_and_place/PickAndPlaceProject/Assets/URDF/niryo_one/niryo_one_urdf/README.md


This package contains URDF file and meshes (collada + stl) for Niryo One.
**Note** : 3D visualization is not available on the Niryo One Raspberry Pi image. To use the following commands, you must have installed ROS on your computer and downloaded the Niryo One ROS packages.
**Note** : 3D visualization is not available on the Niryo One Raspberry Pi image. To use the following commands, you must have installed ROS on your computer and downloaded the Niryo One ROS packages.
* To display Niryo One on Rviz :

8
tutorials/pick_and_place/README.md


# Pick-and-Place Tutorial
Unity's tools for robotic simulation enable users to integrate Unity with ROS-based workflows. [ROS](http://wiki.ros.org/ROS/Introduction) (Robot Operating System) provides services such as message-passing, package management, low-level device control, and hardware abstraction. Unity's robotics tools are able to support **importing URDF files** and **sending and receiving messages between ROS and Unity**. This tutorial will go through the steps necessary to integrate ROS with Unity, from installing the Unity Editor to creating a scene with an imported URDF to completing a pick-and-place task with known poses using [MoveIt](https://moveit.ros.org/) trajectory planning.
Unity's tools for robotic simulation enable users to integrate Unity with ROS-based workflows. [ROS](http://wiki.ros.org/ROS/Introduction) (Robot Operating System) provides services such as message-passing, package management, low-level device control, and hardware abstraction. Unity's robotics tools are able to support **importing URDF files** and **sending and receiving messages between ROS and Unity**. This tutorial will go through the steps necessary to integrate ROS with Unity, from installing the Unity Editor to creating a scene with an imported URDF to completing a pick-and-place task with known poses using [MoveIt](https://moveit.ros.org/) trajectory planning.
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.

This part provides two options for setting up your ROS workspace: using Docker, or manually setting up a catkin workspace.
## [Part 1: Create Unity scene with imported URDF](1_urdf.md)
## [Part 1: Create Unity scene with imported URDF](1_urdf.md)
This part includes downloading and installing the Unity Editor, setting up a basic Unity scene, and importing a robot--the [Niryo One](https://niryo.com/niryo-one/)--using the URDF Importer.
This part includes downloading and installing the Unity Editor, setting up a basic Unity scene, and importing a robot--the [Niryo One](https://niryo.com/niryo-one/)--using the URDF Importer.
## [Part 2: ROS–Unity Integration](2_ros_tcp.md)

## [Part 3: Pick-and-Place In Unity](3_pick_and_place.md)
<img src="img/0_pick_place.gif" width="400"/>
This part includes the preparation and setup necessary to run a pick-and-place task with known poses using MoveIt. Steps covered include creating and invoking a motion planning service in ROS, moving a Unity Articulation Body based on a calculated trajectory, and controlling a gripping tool to successfully grasp and drop an object.

6
tutorials/pick_and_place/ROS/src/niryo_moveit/README.md


### Prerequisites
### Prerequisites
### ROS & Simulated Arm Only
### ROS & Simulated Arm Only
--
**Terminal 1**

niryo_one_msgs/TrajectoryPlan Trajectory
geometry_msgs/Pose pose_quat
string saved_position_name
int32 saved_trajectory_id
int32 saved_trajectory_id
```
**TrajectoryPlan.msg**

2
tutorials/pick_and_place/ROS/src/niryo_one_urdf/README.md


This package contains URDF file and meshes (collada + stl) for Niryo One.
**Note** : 3D visualization is not available on the Niryo One Raspberry Pi image. To use the following commands, you must have installed ROS on your computer and downloaded the Niryo One ROS packages.
**Note** : 3D visualization is not available on the Niryo One Raspberry Pi image. To use the following commands, you must have installed ROS on your computer and downloaded the Niryo One ROS packages.
* To display Niryo One on Rviz :

16
tutorials/pick_and_place/Scripts/SourceDestinationPublisher.cs


{
// ROS Connector
private ROSConnection ros;
// Variables required for ROS communication
public string topicName = "SourceDestination_input";

/// <summary>
///
/// </summary>

string arm_link = shoulder_link + "/arm_link";
jointArticulationBodies[1] = niryoOne.transform.Find(arm_link).GetComponent<ArticulationBody>();
string hand_link = wrist_link + "/hand_link";
jointArticulationBodies[5] = niryoOne.transform.Find(hand_link).GetComponent<ArticulationBody>();
}

30
tutorials/pick_and_place/Scripts/TrajectoryPlanner.cs


private readonly float jointAssignmentWait = 0.1f;
private readonly float poseAssignmentWait = 0.5f;
private readonly Vector3 pickPoseOffset = Vector3.up * 0.1f;
// Assures that the gripper is always positioned above the target cube before grasping.
private readonly Quaternion pickOrientation = Quaternion.Euler(90, 90, 0);

PickUp,
Place
};
/// <summary>
/// Close the gripper
/// </summary>

MNiryoMoveitJoints CurrentJointConfig()
{
MNiryoMoveitJoints joints = new MNiryoMoveitJoints();
joints.joint_00 = jointArticulationBodies[0].xDrive.target;
joints.joint_01 = jointArticulationBodies[1].xDrive.target;
joints.joint_02 = jointArticulationBodies[2].xDrive.target;

{
MMoverServiceRequest request = new MMoverServiceRequest();
request.joints_input = CurrentJointConfig();
// Pick Pose
request.pick_pose = new MPose
{

if (response.trajectories != null)
{
// For every trajectory plan returned
for (int poseIndex = 0 ; poseIndex < response.trajectories.Length; poseIndex++)
for (int poseIndex = 0; poseIndex < response.trajectories.Length; poseIndex++)
for (int jointConfigIndex = 0 ; jointConfigIndex < response.trajectories[poseIndex].joint_trajectory.points.Length; jointConfigIndex++)
for (int jointConfigIndex = 0; jointConfigIndex < response.trajectories[poseIndex].joint_trajectory.points.Length; jointConfigIndex++)
float[] result = jointPositions.Select(r=> (float)r * Mathf.Rad2Deg).ToArray();
float[] result = jointPositions.Select(r => (float)r * Mathf.Rad2Deg).ToArray();
var joint1XDrive = jointArticulationBodies[joint].xDrive;
var joint1XDrive = jointArticulationBodies[joint].xDrive;
joint1XDrive.target = result[joint];
jointArticulationBodies[joint].xDrive = joint1XDrive;
}

// Close the gripper if completed executing the trajectory for the Grasp pose
if (poseIndex == (int)Poses.Grasp)
CloseGripper();
// Wait for the robot to achieve the final pose from joint assignment
yield return new WaitForSeconds(poseAssignmentWait);
}

string arm_link = shoulder_link + "/arm_link";
jointArticulationBodies[1] = niryoOne.transform.Find(arm_link).GetComponent<ArticulationBody>();
string hand_link = wrist_link + "/hand_link";
jointArticulationBodies[5] = niryoOne.transform.Find(hand_link).GetComponent<ArticulationBody>();

rightGripper = rightGripperGameObject.GetComponent<ArticulationBody>();
leftGripper = leftGripperGameObject.GetComponent<ArticulationBody>();
}
}
}

26
tutorials/pick_and_place/Scripts_Part4/RealSimPickAndPlace.cs


private const int CLOSE_GRIPPER = 2;
private const int TOOL_COMMAND_EXECUTION = 6;
private const int TRAJECTORY_COMMAND_EXECUTION = 7;
// Assures that the gripper is always positioned above the target cube before grasping.
private readonly Quaternion pickOrientation = Quaternion.Euler(90, 90, 0);

orientation = pickOrientation.To<FLU>()
}
};
/// <summary>
/// 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.

string armLink = shoulder_link + "/arm_link";
jointArticulationBodies[1] = niryoOne.transform.Find(armLink).GetComponent<ArticulationBody>();
string handLink = wristLink + "/hand_link";
jointArticulationBodies[5] = niryoOne.transform.Find(handLink).GetComponent<ArticulationBody>();

rightGripperJoint = rightGripperGameObject.GetComponent<ArticulationBody>();
leftGripperJoint = leftGripperGameObject.GetComponent<ArticulationBody>();
}
void Start()
{
ros.Subscribe<MRobotMoveActionGoal>(rosRobotCommandsTopicName, ExecuteRobotCommands);

foreach (var point in trajectories.joint_trajectory.points)
{
var jointPositions = point.positions;
float[] result = jointPositions.Select(r=> (float)r * Mathf.Rad2Deg).ToArray();
float[] result = jointPositions.Select(r => (float)r * Mathf.Rad2Deg).ToArray();
var joint1XDrive = jointArticulationBodies[joint].xDrive;
var joint1XDrive = jointArticulationBodies[joint].xDrive;
joint1XDrive.target = result[joint];
jointArticulationBodies[joint].xDrive = joint1XDrive;
}

12
tutorials/pick_and_place/moveit_file_descriptions.md


- Starts ROS node `controller_manager` with arguments `joint_state_controller niryo_one_follow_joint_trajectory_controller
--shutdown-timeout 1`
- Starts ROS node `robot_state_publisher` package.
- Starts ROS node `robot_state_publisher` package.
- Ex. `rosrun robot_state_publisher robot_state_publisher`
**move_group.launch**

- `moveit_controller_manager` set to `niryo_one`
- Call `planning_context.launch`
- Start ROS node `moveit_ros_move_group`
- Start ROS node `moveit_ros_move_group`
- Set rosparam `allow_trajectory_execution` to true
- Set rosparam `max_safe_path_cost` to 1
- Set rosparam `jiggle_fraction` to 0.05

- Sets rosparams `service_timeout` to 2, `action_connection_timeout` to 2, `action_execute_timeout` to 15, and `action_preempt_timeout` to 3 for `niryo_one/python_api` namespace
- Sets rosparams `rate_tf_listener` to 5.0 and `rate_publish_state` to 5.0 for `niryo_one/robot_state` namespace
- Loads `niryo_one_urdf.xacro` as rosparams `robot_description` and `robot_description_tf2`
**niryo_one_moveit_controller_manager.launch.xml**

- Reads `controllers.yaml` into rosparam
**ompl_planning_pipeline.launch.xml**
- Set rosparam `planning_plugin` with value of `ompl_interface/OMPLPlanner`
- Set rosparam `planning_adapters` with value of:

**niryo_one.srdf**
- Defines joint groups, group states, and disables collisions between joints and links that are impossible to collide.
- [MoveIt SRDF Documentation](https://ros-planning.github.io/moveit_tutorials/doc/urdf_srdf/urdf_srdf_tutorial.html#srdf)
- [MoveIt SRDF Documentation](https://ros-planning.github.io/moveit_tutorials/doc/urdf_srdf/urdf_srdf_tutorial.html#srdf)
**niryo_one_controllers.yaml**

10
tutorials/pick_and_place/quick_demo.md


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**.
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. 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: 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
>

> * **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
> * **Publisher**: the object that publish joint configurations to the ROS network for planning
### 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).

6
tutorials/quick_setup.md


This page provides brief instructions on installing the Unity Robotics packages. Head over to the [Pick-and-Place Tutorial](pick_and_place/README.md) for more detailed instructions and steps for building a sample project.
1. Create or open a Unity project.
1. Create or open a Unity project.
1. In the Package Manager window, find and click the `+` button in the upper lefthand corner of the window. Select `Add package from git URL...`.
1. In the Package Manager window, find and click the `+` button in the upper lefthand corner of the window. Select `Add package from git URL...`.
![](../images/packman.png)

1. Click `Add`.
1. Click `Add`.
To install from a local clone of the repository, see [installing a local package](https://docs.unity3d.com/Manual/upm-ui-local.html) in the Unity manual.

2
tutorials/ros_unity_integration/network.md


## If Using Docker
The container will need to be started with the following arguments to forward the ports used for communication between ROS and Unity.
The container will need to be started with the following arguments to forward the ports used for communication between ROS and Unity.
`-p 10000:10000 -p 5005:5005`

8
tutorials/ros_unity_integration/publisher.md


- Follow the [ROS–Unity Initial Setup](setup.md) guide.
- Open a new terminal window and run the following commands:
```bash
source devel/setup.bash
rosrun robotics_demo server_endpoint.py

using Unity.Robotics.ROSTCPConnector;
/// <summary>
///
///
/// </summary>
public class RosPublisherExample : MonoBehaviour
{

// The game object
// The game object
public GameObject cube;
// Publish the cube's position and rotation every N seconds
public float publishMessageFrequency = 0.5f;

void Start()
{
// start the ROS connection

8
tutorials/ros_unity_integration/server_endpoint.md


connections = rospy.get_param("/TCP_CONNECTIONS", 10)
tcp_server = TcpServer(ros_node_name, buffer_size, connections)
rospy.init_node(ros_node_name, anonymous=True)
tcp_server.start({
'pos_rot': RosPublisher('pos_rot', PosRot, queue_size=10),
'color': RosSubscriber('color', UnityColor, tcp_server),

rospy.spin()

'pos_srv': RosService('pos_srv', PositionService),
'obj_pose_srv': UnityService('obj_pose_srv', ObjectPoseService, tcp_server),
})
rospy.spin()
```

<env name="ROS_IP" value="127.0.0.1"/>
<env name="ROS_HOSTNAME" value="$(env ROS_IP)"/>
<param name="ROS_IP" type="str" value="$(env ROS_IP)" />
<param name="ROS_TCP_PORT" type="int" value="10000" />
<param name="TCP_NODE_NAME" type="str" value="TCPServer" />

2
tutorials/ros_unity_integration/service.md


- Follow the [ROS–Unity Initial Setup](setup.md) guide.
- Open a new terminal window, navigate to your ROS workspace, and run the following commands:
```bash
source devel/setup.bash
rosrun robotics_demo server_endpoint.py

10
tutorials/ros_unity_integration/setup.md


1. Navigate to your Catkin workspace and run `catkin_make && source devel/setup.bash`. Ensure there are no errors.
1. Open a new terminal, navigate to your Catkin workspace, and run:
```bash
source devel/setup.bash
roscore &

1. Note that in the `server_endpoint`, the script fetches parameters for the TCP connection. You will need to know the IP address of your ROS machine as well as the IP address of the machine running Unity.
1. Note that in the `server_endpoint`, the script fetches parameters for the TCP connection. You will need to know the IP address of your ROS machine as well as the IP address of the machine running Unity.
1. The ROS parameter values can be set using a YAML file. Create a `params.yaml` file in your package, e.g. `./config/params.yaml`. Open the file for editing.
1. The ROS parameter values can be set using a YAML file. Create a `params.yaml` file in your package, e.g. `./config/params.yaml`. Open the file for editing.
1. Update the `ROS_IP` below with the appropriate address and copy the contents into the `params.yaml` file.

```
e.g.
```yaml

<rosparam file="$(find <PACKAGE_NAME>)/config/params.yaml" command="load"/>
</launch>
```
> Read more about rosparam YAML options [here](http://wiki.ros.org/rosparam).
>
> Read more about the ROS Parameter Server [here](http://wiki.ros.org/Parameter%20Server).

4
tutorials/ros_unity_integration/subscriber.md


- Follow the [ROS–Unity Initial Setup](setup.md) guide.
- Open a new terminal window, navigate to your Catkin workspace, and run the following commands:
```bash
source devel/setup.bash
rosrun robotics_demo server_endpoint.py

- In Unity, we need to generate the C# code for the `UnityColor` message. Open `Robotics` -> `Generate ROS Messages...`.
- Set the ROS message path to `PATH/TO/Unity-Robotics-Hub/tutorials/ros_packages/robotics_demo/`, expand the robotics_demo subfolder and click `Build 2 msgs`.
![](images/generate_messages_1.png)
- The generated files will be saved in the default directory `Assets/RosMessages/RoboticsDemo/msg`.

4
tutorials/ros_unity_integration/unity_scripts/RosPublisherExample.cs


// Used to determine how much time has elapsed since the last message was published
private float timeElapsed;
void Start()
{
// start the ROS connection

timeElapsed = 0;
}
}
}
}

4
tutorials/ros_unity_integration/unity_scripts/RosServiceExample.cs


// Send message to ROS and return the response
ros.SendServiceMessage<MPositionServiceResponse>(serviceName, positionServiceRequest, Callback_Destination);
awaitingResponseUntilTimestamp = Time.time+1.0f; // don't send again for 1 second, or until we receive a response
awaitingResponseUntilTimestamp = Time.time + 1.0f; // don't send again for 1 second, or until we receive a response
}
}

destination = new Vector3(response.output.pos_x, response.output.pos_y, response.output.pos_z);
Debug.Log("New Destination: " + destination);
}
}
}

36
tutorials/ros_unity_integration/unity_scripts/RosSubscriberExample.cs


using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using RosColor = RosMessageTypes.RoboticsDemo.MUnityColor;
public class RosSubscriberExample : MonoBehaviour
{
public GameObject cube;
void Start()
{
ROSConnection.instance.Subscribe<RosColor>("color", ColorChange);
}
void ColorChange(RosColor colorMessage)
{
cube.GetComponent<Renderer>().material.color = new Color32((byte)colorMessage.r, (byte)colorMessage.g, (byte)colorMessage.b, (byte)colorMessage.a);
}
}
using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using RosColor = RosMessageTypes.RoboticsDemo.MUnityColor;
public class RosSubscriberExample : MonoBehaviour
{
public GameObject cube;
void Start()
{
ROSConnection.instance.Subscribe<RosColor>("color", ColorChange);
}
void ColorChange(RosColor colorMessage)
{
cube.GetComponent<Renderer>().material.color = new Color32((byte)colorMessage.r, (byte)colorMessage.g, (byte)colorMessage.b, (byte)colorMessage.a);
}
}

4
tutorials/ros_unity_integration/unity_scripts/RosUnityServiceExample.cs


MObjectPoseServiceResponse objectPoseResponse = new MObjectPoseServiceResponse();
// Find a game object with the requested name
GameObject gameObject = GameObject.Find(request.object_name);
if (gameObject)
if (gameObject)
return objectPoseResponse;
}
}

22
tutorials/ros_unity_integration/unity_service.md


- Follow the [ROS–Unity Initial Setup](setup.md) guide.
- Open a new terminal window, navigate to your ROS workspace, and run the following commands:
```bash
source devel/setup.bash
rosrun robotics_demo server_endpoint.py

![](images/generate_messages_2.png)
- The generated files will be saved in the default directory `Assets/RosMessages/RoboticsDemo/srv`.
- Create a new C# script and name it `RosUnityServiceExample.cs`
- Paste the following code into `RosUnityServiceExample.cs`
- **Note:** This script can be found at `tutorials/ros_unity_integration/unity_scripts`.

MObjectPoseServiceResponse objectPoseResponse = new MObjectPoseServiceResponse();
// Find a game object with the requested name
GameObject gameObject = GameObject.Find(request.object_name);
if (gameObject)
if (gameObject)
return objectPoseResponse;
}
}

- Create an empty GameObject and name it `UnityService`.
- Attach the `RosUnityServiceExample` script to the `UnityService` GameObject.
- Attach the `RosUnityServiceExample` script to the `UnityService` GameObject.
- Pressing play in the Editor should start running as a ROS node, waiting to accept ObjectPose requests. Once a connection to ROS has been established, a message will be printed on the ROS terminal similar to `Connection from 172.17.0.1`.

```bash
Requesting pose for Cube
Pose for Cube:
position:
Pose for Cube:
position:
orientation:
orientation:
x: 0.0
y: -0.0
z: 0.0

rosservice call /obj_pose_srv Cube
```
```bash
object_pose:
position:
object_pose:
position:
orientation:
orientation:
x: 0.0
y: -0.0
z: 0.0

42
tutorials/urdf_importer/urdf_appendix.md


## File Hierarchy
URDF files and associated meshes should be placed in a single folder within the Assets directory of Unity. We suggest creating a new folder with the robot's name and place the URDF file in its root with all associated mesh files in sub folders. Be sure to update the file locations as described by the URDF file.
## GameObject Hierarchy
## GameObject Hierarchy
The robot imported in Unity follows a Parent - Child hierarchy.
The robot imported in Unity follows a Parent - Child hierarchy.
- Robot GameObject
- UrdfRobot Script: UrdfRobot.cs script contains functions to change the behaviors of the imported robot. The script is used to control a robot's behavior, compare against a URDF file, and export the robot as a URDF file.
- Controller Script: Enables keyboard control of the robot. It can be modified to create custom controllers as described [here](##Guide-to-write-your-own-controller).

- After the exported file location is selected, its location is automatically selected as location of `Log File Save Location`. You can choose your own save location by pressing the `Select` next to the text field.
- To compare the two URDF files press `Compare URDF Files` to generate the [log file](#URDF_Comparator).
## URDF_Comparator
## URDF_Comparator
Name:
Name:
Equal: True
Name: Source: base_link Exported: base_link
Inertial Checks

Material Checks
Material Nullity Check: True
Name Equal: True
Name: Source: LightGrey
Name: Source: LightGrey
RGB :0.700 0.700 0.700
RGB :0.700 0.700 0.700
Texture nullity equality: True
Collisions Checks
Number of Collision Components

-Collision Component: 1
Collision Name
Equal: True
Name: Source:
Exported:
Name: Source:
Exported:
Origin Checks
Origin Nullity Check: True
Geometry:

Axis Checks
Axis
Equal: True
XYZ : (0.000,0.000,1.000)
XYZ : (0.000,0.000,1.000)
Dynamics Equal: True
Dynamics Equal: True
Lower Limit:
Equal: True
Lower Limit Value: -3.14159265359

Child Name: Exported: shoulder_link
```
Log file contains comparison for every attribute contained in the source URDF file to the corresponding attribute in exported URDF file. Each attribute follows the format :
Log file contains comparison for every attribute contained in the source URDF file to the corresponding attribute in exported URDF file. Each attribute follows the format :
```
<Attribute_Name>
Equal : <True/False>

Some attributes generates a nullity check which checks for presence of attributes in both URDF files.
## Articulation Body axis definition
## Articulation Body axis definition
![](images/Unity_coordinate.png)
The most commonly used Coordinate system is the right hand coordinate system which is shown in the figure above. It follows the convention that if your right-hand thumb represents the X direction, then the index finger and the middle finger stretched out uncrossed at right angles would represent the Y and Z direction respectively. Positive direction of rotation is represented by the curl of the fingers with the thumb stretched out.

Articulation Body allows the joints to be controlled by three methods:
1. Position Control
2. Torque Control
2. Torque Control
3. Velocity Control
All types of control are governed by the Spring-Damper equation :

#### Example Code
Code for positional control can be divided into two scripts. One script would be attached to the root GameObject which represents the robot. This script would determine the correct position of the joint, directed by a control policy implemented by the user. The other end of the script is attached to the GameObject with ArticulationBody component which receives the target position and assigns that
Code for positional control can be divided into two scripts. One script would be attached to the root GameObject which represents the robot. This script would determine the correct position of the joint, directed by a control policy implemented by the user. The other end of the script is attached to the GameObject with ArticulationBody component which receives the target position and assigns that
value to the articulation body.
**Note: This architecture can be changed according to the user's design.**

}
Highlight(selectedIndex);
}
UpdateDirection(selectedIndex);
}
```

{
float moveDirection = Input.GetAxis("Vertical");
JointControl current = articulationChain[jointIndex].GetComponent<JointControl>();
JointControl current = articulationChain[jointIndex].GetComponent<JointControl>();
JointControl previous = articulationChain[previousIndex].GetComponent<JointControl>();
JointControl previous = articulationChain[previousIndex].GetComponent<JointControl>();
previous.direction = RotationDirection.None;
previousIndex = jointIndex;
}

float newTargetDelta = (int)direction * Time.fixedDeltaTime * speed;
if (newTargetDelta + currentDrive.target <= currentDrive.upperLimit && newTargetDelta + currentDrive.target >= currentDrive.lowerLimit){
currentDrive.target += newTargetDelta;
}
}
}
}
}
}
}

### Position Control
### Position Control
Position Control can be imagined as adding a spring to a joint with linear spring in case of prismatic joint and a torsional spring in case of revolute joint. The joint follows Hooke's law:

URDF defines the robot visually using Visual Meshes, and its collision using Collision Meshes. Collision meshes define the physical volume of the links, and are used to calculate the inertia of the links and also to detect collisions between different physical objects. In Unity, rigidbodies cannot have concave collision meshes, so when importing a concave collision mesh, all concave regions are closed over to produce a convex outline. As a result, the convex shapes might intersect with each other, creating a hindrance in robot movement. To remedy this, we support a ```disable collision``` tag in URDF. To add an exception for collision detection in Unity:
1. Identify the links between which you want to ignore the collisions.
2. Add a tag in the URDF file with the format
2. Add a tag in the URDF file with the format
```XML
<disable_collision link1= <name_of_link_1> link2=<name_of_link_2>>
</disable_collision>

10
tutorials/urdf_importer/urdf_tutorial.md


- Niryo One URDF files from [Niryo One ROS](https://github.com/NiryoRobotics/niryo_one_ros)
- Working ROS environment
## Setting up the URDF Importer in Unity Editor
## Setting up the URDF Importer in Unity Editor
- Integrate the URDF Importer following these [instructions](https://github.com/Unity-Technologies/URDF-Importer#integrate-urdf-importer-into-unity-project)
- Create a new directory in `Assets` and name it `URDF`
- Clone the [Niryo One ROS](https://github.com/NiryoRobotics/niryo_one_ros) repo and copy the `niryo_one_description` directory into `Assets/URDF`

- Right click on the this file and select `Import Robot from URDF`
- Select the co-ordinate system in which the meshes were designed. Default mesh orientation is Y-up which is supported by Unity but some packages often use Z-up and X-up configuration. For more [information](https://docs.unity3d.com/Manual/HOWTO-FixZAxisIsUp.html).
- Right click on the this file and select `Import Robot from URDF`
- Select the co-ordinate system in which the meshes were designed. Default mesh orientation is Y-up which is supported by Unity but some packages often use Z-up and X-up configuration. For more [information](https://docs.unity3d.com/Manual/HOWTO-FixZAxisIsUp.html).
- To add the controller to an imported robot click the `Enable` button in the Inspector window in front of the `Controller Script` option. This will add a Controller Script, FKrobot and Joint Control at runtime.
- To add the controller to an imported robot click the `Enable` button in the Inspector window in front of the `Controller Script` option. This will add a Controller Script, FKrobot and Joint Control at runtime.
- To prevent the joints from slipping set the `Stiffness` and `Damping` to `100,000` and `10,000` respectively.
- To be able to apply forces to the joints set the `Force Limit` to `10,000`.
- To prevent the robot from falling over, in the GameObject tree expand `niryo_one` -> `world` -> `base_link` and set the toggle for `Immovable` for the base_link.

75
.editorconfig


; see http://editorconfig.org/ for docs on this file
; See https://github.com/dotnet/format for dotnet format
root = true
[*]
ignore_if_in_header = This code was generated by a tool|<auto-generated>
indent_style = space
indent_size = 4
; uncomment to help with sharing files across os's (i.e. network share or through local vm)
#end_of_line = lf
; avoid a bom, which causes endless problems with naive text tooling
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
; keeping auto-format enabled helps avoid merge hell for projects without CI-based format validation
#disable_auto_format = true
[*.cs]
; uncomment to enable full formatting of c# files
formatters = generic, uncrustify
[*.asmdef]
scrape_api = true
[**/Tests/**.asmdef]
scrape_api = false
[*.Tests.asmdef]
scrape_api = false
[*.md]
indent_size = 2
; trailing whitespace is unfortunately significant in markdown
trim_trailing_whitespace = false
; uncomment to enable basic formatting of markdown files
#formatters = generic
[{Makefile,makefile}]
; tab characters are part of the Makefile format
indent_style = tab
[*.asmdef]
indent_size = 4
[*.json]
indent_size = 2
[*.{vcproj,bat,cmd,xaml,tt,t4,ttinclude}]
end_of_line = crlf
; this VS-specific stuff is based on experiments to see how VS will modify a file after it has been manually edited.
; the settings are meant to closely match what VS does to minimize unnecessary diffs.
[*.{vcxproj,vcxproj.filters}]
indent_style = space
indent_size = 2
end_of_line = crlf
charset = utf-8-bom
trim_trailing_whitespace = true
insert_final_newline = false
; must be broken out because of 51-char bug (https://github.com/editorconfig/editorconfig-visualstudio/issues/21)
[*.{csproj,pyproj,props,targets}]
indent_style = space
indent_size = 2
end_of_line = crlf
charset = utf-8-bom
trim_trailing_whitespace = true
insert_final_newline = false
[*.{sln,sln.template}]
indent_style = tab
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false

32
.pre-commit-config.yaml


repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: mixed-line-ending
exclude: >
(?x)^(
.*cs.meta|
.*.css|
.*.meta|
.*.mat|
.*.preset|
.*.lighting|
.*.dae
)$
args: [--fix=lf]
- id: trailing-whitespace
name: trailing-whitespace-markdown
types: [markdown]
- id: check-merge-conflict
args: [--assume-in-merge]
- id: check-yaml
# Won't handle the templating in yamato
exclude: \.yamato/.*
- repo: https://github.com/dotnet/format
rev: "7e343070a0355c86f72bdee226b5e19ffcbac931"
hooks:
- id: dotnet-format
args: [--folder, --include]

19
.github/workflows/pre-commit.yaml


name: pre-commit
on:
pull_request:
push:
branches: [dev]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.7.x
- uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
- uses: pre-commit/action@v2.0.0
正在加载...
取消
保存