Coder Social home page Coder Social logo

atsushisakai / pyroombaadapter Goto Github PK

View Code? Open in Web Editor NEW
72.0 7.0 21.0 689 KB

A Python library for Roomba Open Interface

Home Page: https://atsushisakai.github.io/PyRoombaAdapter/

License: MIT License

Shell 9.98% Python 89.45% Makefile 0.57%
python-library python3 python roomba robotics autonomous-robots navigation

pyroombaadapter's Introduction

PyRoombaAdapter

A Python library for Roomba Open Interface

Downloads Downloads Downloads

What is this?

This is a python library for Roomba Open Interface(ROI)

This module is based on the document:

It aims to control a Roomba easily.

This module is only tested on Roomba 690 model.

Install

You can use pip to install it.

$ pip install pyroombaadapter

Requirements

  • Python 3.6.x or higher (2.7 is not supported)

  • pyserial

Documentation

Please check the document for all API and usages.

Usage examples

All examples are in examples directory.

Click each image to see each example movie.

Go and back example

This example uses "move" API.

"""
    Go and back example with roomba
"""
from time import sleep
import math
from pyroombaadapter import PyRoombaAdapter

PORT = "/dev/ttyUSB0"
adapter = PyRoombaAdapter(PORT)
adapter.move(0.2, math.radians(0.0))  # go straight
sleep(1.0)
adapter.move(0, math.radians(-20))  # turn right
sleep(6.0)
adapter.move(0.2, math.radians(0.0))  # go straight
sleep(1.0)
adapter.move(0, math.radians(20))  # turn left
sleep(6.0)

#Print the total distance traveled
print(f"distance: {adapter.request_distance()} mm, angle: {adapter.request_angle()} rad")

Play song1

This example uses "send_song_cmd" and "send_play_cmd" API.

"""
    Play Darth Vader song
"""
from time import sleep

from pyroombaadapter import PyRoombaAdapter

PORT = "/dev/ttyUSB0"
adapter = PyRoombaAdapter(PORT)

adapter.send_song_cmd(0, 9,
                      [69, 69, 69, 65, 72, 69, 65, 72, 69],
                      [40, 40, 40, 30, 10, 40, 30, 10, 80])
adapter.send_play_cmd(0)
sleep(10.0)

Play song2

This example uses "send_song_cmd" and "send_play_cmd" API.

"""
    Play namidaga kirari by spitz
"""
from time import sleep

from pyroombaadapter import PyRoombaAdapter

PORT = "/dev/ttyUSB0"
adapter = PyRoombaAdapter(PORT)

adapter.send_song_cmd(0, 10,
                      [66, 67, 69, 67, 66, 62, 64, 66, 67, 66],
                      [16, 16, 16, 32, 32, 16, 16, 16, 16, 64])

sleep(1.0)
adapter.send_song_cmd(1, 9,
                      [66, 67, 69, 67, 66, 71, 59, 62, 61],
                      [16, 16, 16, 32, 32, 32, 16, 16, 64])

sleep(1.0)
adapter.send_song_cmd(2, 13,
                      [62, 64, 61, 62, 64, 66, 62, 64, 66, 67, 64, 66, 71],
                      [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16])
sleep(1.0)
adapter.send_song_cmd(3, 7,
                      [71, 67, 64, 62, 61, 62, 62],
                      [16, 16, 16, 16, 48, 16, 64])

sleep(3.0)
adapter.send_play_cmd(0)
sleep(4.0)
adapter.send_play_cmd(1)
sleep(4.0)
adapter.send_play_cmd(0)
sleep(4.0)
adapter.send_play_cmd(1)
sleep(4.0)
adapter.send_play_cmd(2)
sleep(4.0)
adapter.send_play_cmd(3)
sleep(4.0)

Read sensors

There are two ways how to read sensor values. Request manually on demand:

"""
    Read Roomba sensors
"""
from time import sleep
from pyroombaadapter import PyRoombaAdapter

PORT = "/dev/ttyUSB0"
adapter = PyRoombaAdapter(PORT)
adapter.change_mode_to_passive()

# Request sensor value manually
print(adapter.request_charging_state())
print(adapter.request_voltage())
print(adapter.request_current())
print(adapter.request_temperature())
print(adapter.request_charge())
print(adapter.request_capacity())
print(adapter.request_oi_mode())
print(adapter.request_distance())
print(adapter.request_angle())

Start a data stream:

"""
    Read Roomba sensors
"""
from time import sleep
from pyroombaadapter import PyRoombaAdapter

PORT = "/dev/ttyUSB0"
adapter = PyRoombaAdapter(PORT)
adapter.change_mode_to_passive()

# Read sensor value from data stream
adapter.data_stream_start(
    ["Charging State", "Voltage", "Current", "Temperature", "Battery Charge", "Battery Capacity", "OI Mode"])
sleep(1)
print(adapter.data_stream_read())
sleep(1)
print(adapter.data_stream_read())
sleep(1)
print(adapter.data_stream_read())
sleep(1)
adapter.data_stream_stop()

Contribution

Any contributions to this project are welcome!

Feel free to make an issue and a PR to improve this OSS.

License

MIT

Authors

pyroombaadapter's People

Contributors

15jgme avatar atsushisakai avatar hirohashi avatar mrkeuz avatar process1183 avatar rforro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyroombaadapter's Issues

NameError: name 'SerialException' is not defined

Hi. If you try to create a new instance of PyRoombaAdapter without the serial port being present, it raises a SerialException. However, this exception is not defined in pyroombaadapter.py and causes a NameError exception to be raised. This is an easy fix (see commit process1183@8699ffc). After fixing the SerialException definition, I ran into another issue: If opening the serial port fails, then the __del__() method also throws an exception. Here's an example of this:

Python 3.7.3 (default, Jan 22 2021, 20:04:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyroombaadapter
>>> roomba = pyroombaadapter.PyRoombaAdapter("/dev/doesnotexist")
Cannot find serial port. Plase reconnect it.
Exception ignored in: <function PyRoombaAdapter.__del__ at 0x7f96d2691b70>
Traceback (most recent call last):
  File "/home/josh/projects/forked/PyRoombaAdapter/pyroombaadapter/pyroombaadapter.py", line 86, in __del__
    self._send_cmd(self.CMD["Start"])  # move to passive mode
  File "/home/josh/projects/forked/PyRoombaAdapter/pyroombaadapter/pyroombaadapter.py", line 608, in _send_cmd
    self.serial_con.write(bytes([cmd]))
AttributeError: 'PyRoombaAdapter' object has no attribute 'serial_con'

One possible solution is to check that self.serial_con exists before trying to set the Roomba to passive mode and close the connection in __del__(). Does this seem like a good solution to you? If so, I can include it in the pull request for the SerialException fix.

v0.2.0

[ ] design architecture of getting sensor data
[ ] Implement API to get Sensor Packets

Pip install fails for version 0.1.4

Hello. Attempting to install PyRoombaAdapter 0.1.4 from pip results in an error:

josh@roomba:~$ sudo pip3 install pyroombaadapter
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pyroombaadapter
  Downloading https://files.pythonhosted.org/packages/2a/a6/beb4c900dfaa642c04364e1de1a1262b02bd7611b7d7a67f4cd4a57db230/pyroombaadapter-0.1.4.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-d7kk3yw9/pyroombaadapter/setup.py", line 25, in <module>
        with open(PROJECT_PATH + "/VERSION", 'r') as fd:
    FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-install-d7kk3yw9/pyroombaadapter/VERSION'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-d7kk3yw9/pyroombaadapter/

'byte_tool' is not defined

Hi! Trying to use the send_drive_direct() and send_drive_pwm() methods raise the following exception: NameError: name 'byte_tool' is not defined. It looks like these methods should be using self._get_2_bytes() instead.

sys.exit(1) is hard-coded in PyRoombaAdapter.__init__() and permit any retries

Hi,

I found that in constructor of PyRoombaAdapter a sys.exit(1) call is hard-coded, so you cannot try to reconnect without restart python script. So if serial connect is fail you cannot as program exit with no option.

I think more flexible here is just re-raise some custom exception with human-readable message.

What you think about this?

Docs improvments: 'np.deg2rad(x)' can be replaced to 'math.radiant(x)'

Hi,

I found that numpy.deg2rad(x) in all examples can be replaced to standard library call math.radians(x) and thus avoid heavyweight NumPy dependency in examples at start.

I think it will be easier and faster for fast try and start.

Here is small test for interdependence these functions. Seems work fine:

import math
import numpy as np

from unittest import TestCase


class Deg2Radians(TestCase):
    def testDeg2radians(self):
        self.assertInterdependence(0.0)
        self.assertInterdependence(23.0)
        self.assertInterdependence(45.0)
        self.assertInterdependence(360.0)
        self.assertInterdependence(720.0)
        self.assertInterdependence(-720.0)
        self.assertInterdependence(-90.0)
        self.assertInterdependence(-10.0)
        self.assertInterdependence(-90)
        self.assertInterdependence(-10)

    def assertInterdependence(self, degrees):
        np_rad = np.deg2rad(degrees)
        math_rad = math.radians(degrees)

        self.assertFloat(np_rad)
        self.assertFloat(math_rad)
        self.assertAlmostEqual(math_rad, np_rad)

    def assertFloat(self, value):
        try:
            float(value)
        except ValueError:
            self.fail(f"Value {value} cannot be convert to float")

See: https://docs.python.org/3/library/math.html#math.radians

PS: Thanks for cool project! 🚀

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.