mmwise / sphero_ros

A Sphero ROS driver.
76 stars 61 forks source link

Runtime error: Bad SOF #3

Closed davinellulinvega closed 9 years ago

davinellulinvega commented 9 years ago

Hello,

First of all, congratulation for developing such a wonderful API for the sphero robot. As a beginner with both python and sphero, I tried to put together a simple application where one could make the sphero roll, using the arrow keys on the computer, and the terminal would display the position and speed of the robot. Thus, I have been heavily relying on your sphero_driver.py (I am not using ROS for the moment). However, after calling the set_data_stream function, with what I believe to be the right parameters, and starting a new thread for the data streaming, I get the following exception in the thread dedicated to receiving the data:


Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
File "/usr/local/lib/python2.7/dist-packages/sphero_driver/sphero_driver.py", line 754, in run
    self.recv(1024)
File "/usr/local/lib/python2.7/dist-packages/sphero_driver/sphero_driver.py", line 834, in recv
    raise RuntimeError("Bad SOF : " + self.data2hexstr(data))

RuntimeError: Bad SOF : 75 3e ff fe 03 00 05 00 01 ff f8 ff
RuntimeError: Bad SOF : 75 3e ff fe 03 00 05 00 00 ff fd fb

I tried to run the code twice, hence the two Runtime Error at the end. The only problem I have noticed so far is that it seems the socket still contains some data ("75 3e" in both cases) and is therefore not able to determine what to do with the packet. Do you have any ideas as to how I could handle this problem?

Thank you very much in advance for your help. Sincerely.

mmwise commented 9 years ago

Can you post the code that you are trying to run with the set_data_stream function?

davinellulinvega commented 9 years ago

Hello,

I thank you very much for answering so quickly. Here is the code I am trying to run:


import bluetooth
from sphero_driver import sphero_driver
import curses
from time import sleep
# Create a sphero object
sphero = sphero_driver.Sphero()
# Connect to the first available sphero over bluetooth
sphero.connect()
# Set the stream of data
sphero.set_data_strm(40, 1, 0, 0, sphero_driver.STRM_MASK2['ODOM_Y'] | sphero_driver.STRM_MASK2['ODOM_X'], False)
# Start a thread for data steaming
sphero.start()
# Initialize the user input
user_in = ""
while user_in != "q":
    # Display a very simple menu
    print("------------ Menu ------------")
    print("i    interactive mode")
    print("h    set heading")
    print("q    quit")
    # Ask the user for some input
    user_in = raw_input("Please make your choice: \n")
    # Treat the user's request
    if user_in == "i":
        # Initialize a curse object
        std_scr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        std_scr.keypad(1)
        # Activate the tail led
        sphero.set_back_led(255, False)
        # Initialize the heading and speed
        heading = 0
        speed = 0
        # Get the user input
        while 1:
            key = std_scr.getch()
            # React to the input
            if key == ord('q'):
                sphero.roll(0, 0, 0x00, False)
                # Activate the tail led
                sphero.set_back_led(0, False)
                break
            elif key == curses.KEY_LEFT:
                # Compute the new heading
                heading = (360 + (heading - 7)) % 360
            elif key == curses.KEY_RIGHT:
                # Compute the new heading
                heading = (heading + 7) % 360
            elif key == curses.KEY_UP:
                # Increase the speed
                if speed <= 115:
                    speed += 10
            elif key == curses.KEY_DOWN:
                # Decrease the speed
                if speed >= 10:
                    speed -= 10
                # If the speed is negative go in the opposite direction
                if speed == 0:
                    heading = (heading + 180) % 360
            # Roll in the new direction
            sphero.roll(abs(speed), heading, 0x01, False)
        # Terminate the curses window
        curses.endwin()
    elif user_in == "h":
        # Initialize a curse object
        std_scr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        std_scr.keypad(1)
        # Activate the tail led
        sphero.set_back_led(255, False)
        # Set the heading to 0
        heading = 0
        sphero.set_heading(heading, False)
        # Get the user input
        while 1:
            key = std_scr.getch()
            # React to the input
            if key == ord('q'):
                break
            elif key == curses.KEY_LEFT:
                # Compute the new heading
                heading = (360 + (heading - 5)) % 360
            elif key == curses.KEY_RIGHT:
                # Compute the new heading
                heading = (heading + 5) % 360
            # Set the new heading
            sphero.set_heading(heading, False)
        # Deactivate the tail led
        sphero.set_back_led(0, False)
        # Terminate the curses window
        curses.endwin()
# Wait for both threads to come to an end
sphero.join(20)
# Disconnect from the sphero robot
sphero.disconnect()
# Print a goodbye message
print("Goodbye hope to see you soon")

It is quite a messy source code, I am sorry for that, but should display a menu for setting the heading or controlling the sphero through the arrow keys.

For information, I am running a Sphero 2.0 with firmware version 3.59 and executing this piece of code on ubuntu 15.04.

Thank you very much for your help. Sincerely.

davinellulinvega commented 9 years ago

After some thought and readings of your source code, I realised two things. The exception Error bad SOF, is triggered when there is remaining data in the socket from a previous program that exited with an error. And for me to be able to treat the result of the data streaming, I should declare a freaking function that does the intended job. All in all I only have my own stupidity to blame for all this.

Still thank you very much for answering me. Sincerely.