ROS-like Python library for game robot control via WebSocket
Project description
agroweekpy
ROS-like Python library for game robot control via WebSocket.
Overview
agroweekpy provides a familiar rospy-style API for controlling robots in a game via WebSocket communication. It supports:
- Motor Control: Set velocities for left and right motors
- Odometry: Get distance traveled by motors
- Yaw/Orientation: Get rotation angle (Y-axis)
Installation
pip install -e .
Or install dependencies directly:
pip install websockets
Quick Start
import agroweekpy
from agroweekpy.msg import MotorCommand
# Initialize node and connect to game
agroweekpy.init_node('my_rover', uri='ws://localhost:8765')
# Create motor publisher
motor_pub = agroweekpy.Publisher('/motor_cmd', MotorCommand)
# Main control loop
rate = agroweekpy.Rate(10) # 10 Hz
while not agroweekpy.is_shutdown():
cmd = MotorCommand(left_velocity=0.5, right_velocity=0.5)
motor_pub.publish(cmd)
rate.sleep()
API Reference
Node Management
# Initialize node
agroweekpy.init_node(name, uri='ws://localhost:8765', anonymous=False)
# Check shutdown state
agroweekpy.is_shutdown() # Returns True/False
# Block until shutdown
agroweekpy.spin()
# Request shutdown
agroweekpy.signal_shutdown(reason='done')
# Register shutdown callback
agroweekpy.on_shutdown(lambda reason: print(f'Shutting down: {reason}'))
Rate Control
rate = agroweekpy.Rate(10) # 10 Hz
while not agroweekpy.is_shutdown():
# Do work...
rate.sleep() # Sleep to maintain rate
Logging
agroweekpy.logdebug('Debug message')
agroweekpy.loginfo('Info message')
agroweekpy.logwarn('Warning message')
agroweekpy.logerr('Error message')
agroweekpy.logfatal('Fatal message')
Publisher
from agroweekpy import Publisher
from agroweekpy.msg import MotorCommand
# Create publisher
pub = Publisher('/motor_cmd', MotorCommand, queue_size=10)
# Publish message
cmd = MotorCommand(left_velocity=0.5, right_velocity=0.5)
pub.publish(cmd)
MotorPublisher (Convenience Class)
from agroweekpy import MotorPublisher
motor = MotorPublisher('/motor_cmd')
motor.forward(0.5) # Move forward
motor.backward(0.5) # Move backward
motor.turn_left(0.3) # Turn left in place
motor.turn_right(0.3) # Turn right in place
motor.stop() # Stop motors
motor.set_velocity(0.5, 0.3) # Set left/right velocities
Subscriber
from agroweekpy import Subscriber
from agroweekpy.msg import Odometry
def callback(msg):
print(f'Distance: {msg.total_distance}')
sub = Subscriber('/odometry', Odometry, callback)
OdometrySubscriber (Convenience Class)
from agroweekpy import OdometrySubscriber
odom = OdometrySubscriber('/odometry')
odom.get_distance() # Total distance (average of both motors)
odom.get_left_distance() # Left motor distance
odom.get_right_distance() # Right motor distance
odom.get_odometry() # Full Odometry message
YawSubscriber (Convenience Class)
from agroweekpy import YawSubscriber
yaw = YawSubscriber('/yaw')
yaw.get_angle() # Current angle in degrees
yaw.get_angle_radians() # Current angle in radians
yaw.get_normalized_angle() # Angle in -180 to 180 range
yaw.get_angular_velocity() # Angular velocity (deg/s)
yaw.angle_to(90.0) # Shortest angle to target
Message Types
MotorCommand
from agroweekpy.msg import MotorCommand
cmd = MotorCommand(left_velocity=0.5, right_velocity=0.5)
cmd.left_velocity # -1.0 to 1.0
cmd.right_velocity # -1.0 to 1.0
cmd.timestamp # Auto-generated
# Convenience methods
cmd.forward(0.5)
cmd.backward(0.5)
cmd.turn_left(0.3)
cmd.turn_right(0.3)
cmd.stop()
Odometry
from agroweekpy.msg import Odometry
odom = Odometry(left_distance=10.5, right_distance=10.3)
odom.left_distance # Left motor distance
odom.right_distance # Right motor distance
odom.total_distance # Average distance
odom.left_velocity # Current left velocity
odom.right_velocity # Current right velocity
Yaw
from agroweekpy.msg import Yaw
yaw = Yaw(angle=45.0)
yaw.angle # Angle in degrees
yaw.radians # Angle in radians
yaw.normalized_angle # -180 to 180
yaw.angular_velocity # deg/s
yaw.angle_to(90.0) # Shortest turn to target
WebSocket Protocol
Message Format
All messages are JSON with this structure:
{
"topic": "/motor_cmd",
"data": {
"left_velocity": 0.5,
"right_velocity": 0.5,
"timestamp": 1706450400.123
},
"timestamp": 1706450400.123
}
Topics
| Topic | Direction | Message Type | Description |
|---|---|---|---|
/motor_cmd |
Client → Game | MotorCommand | Motor velocity commands |
/odometry |
Game → Client | Odometry | Motor distances |
/yaw |
Game → Client | Yaw | Robot orientation |
Expected Game Server Messages
Odometry (sent by game):
{
"topic": "/odometry",
"data": {
"left_distance": 10.5,
"right_distance": 10.3,
"left_velocity": 0.5,
"right_velocity": 0.5,
"timestamp": 1706450400.123
}
}
Yaw (sent by game):
{
"topic": "/yaw",
"data": {
"angle": 45.0,
"angular_velocity": 5.0,
"timestamp": 1706450400.123
}
}
Configuration
agroweekpy.init_node(
'my_rover',
uri='ws://192.168.1.100:8765', # Game server URI
anonymous=False, # Add timestamp to name
log_level=logging.INFO, # Logging level
reconnect=True, # Auto-reconnect
reconnect_interval=1.0, # Initial reconnect delay
max_reconnect_interval=30.0, # Max reconnect delay
ping_interval=20.0, # WebSocket ping interval
)
Examples
See the examples/ directory for complete examples:
basic_publisher.py- Simple motor controlodometry_listener.py- Reading odometry datayaw_listener.py- Reading orientation datarover_controller.py- Complete rover control examplemock_game_server.py- Mock server for testing
Comparison with rospy
| rospy | agroweekpy | Notes |
|---|---|---|
rospy.init_node() |
agroweekpy.init_node() |
Similar API |
rospy.Publisher() |
agroweekpy.Publisher() |
Same pattern |
rospy.Subscriber() |
agroweekpy.Subscriber() |
Same pattern |
rospy.Rate() |
agroweekpy.Rate() |
Same pattern |
rospy.spin() |
agroweekpy.spin() |
Same behavior |
rospy.is_shutdown() |
agroweekpy.is_shutdown() |
Same behavior |
rospy.loginfo() |
agroweekpy.loginfo() |
Same API |
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agroweekpy-1.0.0.tar.gz.
File metadata
- Download URL: agroweekpy-1.0.0.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42afb3e1491d9824f0ad4928170698e89889d92288802b2d04c5e26f2fcf91ab
|
|
| MD5 |
6f3da9f57e384d06b79f4e93fefb9f34
|
|
| BLAKE2b-256 |
206517aa66473f1f978f77353e50bf5b579e9ef078208fa033bbb885d5073fd3
|
File details
Details for the file agroweekpy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: agroweekpy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ef31e3317d0602217acb53ecf9705b40f3592a9ea8332526f3ec0a421f53d4d
|
|
| MD5 |
431f6e4055a9ca684814ed8ad1b7bf61
|
|
| BLAKE2b-256 |
748ed340b478d36a8e7b0a607a0ef2e59fa1d9a4104383784197f6be751e3150
|