Skip to content

Commit e242327

Browse files
committed
simple turtlebot tutorial
1 parent 0a78087 commit e242327

File tree

8 files changed

+1074
-966
lines changed

8 files changed

+1074
-966
lines changed
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ ZeroSim provides a multitude of tools for building robots and environments in Un
4747

4848
## Getting Started
4949

50+
### Recommended System
51+
52+
* Ubuntu 18.04 or 20.04 (may work on MacOS or Windows but currently untested)
53+
* Unity 2020.x
54+
5055
### Setting up a new Unity Project
5156

5257
1. In Unity Hub create a new Unity project using Unity 2020.x or later. ![New Unity Project](Documentation~/images/new_unity_project.png)
@@ -61,4 +66,45 @@ ZeroSim provides a multitude of tools for building robots and environments in Un
6166
3. If running Unity on Linux you want to avoid using OpenGL and use Vulkan, otherwise image based sensors may run slowly or not at all. To change to using Vulkan:
6267
1. In the Unity Menu: `Edit -> Project Settings...`:
6368
2. Uncheck `Auto Graphics API for Linux` and then under `Graphics APIs for Linux` set `Vulkan` ahead of `OpenGL`:
64-
![Vulkan Settings](Documentation~/images/vulkan_settings.png)
69+
![Vulkan Settings](Documentation~/images/vulkan_settings.png)
70+
71+
72+
### Getting ZeroSim ROS Docker Container
73+
74+
1. Available at https://hub.docker.com/r/zerodog/zerosim_ros_vnc or `docker pull zerodog/zerosim_ros_vnc:latest`
75+
### Running TurtleBot Test Scene
76+
77+
*NOTE:* Order of operations is important. Especially starting the Docker *before* the Unity simulation.
78+
79+
1. Make sure that the ZeroSim samples are installed as outlined above.
80+
2. Make sure that the ZeroSim Docker container above is installed.
81+
3. Open the `Scenes/Turtlebot3_Waffle_test.scene`
82+
4. Launch the ZeroSim Docker via:
83+
```
84+
docker run -it --rm \
85+
--publish=9090:9090 \
86+
--publish=11311:11311 \
87+
--publish=8083:8083 \
88+
--publish=80:80 \
89+
--publish=5678:5678 \
90+
--name my_zerosim_vnc_docker \
91+
zerodog/zerosim_ros_vnc:latest \
92+
roslaunch zero_sim_ros basic_unity_editor.launch
93+
94+
```
95+
5. Run the ROS teleop in a seperate terminal by running:
96+
```
97+
docker exec -it my_zerosim_vnc_docker \
98+
bash -c "source devel/setup.bash ; rosrun turtlebot3_teleop turtlebot3_teleop_key"
99+
```
100+
6. In the Unity editor press the "Play" button.
101+
7. The Turtlebot can now be controlled via the `w a s d` keys in the ROS teleop console window:
102+
103+
### Using RViz Example
104+
105+
1. Startup the Turtlebot Test Scene as detailed above.
106+
2. Open a noVNC connection by:
107+
1. In a browser open http://localhost:8083/vnc.html
108+
2. Press the "Connect" button. ![noVNC Login](Documentation~/images/novnc_login.png)
109+
3. In the VNC window press the *LEFT* mouse button and select "Terminal". ![noVNC Terminal](Documentation~/images/novnc_terminal.png)
110+
4. In the new terminal run `rviz -d ./src/zero_sim_ros/rviz/turtlebot_viewer.rviz`. RViz will start up with a 3D view with the LIDAR scanner visibile. ![RViz Turtlebot Viewer](Documentation~/images/rviz_turtlebot.gif)

Runtime/Scripts/ROS/Unity/Controllers/ZOArmController.cs

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,25 +181,26 @@ protected override void ZOFixedUpdateHzSynchronized() {
181181
if (GoalStatus == ActionStatusEnum.ACTIVE) {
182182

183183
// find the closest target position given the current time
184-
bool foundTargetPoint = false;
185-
foreach (JointTrajectoryPointMessage point in Goal.goal.trajectory.points) {
186-
// Debug.Log("INFO: point time: " + point.time_from_start.Seconds.ToString("R3"));
187-
if (_currentGoalTime <= point.time_from_start.Seconds) {
188-
_currentPoint = point;
189-
foundTargetPoint = true;
190-
break;
191-
}
192-
}
193-
194-
195-
if (foundTargetPoint == true) {
184+
// bool foundTargetPoint = false;
185+
// foreach (JointTrajectoryPointMessage point in Goal.goal.trajectory.points) {
186+
// // Debug.Log("INFO: point time: " + point.time_from_start.Seconds.ToString("R3"));
187+
// if (_currentGoalTime <= point.time_from_start.Seconds) {
188+
// _currentPoint = point;
189+
// foundTargetPoint = true;
190+
// break;
191+
// }
192+
// }
193+
194+
double[] interpolatedJointPositions = GetJointPositionsAtTimeSeconds(Goal.goal.trajectory.points, _currentGoalTime);
195+
if (interpolatedJointPositions != null) {
196+
196197

197198
for (int i = 0; i < Goal.goal.trajectory.joint_names.Length; i++) {
198199
_trajectoryControllerStateMessage.joint_names[i] = Goal.goal.trajectory.joint_names[i];
199200
ZOJointInterface joint = GetJointByName(Goal.goal.trajectory.joint_names[i]);
200201

201-
_trajectoryControllerStateMessage.desired.positions[i] = _currentPoint.positions[i];
202-
ActionMessage.action_feedback.feedback.desired.positions[i] = _currentPoint.positions[i];
202+
_trajectoryControllerStateMessage.desired.positions[i] = interpolatedJointPositions[i];
203+
ActionMessage.action_feedback.feedback.desired.positions[i] = interpolatedJointPositions[i];
203204

204205
_trajectoryControllerStateMessage.actual.positions[i] = joint.Position;
205206
ActionMessage.action_feedback.feedback.actual.positions[i] = joint.Position;
@@ -301,6 +302,41 @@ protected override void ZOOnGUI() {
301302
}
302303
#endregion // ZOGameObjectBase
303304

305+
#region Utils
306+
307+
protected double[] GetJointPositionsAtTimeSeconds(JointTrajectoryPointMessage[] points, float timeSeconds) {
308+
309+
if (points.Length > 1) {
310+
for (int i = 1; i < points.Length; i++) {
311+
// search for bracket
312+
double aTime = points[i - 1].time_from_start.Seconds;
313+
double bTime = points[i].time_from_start.Seconds;
314+
if (timeSeconds > aTime && timeSeconds <= bTime) {
315+
316+
double timeBetweenPoints = bTime - aTime;
317+
if (timeBetweenPoints > 0) {
318+
double timeFromA = timeSeconds - aTime;
319+
double t = timeFromA / timeBetweenPoints;
320+
int numPositions = points[i].positions.Length;
321+
double[] interpolatedJointPositions = new double[numPositions];
322+
for (int p = 0; p < numPositions; p++) {
323+
double aJointPosition = points[i-1].positions[p];
324+
double bJointPosition = points[i].positions[p];
325+
interpolatedJointPositions[p] = Mathf.LerpAngle((float)aJointPosition * Mathf.Rad2Deg, (float)bJointPosition * Mathf.Deg2Rad, (float)t) * Mathf.Deg2Rad;
326+
}
327+
328+
return interpolatedJointPositions;
329+
330+
}
331+
}
332+
}
333+
}
334+
335+
return null; // failed to find joint positions bracket. perhaps time has gone beyond the last joint position.
336+
}
337+
338+
#endregion // Utils
339+
304340
#region ZOROSControllerInterface
305341

306342
public string ControllerName {
@@ -363,6 +399,11 @@ public string[] JointNames {
363399
}
364400
}
365401

402+
/// <summary>
403+
/// Get Joint given its string name
404+
/// </summary>
405+
/// <param name="name">The name of the joint</param>
406+
/// <returns>ZOJointInterface</returns>
366407
public ZOJointInterface GetJointByName(string name) {
367408
foreach (ZOJointInterface joint in Joints) {
368409
if (joint.Name == name) {

Samples~/ZeroSimSamples/Assets/PhysicsMaterials/StickyNoBounce.physicMaterial

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ PhysicMaterial:
77
m_PrefabInstance: {fileID: 0}
88
m_PrefabAsset: {fileID: 0}
99
m_Name: StickyNoBounce
10-
dynamicFriction: 1
11-
staticFriction: 1
10+
dynamicFriction: 2
11+
staticFriction: 2
1212
bounciness: 0
1313
frictionCombine: 0
1414
bounceCombine: 0

0 commit comments

Comments
 (0)