浏览代码

Add linter (#227)

* Add linter and pre-commit hooks

* Formatting

* Remove setting up ruby
/merge-resolve-conflicts
peifeng-unity 3 年前
当前提交
32378ec2
共有 12 个文件被更改,包括 99 次插入99 次删除
  1. 2
      .github/PULL_REQUEST_TEMPLATE.md
  2. 14
      CONTRIBUTING.md
  3. 10
      README.md
  4. 58
      tutorials/pick_and_place/2_ros_tcp.md
  5. 30
      tutorials/pick_and_place/Scripts/TrajectoryPlanner.cs
  6. 6
      tutorials/quick_setup.md
  7. 2
      tutorials/ros_unity_integration/network.md
  8. 4
      tutorials/ros_unity_integration/unity_scripts/RosServiceExample.cs
  9. 36
      tutorials/ros_unity_integration/unity_scripts/RosSubscriberExample.cs
  10. 4
      tutorials/ros_unity_integration/unity_scripts/RosUnityServiceExample.cs
  11. 22
      tutorials/ros_unity_integration/unity_service.md
  12. 10
      tutorials/urdf_importer/urdf_tutorial.md

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]

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

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/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>();
}
}
}

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`

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

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.

正在加载...
取消
保存