Skip to content

Commit

Permalink
Demo code update to draw a heart shape
Browse files Browse the repository at this point in the history
  • Loading branch information
nhjschulz committed Aug 26, 2024
1 parent ca2855b commit 1843b57
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 24 deletions.
42 changes: 37 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,59 @@
A ROS2 TurtleSim Python Controller similar to turtle_teleop_key, but
using python turtle command scripts for controlling instead of key strokes.

Running this example wiill result in the following output:
![turtle_sim_pythonop_demo](./doc/turtlesim_pythonop_demo.png)

Read the [ROS2 turtlesim Tutorial](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.html)
if you are unfamiliar with this evironment.

# Installation and Running as ROS package
The following Python turtle commands are supported. See the
[Python Turtle](https://docs.python.org/3/library/turtle.html) page for command
details.

* Movement

forward(), backward(), right(), left(), goto(), setpos(), teleport(), setx(),
sety(), setheading(), home(), circle()

* State

position(), towards(), xcor(), ycor(), heading(), distance(), clear()

* Pen Control

pendown(), penup()

1. Clone this repository into a ros2 workspace src folder

## Installation and Running as ROS2 package

1. Clone this repository into a ROS2 workspace src folder
2. Build workspace with `colcon build` followed by `source install/local_setup.bash`
3. In another terminal launch the turtlesim package as described in the ROS2 Tutorial

sudo apt install ros-jazzy-turtlesim
sudo apt install ros-$ROS_DISTRO-turtlesim
ros2 run turtlesim turtlesim_node

3. Run this package from the workspace with

run turtlesim_teleop_python pythonop_turtle

# Interactive Test
## Parameter

The package provides the following custom parameters:

| Parameter | Type |Description | Default |
|---------------|-------|--------------------------------------------------| --------|
| delay | float | Delay between sending update messages in seconds.| 1.0 |
| scale_angular | float | Scale factor for angular movements. | 1.0 |
| scale_linear | float | Scale factor for linear movements. | 1.0 |


## Interactive Usage

Interactive testing is working by going into
`turtlesim_teleop_python/turtlesim_teleop_python` folder
and start python3. Then execute the commands below as an example:
and start python3 from there. Then execute the commands below as an example:

```python
import rclpy
Expand Down
Binary file added doc/turtlesim_pythonop_demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 37 additions & 19 deletions turtlesim_teleop_python/pythonop_turtle.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def clear(self) -> None:
"""Send clear request."""
request = Empty.Request()
self._clear_srv.call_async(request)
self._delay()


def penup(self) -> None:
"""Lift the pen up."""
Expand All @@ -92,6 +94,8 @@ def penup(self) -> None:
request.width = 3
request.off = 1
self._setPen_srv.call_async(request)
self._delay()


pu = penup
up = penup
Expand All @@ -105,6 +109,7 @@ def pendown(self) -> None:
request.width = 3
request.off = 0
self._setPen_srv.call_async(request)
self._delay()

def delay(self, dl=None) -> float:
"""Set or get update turtle update delay in seconds."""
Expand Down Expand Up @@ -137,7 +142,8 @@ def goto(self, x, y) -> None:
request.y = float(self.ycor()) * self._scale_linear
request.theta = math.radians(self.heading() * self._scale_angular)
self._teleport_abs_srv.call_async(request)
rclpy.spin_once(self, timeout_sec=0.0)
self._delay()


def _rotate(self, angle):
super()._rotate(angle)
Expand All @@ -159,12 +165,14 @@ def _update_geometry(self, distance: float = 0.0, angle: float = 0.0) -> None:
msg.linear.x = float(distance) * self._scale_linear
self._publisher.publish(msg)

# tiwst message delay
self._delay()

def _delay(self, n=None):
"""Message delay wait."""
wait_for_time = time.time() + self._twist_delay
while time.time() < wait_for_time:
rclpy.spin_once(self, timeout_sec=0.0)


def main(args=None):
"""Application runnable enty point."""
rclpy.init(args=args)
Expand All @@ -176,26 +184,36 @@ def main(args=None):

def demo(turtle: TurtleTwistPublisher) -> None:
"""Do some turtle fun."""
turtle.penup()
turtle.clear()
turtle.penup()
turtle.home()
turtle.left(90.0)
turtle.forward(1.0)
turtle.pendown()
turtle.left(90)
turtle.forward(5)
turtle.right(160)
turtle.forward(5.5)
turtle.left(160)
turtle.forward(5)
turtle.right(90)
turtle.forward(3)
turtle.backward(1.5)
turtle.right(90)
turtle.forward(5)
turtle.circle(radius=1.0, extent=180.1)
turtle.right(180.0)
turtle.circle(radius=1.0, extent=180.1)
x = turtle.xcor()
y = turtle.ycor()
for i in range(0,181, 30):
print(i)
print(math.cos(math.radians(float(i))))
turtle.goto(
x + 1.0 - math.cos(math.radians(float(i))),
y - i /90)

x = turtle.xcor()
y = turtle.ycor()
for i in range(0,181, 30):
print(i)
print(math.cos(math.radians(float(i))))
turtle.goto(
x + 1.0 + math.cos(math.radians(180.0 + float(i))),
y + i /90)

turtle.penup()
turtle.goto(2, 2)
turtle.pendown()
turtle.circle(1.5)
turtle.home()


if __name__ == "__main__":
if __name__ == "__main__":
main()

0 comments on commit 1843b57

Please sign in to comment.