├── .gitignore ├── LICENSE.md ├── Pipfile ├── README.md ├── SpheroSDKLicense2Oct2019.pdf ├── docs └── SpheroRVRControlSystemManual.pdf ├── first-time-setup.sh ├── getting_started ├── __init__.py ├── asyncio │ ├── __init__.py │ ├── api_and_shell │ │ ├── __init__.py │ │ ├── echo.py │ │ └── generate_api_error.py │ ├── color_sensor │ │ ├── __init__.py │ │ └── color_detection.py │ ├── driving │ │ ├── __init__.py │ │ ├── control_system_selection.py │ │ ├── control_system_timeouts.py │ │ ├── drive_raw_motors.py │ │ ├── drive_rc_normalized.py │ │ ├── drive_rc_si_units.py │ │ ├── drive_tank_normalized.py │ │ ├── drive_tank_si.py │ │ ├── drive_target_slewing.py │ │ ├── drive_to_position_normalized.py │ │ ├── drive_to_position_si.py │ │ ├── drive_with_heading.py │ │ ├── drive_with_heading_reverse_mode.py │ │ ├── drive_with_helper.py │ │ ├── drive_with_helper_roll.py │ │ ├── drive_with_stop_controller.py │ │ ├── drive_with_yaw_normalized.py │ │ ├── drive_with_yaw_si_units.py │ │ └── get_encoder_counts.py │ ├── infrared │ │ ├── __init__.py │ │ ├── broadcast_ir.py │ │ ├── broadcast_ir_with_helper.py │ │ ├── listen_for_and_send_ir.py │ │ └── listen_for_and_send_ir_with_helper.py │ ├── leds │ │ ├── __init__.py │ │ ├── set_all_leds.py │ │ ├── set_all_leds_with_helper.py │ │ ├── set_multiple_leds.py │ │ ├── set_multiple_leds_with_helper.py │ │ ├── set_single_led.py │ │ └── set_single_led_with_helper.py │ ├── magnetometer │ │ ├── __init__.py │ │ ├── get_magnetometer_reading.py │ │ └── magnetometer_calibrate_to_north.py │ ├── motors │ │ ├── __init__.py │ │ ├── get_motor_fault_state.py │ │ ├── get_thermal_protection_status.py │ │ ├── motor_fault_notification.py │ │ ├── motor_stall_notification.py │ │ └── thermal_protection_notification.py │ ├── power │ │ ├── __init__.py │ │ ├── get_battery_state.py │ │ ├── get_battery_state_notifications.py │ │ └── sleep_monitoring.py │ ├── sensor_streaming │ │ ├── __init__.py │ │ ├── change_stream_settings.py │ │ ├── multi_sensor_stream.py │ │ └── single_sensor_stream.py │ └── system │ │ ├── __init__.py │ │ ├── disable_notifications_and_active_commands.py │ │ └── get_main_app_version.py └── observer │ ├── __init__.py │ ├── api_and_shell │ ├── __init__.py │ ├── echo.py │ └── generate_api_error.py │ ├── color_sensor │ ├── __init__.py │ └── color_detection.py │ ├── driving │ ├── __init__.py │ ├── control_system_selection.py │ ├── control_system_timeouts.py │ ├── drive_raw_motors.py │ ├── drive_rc_normalized.py │ ├── drive_rc_si_units.py │ ├── drive_tank_normalized.py │ ├── drive_tank_si.py │ ├── drive_target_slewing.py │ ├── drive_to_position_normalized.py │ ├── drive_to_position_si.py │ ├── drive_with_heading.py │ ├── drive_with_heading_reverse_mode.py │ ├── drive_with_helper.py │ ├── drive_with_helper_roll.py │ ├── drive_with_stop_controller.py │ ├── drive_with_yaw_normalized.py │ ├── drive_with_yaw_si_units.py │ └── get_encoder_counts.py │ ├── infrared │ ├── __init__.py │ ├── broadcast_ir.py │ ├── broadcast_ir_with_helper.py │ ├── listen_for_and_send_ir.py │ └── listen_for_and_send_ir_with_helper.py │ ├── leds │ ├── __init__.py │ ├── set_all_leds.py │ ├── set_all_leds_with_helper.py │ ├── set_multiple_leds.py │ ├── set_multiple_leds_with_helper.py │ ├── set_single_led.py │ └── set_single_led_with_helper.py │ ├── magnetometer │ ├── __init__.py │ ├── get_magnetometer_reading.py │ └── magnetometer_calibrate_to_north.py │ ├── motors │ ├── __init__.py │ ├── get_motor_fault_state.py │ ├── get_thermal_protection_status.py │ ├── motor_fault_notification.py │ ├── motor_stall_notification.py │ └── thermal_protection_notification.py │ ├── power │ ├── __init__.py │ ├── get_battery_state.py │ ├── get_battery_state_notifications.py │ └── sleep_monitoring.py │ ├── sensor_streaming │ ├── __init__.py │ ├── change_stream_settings.py │ ├── multi_sensor_stream.py │ └── single_sensor_stream.py │ └── system │ ├── __init__.py │ ├── disable_notifications_and_active_commands.py │ └── get_main_app_version.py ├── projects ├── __init__.py ├── keyboard_control │ ├── Pipfile │ ├── README.md │ ├── __init__.py │ ├── drive_with_wasd_keys.py │ └── helper_keyboard_input.py ├── rc_rvr │ ├── README.md │ ├── __init__.py │ ├── autostart_rc_rvr.sh │ ├── debug │ │ ├── __init__.py │ │ ├── sbus_drive_test.py │ │ ├── serial_print_bytes.py │ │ ├── serial_print_channels.py │ │ └── serial_print_payload.py │ ├── images │ │ ├── SBUS_RVR_Diagram.png │ │ └── X8R_Diagram.png │ ├── pysbus │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── sbus.py │ │ └── serial_parser.py │ ├── rc_async_rvr.py │ └── rc_observer_rvr.py ├── rvr_bolt_ir │ ├── README.md │ ├── __init__.py │ ├── bolt_rvr_follow.lab │ └── rvr_ir_broadcast.py └── ultrasonic_rvr │ ├── Pipfile │ ├── README.md │ ├── images │ ├── Mounting_Suggestion.jpg │ └── Ultrasonic_RVR_Diagram.jpg │ └── ultrasonic_rvr.py ├── requirements.txt ├── setup.py ├── sphero_sdk ├── __init__.py ├── __version__.py ├── asyncio │ ├── __init__.py │ ├── client │ │ ├── __init__.py │ │ ├── dal │ │ │ ├── __init__.py │ │ │ └── serial_async_dal.py │ │ ├── firmware │ │ │ ├── __init__.py │ │ │ └── rvr_fw_check_async.py │ │ └── toys │ │ │ ├── __init__.py │ │ │ └── sphero_rvr_async.py │ ├── config │ │ ├── __init__.py │ │ └── logging_config.py │ ├── controls │ │ ├── __init__.py │ │ ├── drive_control_async.py │ │ ├── infrared_control_async.py │ │ ├── led_control_async.py │ │ └── sensor_control_async.py │ └── server │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── handler │ │ ├── __init__.py │ │ ├── api_sphero_handler.py │ │ └── sphero_handler_base.py │ │ ├── parser │ │ ├── __init__.py │ │ ├── api_sphero_parser.py │ │ └── sphero_parser_base.py │ │ ├── port │ │ ├── __init__.py │ │ ├── serial_sphero_port.py │ │ └── sphero_port_base.py │ │ ├── service │ │ ├── __init__.py │ │ ├── api_robo_service.py │ │ ├── robo_service_base.py │ │ ├── robo_service_channel.py │ │ └── sphero_robo_service.py │ │ └── toy │ │ ├── __init__.py │ │ └── sphero_toy_base.py ├── common │ ├── __init__.py │ ├── client │ │ ├── __init__.py │ │ └── dal │ │ │ ├── __init__.py │ │ │ └── sphero_dal_base.py │ ├── commands │ │ ├── __init__.py │ │ ├── api_and_shell.py │ │ ├── connection.py │ │ ├── drive.py │ │ ├── io.py │ │ ├── power.py │ │ ├── sensor.py │ │ └── system_info.py │ ├── devices.py │ ├── enums │ │ ├── __init__.py │ │ ├── api_and_shell_enums.py │ │ ├── colors_enums.py │ │ ├── connection_enums.py │ │ ├── drive_enums.py │ │ ├── infrared_codes_enums.py │ │ ├── io_enums.py │ │ ├── number_bounds_enums.py │ │ ├── power_enums.py │ │ ├── rvr_led_groups_enum.py │ │ ├── sensor_enums.py │ │ ├── sphero_rvr_enums.py │ │ └── system_info_enums.py │ ├── exceptions.py │ ├── firmware │ │ ├── __init__.py │ │ └── cms_fw_check_base.py │ ├── helpers.py │ ├── log_level.py │ ├── parameter.py │ ├── protocol │ │ ├── __init__.py │ │ ├── api_sphero_header.py │ │ ├── api_sphero_message.py │ │ ├── api_sphero_protocol.py │ │ ├── sphero_async_url.py │ │ ├── sphero_command_url.py │ │ ├── sphero_header_base.py │ │ ├── sphero_message_base.py │ │ └── sphero_url_base.py │ ├── rvr_streaming_services.py │ ├── sensors │ │ ├── __init__.py │ │ ├── sensor_stream_attribute.py │ │ ├── sensor_stream_service.py │ │ ├── sensor_stream_slot.py │ │ └── sensor_streaming_control.py │ └── sequence_number_generator.py └── observer │ ├── __init__.py │ ├── client │ ├── __init__.py │ ├── dal │ │ ├── __init__.py │ │ ├── observer_parser.py │ │ ├── serial_observer_dal.py │ │ └── serial_observer_port.py │ ├── firmware │ │ ├── __init__.py │ │ └── rvr_fw_check_observer.py │ └── toys │ │ ├── __init__.py │ │ └── sphero_rvr_observer.py │ ├── config │ ├── __init__.py │ └── logging_config.py │ ├── controls │ ├── __init__.py │ ├── drive_control_observer.py │ ├── infrared_control_observer.py │ ├── led_control_observer.py │ └── sensor_control_observer.py │ ├── events │ ├── __init__.py │ └── event_dispatcher.py │ └── observer_base.py └── tools ├── pi-uart-check.sh └── pipenv-setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.lock 3 | /pycache/ 4 | /dist/ 5 | /*.egg-info 6 | /.idea 7 | /.python-version 8 | /docs/_build/ 9 | /.fw 10 | *.ipynb_checkpoints 11 | *.h5 12 | *.py~ 13 | *.py.un~ 14 | *.DS_Store 15 | 16 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [requires] 9 | python_version = "3" 10 | 11 | [packages] 12 | aiohttp = "*" 13 | requests = "*" 14 | websocket-client = "*" 15 | pytest-asyncio = "*" 16 | pytest = "*" 17 | twine = "*" 18 | pyserial = "*" 19 | pyserial-asyncio = "*" 20 | 21 | -------------------------------------------------------------------------------- /SpheroSDKLicense2Oct2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/SpheroSDKLicense2Oct2019.pdf -------------------------------------------------------------------------------- /docs/SpheroRVRControlSystemManual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/docs/SpheroRVRControlSystemManual.pdf -------------------------------------------------------------------------------- /first-time-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script guides a user through setting up the Sphero RVR Python SDK. 4 | 5 | # Install the SDK dependencies (only for the current user) 6 | pip3 install --user -r requirements.txt 7 | 8 | # Reload ~/.profile. In recent Raspberry Pi OS releases, this automatically includes $HOME/.local/bin in the path once it exists. 9 | source ~/.profile 10 | 11 | # Provide an opportunity to correct the UART settings if needed. 12 | ./tools/pi-uart-check.sh 13 | -------------------------------------------------------------------------------- /getting_started/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/api_and_shell/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/api_and_shell/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/api_and_shell/echo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import SpheroRvrTargets 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program demonstrates how to use the echo command, which sends data to RVR and RVR returns 22 | the same data. Echo can be used to check to see if RVR is connected. RVR does not 23 | need to be awake for this operation. 24 | """ 25 | 26 | echo_response = await rvr.echo( 27 | data=[0, 1, 2], 28 | target=SpheroRvrTargets.primary.value 29 | ) 30 | print('Echo response 1: ', echo_response) 31 | 32 | echo_response = await rvr.echo( 33 | data=[4, 5, 6], 34 | target=SpheroRvrTargets.secondary.value 35 | ) 36 | print('Echo response 2: ', echo_response) 37 | 38 | await rvr.close() 39 | 40 | 41 | if __name__ == '__main__': 42 | try: 43 | loop.run_until_complete( 44 | main() 45 | ) 46 | 47 | except KeyboardInterrupt: 48 | print('\nProgram terminated with keyboard interrupt.') 49 | 50 | loop.run_until_complete( 51 | rvr.close() 52 | ) 53 | 54 | finally: 55 | if loop.is_running(): 56 | loop.close() 57 | -------------------------------------------------------------------------------- /getting_started/asyncio/api_and_shell/generate_api_error.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import SpheroRvrTargets 9 | from sphero_sdk import ApiResponseCodesEnum 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This sample uses the generate_api_error command to intentionally generate an error response from RVR 23 | with the specified response code. Under normal circumstances certain commands request a response from RVR. 24 | If an error response is detected then it can be handled by the SDK's response logic. However, if a 25 | command does not have expected output, and therefore doesn't request a response (e.g. drive_with_heading), 26 | then RVR does not generate an error response if one occurs. Setting the request_error_responses_only flag 27 | on RVR will enable it to generate error responses even if no output is expected, and give a program the 28 | ability to catch any of the following 10 error response codes: 29 | 30 | Response Code 0x00: success 31 | Response Code 0x01: bad_did 32 | Response Code 0x02: bad_cid 33 | Response Code 0x03: not_yet_implemented 34 | Response Code 0x04: restricted 35 | Response Code 0x05: bad_data_length 36 | Response Code 0x06: failed 37 | Response Code 0x07: bad_data_value 38 | Response Code 0x08: busy 39 | Response Code 0x09: bad_tid (bad target id) 40 | Response Code 0x0A: target_unavailable 41 | 42 | Note a response code of 0x00 indicates a successful command, and is therefore is not considered an error. 43 | """ 44 | 45 | # Since the generate_api_error command doesn't expect any output, the enable_error_responses_only flag must 46 | # be set True in order for RVR to generate an error. This flag will remain true until otherwise specified, 47 | # or when the program terminates. 48 | rvr.request_error_responses_only = True 49 | 50 | await rvr.generate_api_error( 51 | error=ApiResponseCodesEnum.target_unavailable, # Specify code 0x01 - 0x0A to receive that specific error response from RVR. 52 | target=SpheroRvrTargets.secondary.value, 53 | timeout=3 54 | ) 55 | 56 | await rvr.close() 57 | 58 | 59 | if __name__ == '__main__': 60 | try: 61 | loop.run_until_complete( 62 | main() 63 | ) 64 | 65 | except KeyboardInterrupt: 66 | print('\nProgram terminated with keyboard interrupt.') 67 | 68 | loop.run_until_complete( 69 | rvr.close() 70 | ) 71 | 72 | finally: 73 | if loop.is_running(): 74 | loop.close() 75 | -------------------------------------------------------------------------------- /getting_started/asyncio/color_sensor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/color_sensor/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/color_sensor/color_detection.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RvrStreamingServices 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def color_detected_handler(color_detected_data): 21 | print('Color detection data response: ', color_detected_data) 22 | 23 | 24 | async def main(): 25 | """ This program demonstrates how to use the color sensor on RVR (located on the down side of RVR, facing the floor) 26 | to report colors detected. To exit program, press 27 | """ 28 | 29 | await rvr.wake() 30 | 31 | # Give RVR time to wake up 32 | await asyncio.sleep(2) 33 | 34 | await rvr.enable_color_detection(is_enabled=True) 35 | await rvr.sensor_control.add_sensor_data_handler( 36 | service=RvrStreamingServices.color_detection, 37 | handler=color_detected_handler 38 | ) 39 | await rvr.sensor_control.start(interval=250) 40 | 41 | while True: 42 | await asyncio.sleep(1) 43 | 44 | 45 | if __name__ == '__main__': 46 | try: 47 | asyncio.ensure_future( 48 | main() 49 | ) 50 | loop.run_forever() 51 | 52 | except KeyboardInterrupt: 53 | print('\nProgram terminated with keyboard interrupt.') 54 | 55 | loop.run_until_complete( 56 | asyncio.gather( 57 | rvr.enable_color_detection(is_enabled=False), 58 | rvr.close() 59 | ) 60 | ) 61 | 62 | finally: 63 | if loop.is_running(): 64 | loop.close() 65 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/driving/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_rc_normalized.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | # Handler for the active controller stopped notification. 19 | # After sending a stop command, your program can wait for 20 | # this async to confirm that the robot has come to a stop 21 | async def stopped_handler(): 22 | print('RVR has stopped') 23 | 24 | 25 | async def main(): 26 | """ This program has RVR drive around using the normalized RC drive command. 27 | """ 28 | 29 | await rvr.wake() 30 | 31 | # Give RVR time to wake up 32 | await asyncio.sleep(2) 33 | 34 | # Register the handler for the stopped notification 35 | await rvr.on_robot_has_stopped_notify(handler=stopped_handler) 36 | 37 | await rvr.reset_yaw() 38 | 39 | print("sending drive command") 40 | 41 | await rvr.drive_rc_normalized( 42 | linear_velocity=20, # Valid linear velocity values are -127..127 43 | yaw_angular_velocity=0, # Valid angular velocity values are -127..127 44 | flags=0 45 | ) 46 | 47 | # Delay to allow RVR to drive 48 | await asyncio.sleep(2) 49 | 50 | # Continue driving forward, while turning left 51 | await rvr.drive_rc_normalized( 52 | linear_velocity=15, # Valid linear velocity values are -127..127 53 | yaw_angular_velocity=20, # Valid angular velocity values are -127..127 54 | flags=0 55 | ) 56 | 57 | # Delay to allow RVR to turn 58 | await asyncio.sleep(1) 59 | 60 | # Drive in new forward direction 61 | await rvr.drive_rc_normalized( 62 | linear_velocity=20, # Valid linear velocity values are -127..127 63 | yaw_angular_velocity=0, # Valid angular velocity values are -127..127 64 | flags=0 65 | ) 66 | 67 | # Delay to allow RVR to drive 68 | await asyncio.sleep(2) 69 | 70 | print("sending stop command") 71 | 72 | # Stop driving, with deceleration rate of 2 m/s^2 73 | await rvr.drive_stop(2.0) 74 | 75 | # Delay to allow RVR to stop 76 | await asyncio.sleep(1) 77 | 78 | await rvr.close() 79 | 80 | 81 | if __name__ == '__main__': 82 | try: 83 | loop.run_until_complete( 84 | main() 85 | ) 86 | 87 | except KeyboardInterrupt: 88 | print('\nProgram terminated with keyboard interrupt.') 89 | 90 | loop.run_until_complete( 91 | rvr.close() 92 | ) 93 | 94 | finally: 95 | if loop.is_running(): 96 | loop.close() 97 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_rc_si_units.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | loop = asyncio.get_event_loop() 10 | 11 | rvr = SpheroRvrAsync( 12 | dal=SerialAsyncDal( 13 | loop 14 | ) 15 | ) 16 | 17 | # Handler for the active controller stopped notification. 18 | # After sending a stop command, your program can wait for 19 | # this async to confirm that the robot has come to a stop 20 | async def stopped_handler(): 21 | print('RVR has stopped') 22 | 23 | 24 | async def main(): 25 | """ This program has RVR drive around using the normalized RC drive command. 26 | """ 27 | 28 | await rvr.wake() 29 | 30 | # Give RVR time to wake up 31 | await asyncio.sleep(2) 32 | 33 | # Register the handler for the stopped notification 34 | await rvr.on_robot_has_stopped_notify(handler=stopped_handler) 35 | 36 | await rvr.reset_yaw() 37 | 38 | print("sending drive command") 39 | 40 | await rvr.drive_rc_si_units( 41 | linear_velocity=.3, # Valid velocity values are in the range of [-2..2] m/s 42 | yaw_angular_velocity=0, # RVR will spin at up to 624 degrees/s. Values outside of [-624..624] will saturate internally. 43 | flags=0 44 | ) 45 | 46 | # Delay to allow RVR to drive 47 | await asyncio.sleep(1) 48 | 49 | # The control system timeout can be modified to keep a command running longer 50 | # than the default 2 seconds. This remains in effect until changed back, 51 | # or until a reboot occurs. Note that this is in milliseconds. 52 | await rvr.set_custom_control_system_timeout(command_timeout=20000) 53 | 54 | # Continue driving forward, while turning left 55 | await rvr.drive_rc_si_units( 56 | linear_velocity=.1, 57 | yaw_angular_velocity=20, 58 | flags=0 59 | ) 60 | 61 | # Delay to allow RVR to drive 62 | await asyncio.sleep(18) # Oh look, there'll be 2 seconds of driving to go! 63 | 64 | print("sending stop command") 65 | 66 | # Stop early, with a custom deceleration rate of 2 m/s^2. 67 | await rvr.drive_stop(2.0) 68 | 69 | # Restore the default control system timeout to keep things more normal after this. 70 | await rvr.restore_default_control_system_timeout() 71 | 72 | # Delay to allow RVR to stop 73 | await asyncio.sleep(1) 74 | 75 | await rvr.close() 76 | 77 | 78 | if __name__ == '__main__': 79 | try: 80 | loop.run_until_complete( 81 | main() 82 | ) 83 | 84 | except KeyboardInterrupt: 85 | print('\nProgram terminated with keyboard interrupt.') 86 | 87 | loop.run_until_complete( 88 | rvr.close() 89 | ) 90 | 91 | finally: 92 | if loop.is_running(): 93 | loop.close() 94 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_tank_normalized.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program has RVR drive around in different directions using the function drive_tank_normalized. 21 | This function commands a normalized linear velocity target for each tread. Velocity targets 22 | are normalized in the range [-127..127] 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.reset_yaw() 31 | 32 | # drive forward, 50% speed 33 | await rvr.drive_tank_normalized( 34 | left_velocity=64, # Valid velocity values are [-127..127] 35 | right_velocity=64 # Valid velocity values are [-127..127] 36 | ) 37 | 38 | # Delay to allow RVR to drive 39 | await asyncio.sleep(1) 40 | 41 | # drive reverse, 50% speed 42 | await rvr.drive_tank_normalized( 43 | left_velocity=-64, # Valid velocity values are [-127..127] 44 | right_velocity=-64 # Valid velocity values are [-127..127] 45 | ) 46 | 47 | # Delay to allow RVR to drive 48 | await asyncio.sleep(1) 49 | 50 | # Spin in place slowly 51 | await rvr.drive_tank_normalized( 52 | left_velocity=5, # Valid velocity values are [-127..127] 53 | right_velocity=-5 # Valid velocity values are [-127..127] 54 | ) 55 | 56 | # Delay to allow RVR to drive 57 | await asyncio.sleep(2) 58 | 59 | # Spin in place quickly 60 | await rvr.drive_tank_normalized( 61 | left_velocity=-127, # Valid velocity values are [-127..127] 62 | right_velocity=127 # Valid velocity values are [-127..127] 63 | ) 64 | 65 | # Delay to allow RVR to drive 66 | await asyncio.sleep(2) 67 | 68 | await rvr.drive_tank_normalized( 69 | left_velocity=0, # Valid velocity values are [-127..127] 70 | right_velocity=0 # Valid velocity values are [-127..127] 71 | ) 72 | 73 | # Delay to allow RVR to drive 74 | await asyncio.sleep(1) 75 | 76 | await rvr.close() 77 | 78 | 79 | if __name__ == '__main__': 80 | try: 81 | loop.run_until_complete( 82 | main() 83 | ) 84 | 85 | except KeyboardInterrupt: 86 | print('\nProgram terminated with keyboard interrupt.') 87 | 88 | loop.run_until_complete( 89 | rvr.close() 90 | ) 91 | 92 | finally: 93 | if loop.is_running(): 94 | loop.close() 95 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_tank_si.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program has RVR drive around in different directions using the function drive_tank_si. 21 | This function commands a floating point linear velocity target for each tread in meters per second. 22 | Achievable velocity targets are in the range of [-1.555..1.555] 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.reset_yaw() 31 | 32 | # drive forward, 50% speed 33 | await rvr.drive_tank_si_units( 34 | left_velocity=0.75, # Valid velocity values are [-1.555..1.555] 35 | right_velocity=0.75 36 | ) 37 | 38 | # Delay to allow RVR to drive 39 | await asyncio.sleep(1) 40 | 41 | # drive reverse, ~50% speed 42 | await rvr.drive_tank_si_units( 43 | left_velocity=-0.75, 44 | right_velocity=-0.75 45 | ) 46 | 47 | # Delay to allow RVR to drive 48 | await asyncio.sleep(1) 49 | 50 | # Spin in place slowly 51 | await rvr.drive_tank_si_units( 52 | left_velocity=0.1, 53 | right_velocity=-0.1 54 | ) 55 | 56 | # Delay to allow RVR to drive 57 | await asyncio.sleep(2) 58 | 59 | # Spin in place quickly 60 | await rvr.drive_tank_si_units( 61 | left_velocity=-1.5, 62 | right_velocity=1.5 63 | ) 64 | 65 | # Delay to allow RVR to drive 66 | await asyncio.sleep(2) 67 | 68 | await rvr.drive_tank_si_units( 69 | left_velocity=0, 70 | right_velocity=0 71 | ) 72 | 73 | # Delay to allow RVR to drive 74 | await asyncio.sleep(1) 75 | 76 | await rvr.close() 77 | 78 | 79 | if __name__ == '__main__': 80 | try: 81 | loop.run_until_complete( 82 | main() 83 | ) 84 | 85 | except KeyboardInterrupt: 86 | print('\nProgram terminated with keyboard interrupt.') 87 | 88 | loop.run_until_complete( 89 | rvr.close() 90 | ) 91 | 92 | finally: 93 | if loop.is_running(): 94 | loop.close() 95 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_with_heading.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import DriveFlagsBitmask 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program has RVR drive around in different directions using the function drive_with_heading. 22 | """ 23 | 24 | await rvr.wake() 25 | 26 | # Give RVR time to wake up 27 | await asyncio.sleep(2) 28 | 29 | await rvr.reset_yaw() 30 | 31 | await rvr.drive_with_heading( 32 | speed=128, # Valid speed values are 0-255 33 | heading=0, # Valid heading values are 0-359 34 | flags=DriveFlagsBitmask.none.value 35 | ) 36 | 37 | # Delay to allow RVR to drive 38 | await asyncio.sleep(1) 39 | 40 | await rvr.drive_with_heading( 41 | speed=128, # Valid speed values are 0-255 42 | heading=0, # Valid heading values are 0-359 43 | flags=DriveFlagsBitmask.drive_reverse.value 44 | ) 45 | 46 | # Delay to allow RVR to drive 47 | await asyncio.sleep(1) 48 | 49 | await rvr.drive_with_heading( 50 | speed=128, # Valid speed values are 0-255 51 | heading=90, # Valid heading values are 0-359 52 | flags=DriveFlagsBitmask.none.value 53 | ) 54 | 55 | # Delay to allow RVR to drive 56 | await asyncio.sleep(1) 57 | 58 | await rvr.drive_with_heading( 59 | speed=128, # Valid speed values are 0-255 60 | heading=270, # Valid heading values are 0-359 61 | flags=DriveFlagsBitmask.none.value 62 | ) 63 | 64 | # Delay to allow RVR to drive 65 | await asyncio.sleep(1) 66 | 67 | await rvr.drive_with_heading( 68 | speed=0, # Valid heading values are 0-359 69 | heading=0, # Valid heading values are 0-359 70 | flags=DriveFlagsBitmask.none.value 71 | ) 72 | 73 | # Delay to allow RVR to drive 74 | await asyncio.sleep(1) 75 | 76 | await rvr.close() 77 | 78 | 79 | if __name__ == '__main__': 80 | try: 81 | loop.run_until_complete( 82 | main() 83 | ) 84 | 85 | except KeyboardInterrupt: 86 | print('\nProgram terminated with keyboard interrupt.') 87 | 88 | loop.run_until_complete( 89 | rvr.close() 90 | ) 91 | 92 | finally: 93 | if loop.is_running(): 94 | loop.close() 95 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_with_heading_reverse_mode.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import DriveFlagsBitmask 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program has RVR drive around in different directions using the function drive_with_heading. 22 | """ 23 | 24 | await rvr.wake() 25 | 26 | # Give RVR time to wake up 27 | await asyncio.sleep(2) 28 | 29 | await rvr.reset_yaw() 30 | 31 | await rvr.drive_with_heading( 32 | speed=128, # Valid speed values are 0-255 33 | heading=90, # Valid heading values are 0-359 34 | flags=DriveFlagsBitmask.drive_reverse.value 35 | ) 36 | 37 | # Delay to allow RVR to drive 38 | await asyncio.sleep(1) 39 | 40 | await rvr.drive_with_heading( 41 | speed=0, # Valid heading values are 0-359 42 | heading=0, # Valid heading values are 0-359 43 | flags=DriveFlagsBitmask.none.value 44 | ) 45 | 46 | # Delay to allow RVR to drive 47 | await asyncio.sleep(1) 48 | 49 | await rvr.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | try: 54 | loop.run_until_complete( 55 | main() 56 | ) 57 | 58 | except KeyboardInterrupt: 59 | print('\nProgram terminated with keyboard interrupt.') 60 | 61 | loop.run_until_complete( 62 | rvr.close() 63 | ) 64 | 65 | finally: 66 | if loop.is_running(): 67 | loop.close() 68 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program has RVR drive with how to drive RVR using the drive control helper. 21 | """ 22 | 23 | await rvr.wake() 24 | 25 | # Give RVR time to wake up 26 | await asyncio.sleep(2) 27 | 28 | await rvr.drive_control.reset_heading() 29 | 30 | await rvr.drive_control.drive_forward_seconds( 31 | speed=64, 32 | heading=0, # Valid heading values are 0-359 33 | time_to_drive=1 34 | ) 35 | 36 | # Delay to allow RVR to drive 37 | await asyncio.sleep(1) 38 | 39 | await rvr.drive_control.drive_backward_seconds( 40 | speed=64, 41 | heading=0, # Valid heading values are 0-359 42 | time_to_drive=1 43 | ) 44 | 45 | # Delay to allow RVR to drive 46 | await asyncio.sleep(1) 47 | 48 | await rvr.drive_control.turn_left_degrees( 49 | heading=0, # Valid heading values are 0-359 50 | amount=90 51 | ) 52 | 53 | # Delay to allow RVR to drive 54 | await asyncio.sleep(1) 55 | 56 | await rvr.close() 57 | 58 | 59 | if __name__ == '__main__': 60 | try: 61 | loop.run_until_complete( 62 | main() 63 | ) 64 | 65 | except KeyboardInterrupt: 66 | print('\nProgram terminated with keyboard interrupt.') 67 | 68 | loop.run_until_complete( 69 | rvr.close() 70 | ) 71 | 72 | finally: 73 | if loop.is_running(): 74 | loop.close() 75 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/drive_with_helper_roll.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program has RVR drive with how to drive RVR using the drive control helper. 21 | """ 22 | 23 | await rvr.wake() 24 | 25 | # Give RVR time to wake up 26 | await asyncio.sleep(2) 27 | 28 | await rvr.drive_control.reset_heading() 29 | 30 | await rvr.drive_control.roll_start( 31 | speed=64, 32 | heading=90 33 | ) 34 | 35 | # Delay to allow RVR to drive 36 | await asyncio.sleep(1) 37 | 38 | await rvr.drive_control.roll_stop(heading=270) 39 | 40 | # Delay to allow RVR to drive 41 | await asyncio.sleep(1) 42 | 43 | await rvr.close() 44 | 45 | 46 | if __name__ == '__main__': 47 | try: 48 | loop.run_until_complete( 49 | main() 50 | ) 51 | 52 | except KeyboardInterrupt: 53 | print('\nProgram terminated with keyboard interrupt.') 54 | 55 | loop.run_until_complete( 56 | rvr.close() 57 | ) 58 | 59 | finally: 60 | if loop.is_running(): 61 | loop.close() 62 | -------------------------------------------------------------------------------- /getting_started/asyncio/driving/get_encoder_counts.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program demonstrates how to get encoder counts on RVR. 21 | """ 22 | 23 | await rvr.wake() 24 | 25 | # Give RVR time to wake up 26 | await asyncio.sleep(2) 27 | 28 | encoder_counts = await rvr.get_encoder_counts() 29 | print('Encoder counts: ', encoder_counts) 30 | 31 | await rvr.close() 32 | 33 | 34 | if __name__ == '__main__': 35 | try: 36 | loop.run_until_complete( 37 | main() 38 | ) 39 | 40 | except KeyboardInterrupt: 41 | print('\nProgram terminated with keyboard interrupt.') 42 | 43 | loop.run_until_complete( 44 | rvr.close() 45 | ) 46 | 47 | finally: 48 | if loop.is_running(): 49 | loop.close() 50 | -------------------------------------------------------------------------------- /getting_started/asyncio/infrared/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/infrared/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/infrared/broadcast_ir.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import InfraredCodes 9 | from sphero_sdk import RawMotorModesEnum 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.start_robot_to_robot_infrared_broadcasting( 31 | far_code=InfraredCodes.one.value, 32 | near_code=InfraredCodes.zero.value 33 | ) 34 | 35 | for i in range(2): 36 | await rvr.raw_motors( 37 | left_mode=RawMotorModesEnum.forward.value, 38 | left_duty_cycle=64, # Valid duty cycle range is 0-255 39 | right_mode=RawMotorModesEnum.forward.value, 40 | right_duty_cycle=64 # Valid duty cycle range is 0-255 41 | ) 42 | 43 | # Delay to allow RVR to drive 44 | await asyncio.sleep(2) 45 | 46 | await rvr.stop_robot_to_robot_infrared_broadcasting() 47 | 48 | await rvr.close() 49 | 50 | 51 | if __name__ == '__main__': 52 | try: 53 | loop.run_until_complete( 54 | main() 55 | ) 56 | 57 | except KeyboardInterrupt: 58 | print('\nProgram terminated with keyboard interrupt.') 59 | 60 | loop.run_until_complete( 61 | asyncio.gather( 62 | rvr.stop_robot_to_robot_infrared_broadcasting(), 63 | rvr.close() 64 | ) 65 | ) 66 | 67 | finally: 68 | if loop.is_running(): 69 | loop.close() 70 | -------------------------------------------------------------------------------- /getting_started/asyncio/infrared/broadcast_ir_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import InfraredCodes 9 | from sphero_sdk import RawMotorModesEnum 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.infrared_control.start_infrared_broadcasting( 31 | far_code=InfraredCodes.one, 32 | near_code=InfraredCodes.zero 33 | ) 34 | 35 | await rvr.raw_motors( 36 | left_mode=RawMotorModesEnum.forward.value, 37 | left_duty_cycle=64, # Valid duty cycle range is 0-255 38 | right_mode=RawMotorModesEnum.forward.value, 39 | right_duty_cycle=64 # Valid duty cycle range is 0-255 40 | ) 41 | 42 | # Delay to allow RVR to drive 43 | await asyncio.sleep(4) 44 | 45 | await rvr.infrared_control.stop_infrared_broadcasting() 46 | 47 | await rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | try: 52 | loop.run_until_complete( 53 | main() 54 | ) 55 | 56 | except KeyboardInterrupt: 57 | print('\nProgram terminated with keyboard interrupt.') 58 | 59 | loop.run_until_complete( 60 | asyncio.gather( 61 | rvr.stop_robot_to_robot_infrared_broadcasting(), 62 | rvr.close() 63 | ) 64 | ) 65 | 66 | finally: 67 | if loop.is_running(): 68 | loop.close() 69 | -------------------------------------------------------------------------------- /getting_started/asyncio/infrared/listen_for_and_send_ir.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def infrared_message_received_handler(infrared_message): 20 | print('Infrared message response: ', infrared_message) 21 | 22 | 23 | async def main(): 24 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 25 | """ 26 | 27 | await rvr.wake() 28 | 29 | # Give RVR time to wake up 30 | await asyncio.sleep(2) 31 | 32 | await rvr.on_robot_to_robot_infrared_message_received_notify(handler=infrared_message_received_handler) 33 | 34 | await rvr.enable_robot_infrared_message_notify(is_enabled=True) 35 | 36 | infrared_code = 3 37 | strength = 64 38 | 39 | while True: 40 | await rvr.send_infrared_message( 41 | infrared_code=infrared_code, 42 | front_strength=strength, 43 | left_strength=strength, 44 | right_strength=strength, 45 | rear_strength=strength 46 | ) 47 | 48 | print('Infrared message sent with code: {0}'.format(infrared_code)) 49 | 50 | await asyncio.sleep(2) 51 | 52 | 53 | if __name__ == '__main__': 54 | try: 55 | asyncio.ensure_future( 56 | main() 57 | ) 58 | loop.run_forever() 59 | 60 | except KeyboardInterrupt: 61 | print('\nProgram terminated with keyboard interrupt.') 62 | 63 | loop.run_until_complete( 64 | asyncio.gather( 65 | rvr.stop_robot_to_robot_infrared_broadcasting(), 66 | rvr.close() 67 | ) 68 | ) 69 | 70 | finally: 71 | if loop.is_running(): 72 | loop.close() 73 | 74 | -------------------------------------------------------------------------------- /getting_started/asyncio/infrared/listen_for_and_send_ir_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import InfraredCodes 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def infrared_message_received_handler(infrared_message): 21 | print('Infrared message response: ', infrared_message) 22 | 23 | 24 | async def main(): 25 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 26 | """ 27 | 28 | await rvr.wake() 29 | 30 | # Give RVR time to wake up 31 | await asyncio.sleep(2) 32 | 33 | await rvr.infrared_control.listen_for_infrared_message(handler=infrared_message_received_handler) 34 | 35 | codes = [ 36 | InfraredCodes.zero, 37 | InfraredCodes.one, 38 | InfraredCodes.two, 39 | InfraredCodes.three 40 | ] 41 | 42 | while True: 43 | await rvr.infrared_control.send_infrared_messages( 44 | messages=codes, 45 | strength=64 46 | ) 47 | 48 | print('Infrared message sent with codes: {0}'.format([code.value for code in codes])) 49 | 50 | await asyncio.sleep(2) 51 | 52 | 53 | if __name__ == '__main__': 54 | try: 55 | loop.run_until_complete( 56 | main() 57 | ) 58 | 59 | except KeyboardInterrupt: 60 | print('\nProgram terminated with keyboard interrupt.') 61 | 62 | loop.run_until_complete( 63 | asyncio.gather( 64 | rvr.stop_robot_to_robot_infrared_broadcasting(), 65 | rvr.close() 66 | ) 67 | ) 68 | 69 | finally: 70 | if loop.is_running(): 71 | loop.close() -------------------------------------------------------------------------------- /getting_started/asyncio/leds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/leds/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_all_leds.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | from sphero_sdk import SerialAsyncDal 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program demonstrates how to set the all the LEDs. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.set_all_leds( 31 | led_group=RvrLedGroups.all_lights.value, 32 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 33 | ) 34 | 35 | # Delay to show LEDs change 36 | await asyncio.sleep(1) 37 | 38 | await rvr.set_all_leds( 39 | led_group=RvrLedGroups.all_lights.value, 40 | led_brightness_values=[color for x in range(10) for color in [0, 255, 0]] 41 | ) 42 | 43 | # Delay to show LEDs change 44 | await asyncio.sleep(1) 45 | 46 | await rvr.close() 47 | 48 | 49 | if __name__ == '__main__': 50 | try: 51 | loop.run_until_complete( 52 | main() 53 | ) 54 | 55 | except KeyboardInterrupt: 56 | print('\nProgram terminated with keyboard interrupt.') 57 | 58 | loop.run_until_complete( 59 | rvr.close() 60 | ) 61 | 62 | finally: 63 | if loop.is_running(): 64 | loop.close() 65 | -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_all_leds_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import SerialAsyncDal 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program demonstrates how to set the all the LEDs of RVR using the LED control helper. 22 | """ 23 | 24 | await rvr.wake() 25 | 26 | # Give RVR time to wake up 27 | await asyncio.sleep(2) 28 | 29 | await rvr.led_control.turn_leds_off() 30 | 31 | # Delay to show LEDs change 32 | await asyncio.sleep(1) 33 | 34 | await rvr.led_control.set_all_leds_color(color=Colors.yellow) 35 | 36 | # Delay to show LEDs change 37 | await asyncio.sleep(1) 38 | 39 | await rvr.led_control.turn_leds_off() 40 | 41 | # Delay to show LEDs change 42 | await asyncio.sleep(1) 43 | 44 | await rvr.led_control.set_all_leds_rgb(red=255, green=144, blue=0) 45 | 46 | # Delay to show LEDs change 47 | await asyncio.sleep(1) 48 | 49 | await rvr.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | try: 54 | loop.run_until_complete( 55 | main() 56 | ) 57 | 58 | except KeyboardInterrupt: 59 | print('\nProgram terminated with keyboard interrupt.') 60 | 61 | loop.run_until_complete( 62 | rvr.close() 63 | ) 64 | 65 | finally: 66 | if loop.is_running(): 67 | loop.close() 68 | -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_multiple_leds.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | from sphero_sdk import SerialAsyncDal 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program demonstrates how to set multiple LEDs. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.set_all_leds( 31 | led_group=RvrLedGroups.all_lights.value, 32 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 33 | ) 34 | 35 | # Delay to show LEDs change 36 | await asyncio.sleep(1) 37 | 38 | await rvr.set_all_leds( 39 | led_group=RvrLedGroups.headlight_left.value | RvrLedGroups.headlight_right.value, 40 | led_brightness_values=[ 41 | 0, 0, 255, 42 | 255, 0, 0 43 | ] 44 | ) 45 | 46 | # Delay to show LEDs change 47 | await asyncio.sleep(1) 48 | 49 | await rvr.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | try: 54 | loop.run_until_complete( 55 | main() 56 | ) 57 | 58 | except KeyboardInterrupt: 59 | print('\nProgram terminated with keyboard interrupt.') 60 | 61 | loop.run_until_complete( 62 | rvr.close() 63 | ) 64 | 65 | finally: 66 | if loop.is_running(): 67 | loop.close() 68 | -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_multiple_leds_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | from sphero_sdk import SerialAsyncDal 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program demonstrates how to set multiple LEDs on RVR using the LED control helper. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.led_control.turn_leds_off() 31 | 32 | # Delay to show LEDs change 33 | await asyncio.sleep(1) 34 | 35 | await rvr.led_control.set_multiple_leds_with_enums( 36 | leds=[ 37 | RvrLedGroups.headlight_left, 38 | RvrLedGroups.headlight_right 39 | ], 40 | colors=[ 41 | Colors.green, 42 | Colors.blue 43 | ] 44 | ) 45 | 46 | # Delay to show LEDs change 47 | await asyncio.sleep(1) 48 | 49 | await rvr.led_control.set_multiple_leds_with_rgb( 50 | leds=[ 51 | RvrLedGroups.headlight_left, 52 | RvrLedGroups.headlight_right 53 | ], 54 | colors=[ 55 | 255, 0, 0, 56 | 0, 255, 0 57 | ] 58 | ) 59 | 60 | # Delay to show LEDs change 61 | await asyncio.sleep(1) 62 | 63 | await rvr.close() 64 | 65 | 66 | if __name__ == '__main__': 67 | try: 68 | loop.run_until_complete( 69 | main() 70 | ) 71 | 72 | except KeyboardInterrupt: 73 | print('\nProgram terminated with keyboard interrupt.') 74 | 75 | loop.run_until_complete( 76 | rvr.close() 77 | ) 78 | 79 | finally: 80 | if loop.is_running(): 81 | loop.close() 82 | -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_single_led.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | from sphero_sdk import SerialAsyncDal 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program demonstrates how to set a single LED. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.set_all_leds( 31 | led_group=RvrLedGroups.all_lights.value, 32 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 33 | ) 34 | 35 | # Delay to show LEDs change 36 | await asyncio.sleep(1) 37 | 38 | await rvr.set_all_leds( 39 | led_group=RvrLedGroups.headlight_right.value, # 0xe00 40 | led_brightness_values=[255, 0, 0] 41 | ) 42 | 43 | # Delay to show LEDs change 44 | await asyncio.sleep(1) 45 | 46 | await rvr.set_all_leds( 47 | led_group=RvrLedGroups.headlight_left.value, # 0x1c0 48 | led_brightness_values=[0, 255, 0] 49 | ) 50 | 51 | # Delay to show LEDs change 52 | await asyncio.sleep(1) 53 | 54 | await rvr.close() 55 | 56 | 57 | if __name__ == '__main__': 58 | try: 59 | loop.run_until_complete( 60 | main() 61 | ) 62 | 63 | except KeyboardInterrupt: 64 | print('\nProgram terminated with keyboard interrupt.') 65 | 66 | loop.run_until_complete( 67 | rvr.close() 68 | ) 69 | 70 | finally: 71 | if loop.is_running(): 72 | loop.close() 73 | -------------------------------------------------------------------------------- /getting_started/asyncio/leds/set_single_led_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | from sphero_sdk import SerialAsyncDal 10 | 11 | 12 | loop = asyncio.get_event_loop() 13 | 14 | rvr = SpheroRvrAsync( 15 | dal=SerialAsyncDal( 16 | loop 17 | ) 18 | ) 19 | 20 | 21 | async def main(): 22 | """ This program demonstrates how to set a single LED on RVR using the LED control helper. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(2) 29 | 30 | await rvr.led_control.turn_leds_off() 31 | 32 | # Delay to show LEDs change 33 | await asyncio.sleep(1) 34 | 35 | await rvr.led_control.set_led_rgb( 36 | led=RvrLedGroups.headlight_right, 37 | red=255, 38 | green=0, 39 | blue=0 40 | ) 41 | 42 | # Delay to show LEDs change 43 | await asyncio.sleep(1) 44 | 45 | await rvr.led_control.set_led_color( 46 | led=RvrLedGroups.headlight_left, 47 | color=Colors.green 48 | ) 49 | 50 | # Delay to show LEDs change 51 | await asyncio.sleep(1) 52 | 53 | await rvr.close() 54 | 55 | 56 | if __name__ == '__main__': 57 | try: 58 | loop.run_until_complete( 59 | main() 60 | ) 61 | 62 | except KeyboardInterrupt: 63 | print('\nProgram terminated with keyboard interrupt.') 64 | 65 | loop.run_until_complete( 66 | rvr.close() 67 | ) 68 | 69 | finally: 70 | if loop.is_running(): 71 | loop.close() 72 | -------------------------------------------------------------------------------- /getting_started/asyncio/magnetometer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/magnetometer/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/magnetometer/get_magnetometer_reading.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def main(): 20 | """ This program demonstrates how to get a reading from the magnetometer on RVR. 21 | """ 22 | 23 | await rvr.wake() 24 | 25 | # Give RVR time to wake up 26 | await asyncio.sleep(2) 27 | 28 | magnetometer_reading = await rvr.get_magnetometer_reading() 29 | print('Magnetometer reading: ', magnetometer_reading) 30 | 31 | await rvr.close() 32 | 33 | 34 | if __name__ == '__main__': 35 | try: 36 | loop.run_until_complete( 37 | main() 38 | ) 39 | 40 | except KeyboardInterrupt: 41 | print('\nProgram terminated with keyboard interrupt.') 42 | 43 | loop.run_until_complete( 44 | rvr.close() 45 | ) 46 | 47 | finally: 48 | if loop.is_running(): 49 | loop.close() 50 | -------------------------------------------------------------------------------- /getting_started/asyncio/motors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/motors/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/motors/get_motor_fault_state.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ In the rare event that a motor fault occurs, this program demonstrates how to retrieve the motor fault state 22 | on RVR. In order to detect a motor fault, there must be an attempt to use them. 23 | """ 24 | 25 | await rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | await asyncio.sleep(1) 29 | 30 | await rvr.raw_motors( 31 | left_mode=RawMotorModesEnum.forward.value, 32 | left_duty_cycle=128, # Valid duty cycle range is 0-255 33 | right_mode=RawMotorModesEnum.forward.value, 34 | right_duty_cycle=128 # Valid duty cycle range is 0-255 35 | ) 36 | 37 | # Delay to allow RVR to drive 38 | await asyncio.sleep(2) 39 | 40 | response = await rvr.get_motor_fault_state() 41 | print('Motor fault state response:', response) 42 | 43 | await rvr.close() 44 | 45 | 46 | if __name__ == '__main__': 47 | try: 48 | loop.run_until_complete( 49 | main() 50 | ) 51 | 52 | except KeyboardInterrupt: 53 | print('\nProgram terminated with keyboard interrupt.') 54 | 55 | loop.run_until_complete( 56 | rvr.close() 57 | ) 58 | 59 | finally: 60 | if loop.is_running(): 61 | loop.close() 62 | -------------------------------------------------------------------------------- /getting_started/asyncio/motors/get_thermal_protection_status.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program demonstrates how to get motor thermal protection status, in the event RVR's motors have already 22 | been stopped to prevent overheating. This can be used to check if the motors are no longer in a thermal 23 | protection state. RVR does not need to be awake in order to run this operation. 24 | """ 25 | 26 | response = await rvr.get_motor_thermal_protection_status() 27 | print('Thermal protection status response', response) 28 | 29 | # Delay to allow the callback to be invoked 30 | await asyncio.sleep(2) 31 | 32 | if __name__ == '__main__': 33 | try: 34 | loop.run_until_complete( 35 | main() 36 | ) 37 | 38 | except KeyboardInterrupt: 39 | print('\nProgram terminated with keyboard interrupt.') 40 | 41 | loop.run_until_complete( 42 | rvr.close() 43 | ) 44 | 45 | finally: 46 | if loop.is_running(): 47 | loop.close() 48 | -------------------------------------------------------------------------------- /getting_started/asyncio/motors/motor_fault_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def motor_fault_handler(response): 21 | print('Motor fault response:', response) 22 | 23 | 24 | async def main(): 25 | """ In the rare event that a motor fault occurs while operating RVR, this program demonstrates how to register 26 | a handler for a motor fault notification. In order to receive a motor fault notification, RVR's motors 27 | must be in use. 28 | """ 29 | 30 | await rvr.wake() 31 | 32 | await rvr.enable_motor_fault_notify(is_enabled=True) 33 | 34 | await rvr.on_motor_fault_notify(handler=motor_fault_handler) 35 | 36 | # Give RVR time to wake up 37 | await asyncio.sleep(1) 38 | 39 | await rvr.raw_motors( 40 | left_mode=RawMotorModesEnum.forward.value, 41 | left_duty_cycle=128, # Valid duty cycle range is 0-255 42 | right_mode=RawMotorModesEnum.forward.value, 43 | right_duty_cycle=128 # Valid duty cycle range is 0-255 44 | ) 45 | 46 | # Delay to allow RVR to drive 47 | await asyncio.sleep(2) 48 | 49 | await rvr.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | try: 54 | loop.run_until_complete( 55 | main() 56 | ) 57 | 58 | except KeyboardInterrupt: 59 | print('\nProgram terminated with keyboard interrupt.') 60 | 61 | loop.run_until_complete( 62 | rvr.close() 63 | ) 64 | 65 | finally: 66 | if loop.is_running(): 67 | loop.close() 68 | -------------------------------------------------------------------------------- /getting_started/asyncio/motors/motor_stall_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def motor_stall_handler(response): 21 | print('Motor stall response:', response) 22 | 23 | 24 | async def main(): 25 | """ This program demonstrates how to receive motor stall notifications, in the event that RVR's treads become 26 | obstructed, and is unable to move. In order to receive the notification, RVR's motors must be in use. 27 | """ 28 | 29 | await rvr.wake() 30 | 31 | await rvr.enable_motor_stall_notify(is_enabled=True) 32 | 33 | await rvr.on_motor_stall_notify(handler=motor_stall_handler) 34 | 35 | # Give RVR time to wake up 36 | await asyncio.sleep(1) 37 | 38 | print('Press CTRL+C to stop this program anytime.') 39 | 40 | while True: 41 | await rvr.raw_motors( 42 | left_mode=RawMotorModesEnum.forward.value, 43 | left_duty_cycle=128, # Valid duty cycle values are 0-255 44 | right_mode=RawMotorModesEnum.forward.value, 45 | right_duty_cycle=128 # Valid duty cycle values are 0-255 46 | ) 47 | 48 | # Delay to allow RVR to drive 49 | await asyncio.sleep(1) 50 | 51 | 52 | if __name__ == '__main__': 53 | try: 54 | loop.run_until_complete( 55 | main() 56 | ) 57 | 58 | except KeyboardInterrupt: 59 | print('\nProgram terminated with keyboard interrupt.') 60 | 61 | loop.run_until_complete( 62 | rvr.close() 63 | ) 64 | 65 | finally: 66 | if loop.is_running(): 67 | loop.close() 68 | -------------------------------------------------------------------------------- /getting_started/asyncio/motors/thermal_protection_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import TemperatureSensorsEnum 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | async def thermal_protection_handler(response): 19 | print('Motor thermal protection response:', response) 20 | 21 | 22 | async def main(): 23 | """ This program demonstrates how to register a handler for a motor thermal protection notification, in the event 24 | RVR's motors are at risk of overheating. In order to receive the notification, RVR's motors must be heavily 25 | used for an extended period. 26 | 27 | For visibility into the motor temperatures, they are printed to the console every minute. 28 | """ 29 | 30 | printing_loop_counter=9; 31 | 32 | await rvr.wake() 33 | 34 | await rvr.enable_motor_thermal_protection_status_notify(is_enabled=True) 35 | 36 | await rvr.on_motor_thermal_protection_status_notify(handler=thermal_protection_handler) 37 | 38 | # Give RVR time to wake up 39 | await asyncio.sleep(1) 40 | 41 | print('Press CTRL+C to stop this program anytime.') 42 | 43 | # Allow RVR to drive infinitely 44 | while True: 45 | await rvr.drive_tank_normalized( 46 | left_velocity=127, # Valid linear velocity values are [-127..127] 47 | right_velocity=-127 # Valid linear velocity values are [-127..127] 48 | ) 49 | 50 | await asyncio.sleep(1) 51 | 52 | printing_loop_counter += 1 53 | if(++printing_loop_counter>=10): 54 | # It's been 1 minute. Zero the counter 55 | printing_loop_counter = 0 56 | 57 | # Query the temperature 58 | response = await rvr.get_temperature( 59 | id0=TemperatureSensorsEnum.left_motor_temperature.value, 60 | id1=TemperatureSensorsEnum.right_motor_temperature.value 61 | ) 62 | 63 | # 2 Decimal places are displayed only to make changes more visible. 64 | # Motor thermal modeling is not actually that precise in practice. 65 | print("L={0:.2f}C, R={1:.2f}C".format(response["temp0"], response["temp1"])) 66 | 67 | 68 | 69 | if __name__ == '__main__': 70 | try: 71 | loop.run_until_complete( 72 | main() 73 | ) 74 | 75 | except KeyboardInterrupt: 76 | print('\nProgram terminated with keyboard interrupt.') 77 | 78 | loop.run_until_complete( 79 | rvr.close() 80 | ) 81 | 82 | finally: 83 | if loop.is_running(): 84 | loop.close() 85 | -------------------------------------------------------------------------------- /getting_started/asyncio/power/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/power/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/power/get_battery_state.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import BatteryVoltageStatesEnum as VoltageStates 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """ This program demonstrates how to retrieve the battery state of RVR. 22 | """ 23 | 24 | await rvr.wake() 25 | 26 | # Give RVR time to wake up 27 | await asyncio.sleep(2) 28 | 29 | battery_percentage = await rvr.get_battery_percentage() 30 | print('Battery percentage: ', battery_percentage) 31 | 32 | battery_voltage_state = await rvr.get_battery_voltage_state() 33 | print('Voltage state: ', battery_voltage_state) 34 | 35 | state_info = '[{}, {}, {}, {}]'.format( 36 | '{}: {}'.format(VoltageStates.unknown.name, VoltageStates.unknown.value), 37 | '{}: {}'.format(VoltageStates.ok.name, VoltageStates.ok.value), 38 | '{}: {}'.format(VoltageStates.low.name, VoltageStates.low.value), 39 | '{}: {}'.format(VoltageStates.critical.name, VoltageStates.critical.value) 40 | ) 41 | print('Voltage states: ', state_info) 42 | 43 | await rvr.close() 44 | 45 | 46 | if __name__ == '__main__': 47 | try: 48 | loop.run_until_complete( 49 | main() 50 | ) 51 | 52 | except KeyboardInterrupt: 53 | print('\nProgram terminated with keyboard interrupt.') 54 | 55 | loop.run_until_complete( 56 | rvr.close() 57 | ) 58 | 59 | finally: 60 | if loop.is_running(): 61 | loop.close() 62 | -------------------------------------------------------------------------------- /getting_started/asyncio/power/get_battery_state_notifications.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def battery_voltage_state_change_handler(battery_voltage_state): 20 | print('Battery voltage state: ', battery_voltage_state) 21 | 22 | 23 | async def main(): 24 | """ This program demonstrates how to enable battery state change notifications. 25 | """ 26 | 27 | await rvr.wake() 28 | 29 | # Give RVR time to wake up 30 | await asyncio.sleep(2) 31 | 32 | await rvr.on_battery_voltage_state_change_notify(handler=battery_voltage_state_change_handler) 33 | await rvr.enable_battery_voltage_state_change_notify(is_enabled=True) 34 | 35 | print('Waiting for battery notification...') 36 | 37 | # The asyncio loop will run forever to give the aforementioned events time to occur 38 | 39 | 40 | if __name__ == '__main__': 41 | try: 42 | asyncio.ensure_future( 43 | main() 44 | ) 45 | loop.run_forever() 46 | 47 | except KeyboardInterrupt: 48 | print('\nProgram terminated with keyboard interrupt.') 49 | 50 | loop.run_until_complete( 51 | rvr.close() 52 | ) 53 | 54 | finally: 55 | if loop.is_running(): 56 | loop.close() 57 | -------------------------------------------------------------------------------- /getting_started/asyncio/power/sleep_monitoring.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | 9 | 10 | loop = asyncio.get_event_loop() 11 | 12 | rvr = SpheroRvrAsync( 13 | dal=SerialAsyncDal( 14 | loop 15 | ) 16 | ) 17 | 18 | 19 | async def will_sleep_handler(): 20 | print('RVR is about to sleep...') 21 | 22 | # here we could issue a command to RVR, e.g. wake() such that the sleep timer is reset 23 | 24 | 25 | async def did_sleep_handler(): 26 | print('RVR is asleep...') 27 | 28 | 29 | async def main(): 30 | """ This program demonstrates how to register handlers for a) the event received 10 seconds 31 | before RVR will sleep unless some new command is issued and b) the event received 32 | when RVR does go to sleep. 33 | 34 | Note that these notifications are received without the need to enable them on the robot. 35 | """ 36 | 37 | await rvr.wake() 38 | 39 | # Give RVR time to wake up 40 | await asyncio.sleep(2) 41 | 42 | await rvr.on_will_sleep_notify(handler=will_sleep_handler) 43 | await rvr.on_did_sleep_notify(handler=did_sleep_handler) 44 | 45 | # The asyncio loop will run forever to give the aforementioned events time to occur 46 | 47 | 48 | if __name__ == '__main__': 49 | try: 50 | asyncio.ensure_future( 51 | main() 52 | ) 53 | loop.run_forever() 54 | 55 | except KeyboardInterrupt: 56 | print('\nProgram terminated with keyboard interrupt.') 57 | 58 | loop.run_until_complete( 59 | rvr.close() 60 | ) 61 | 62 | finally: 63 | if loop.is_running(): 64 | loop.close() 65 | -------------------------------------------------------------------------------- /getting_started/asyncio/sensor_streaming/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/sensor_streaming/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/sensor_streaming/multi_sensor_stream.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RvrStreamingServices 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def imu_handler(imu_data): 21 | print('IMU data response: ', imu_data) 22 | 23 | 24 | async def color_detected_handler(color_detected_data): 25 | print('Color detection data response: ', color_detected_data) 26 | 27 | 28 | async def accelerometer_handler(accelerometer_data): 29 | print('Accelerometer data response: ', accelerometer_data) 30 | 31 | 32 | async def ambient_light_handler(ambient_light_data): 33 | print('Ambient light data response: ', ambient_light_data) 34 | 35 | async def encoder_handler(encoder_data): 36 | print('Encoder data response: ', encoder_data) 37 | 38 | 39 | async def main(): 40 | """ This program demonstrates how to enable multiple sensors to stream. 41 | """ 42 | 43 | await rvr.wake() 44 | 45 | # Give RVR time to wake up 46 | await asyncio.sleep(2) 47 | 48 | await rvr.sensor_control.add_sensor_data_handler( 49 | service=RvrStreamingServices.imu, 50 | handler=imu_handler 51 | ) 52 | await rvr.sensor_control.add_sensor_data_handler( 53 | service=RvrStreamingServices.color_detection, 54 | handler=color_detected_handler 55 | ) 56 | await rvr.sensor_control.add_sensor_data_handler( 57 | service=RvrStreamingServices.accelerometer, 58 | handler=accelerometer_handler 59 | ) 60 | await rvr.sensor_control.add_sensor_data_handler( 61 | service=RvrStreamingServices.ambient_light, 62 | handler=ambient_light_handler 63 | ) 64 | await rvr.sensor_control.add_sensor_data_handler( 65 | service=RvrStreamingServices.encoders, 66 | handler=encoder_handler 67 | ) 68 | 69 | await rvr.sensor_control.start(interval=250) 70 | 71 | # The asyncio loop will run forever to allow infinite streaming. 72 | 73 | 74 | if __name__ == '__main__': 75 | try: 76 | asyncio.ensure_future( 77 | main() 78 | ) 79 | loop.run_forever() 80 | 81 | except KeyboardInterrupt: 82 | print('\nProgram terminated with keyboard interrupt.') 83 | 84 | loop.run_until_complete( 85 | asyncio.gather( 86 | rvr.sensor_control.clear(), 87 | rvr.close() 88 | ) 89 | ) 90 | 91 | finally: 92 | if loop.is_running(): 93 | loop.close() 94 | -------------------------------------------------------------------------------- /getting_started/asyncio/sensor_streaming/single_sensor_stream.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import RvrStreamingServices 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def accelerometer_handler(accelerometer_data): 21 | print('Accelerometer data response: ', accelerometer_data) 22 | 23 | 24 | async def main(): 25 | """ This program demonstrates how to enable a single sensor to stream. 26 | """ 27 | 28 | await rvr.wake() 29 | 30 | # Give RVR time to wake up 31 | await asyncio.sleep(2) 32 | 33 | await rvr.sensor_control.add_sensor_data_handler( 34 | service=RvrStreamingServices.accelerometer, 35 | handler=accelerometer_handler 36 | ) 37 | 38 | await rvr.sensor_control.start(interval=250) 39 | 40 | # The asyncio loop will run forever to allow infinite streaming. 41 | 42 | 43 | if __name__ == '__main__': 44 | try: 45 | asyncio.ensure_future( 46 | main() 47 | ) 48 | loop.run_forever() 49 | 50 | except KeyboardInterrupt: 51 | print('\nProgram terminated with keyboard interrupt.') 52 | 53 | loop.run_until_complete( 54 | asyncio.gather( 55 | rvr.sensor_control.clear(), 56 | rvr.close() 57 | ) 58 | ) 59 | 60 | finally: 61 | if loop.is_running(): 62 | loop.close() 63 | -------------------------------------------------------------------------------- /getting_started/asyncio/system/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/asyncio/system/__init__.py -------------------------------------------------------------------------------- /getting_started/asyncio/system/get_main_app_version.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | import asyncio 6 | from sphero_sdk import SpheroRvrAsync 7 | from sphero_sdk import SerialAsyncDal 8 | from sphero_sdk import SpheroRvrTargets 9 | 10 | 11 | loop = asyncio.get_event_loop() 12 | 13 | rvr = SpheroRvrAsync( 14 | dal=SerialAsyncDal( 15 | loop 16 | ) 17 | ) 18 | 19 | 20 | async def main(): 21 | """This program demonstrates how to obtain the firmware version for a specific processor. RVR does not 22 | need to be awake for this operation. 23 | """ 24 | 25 | nordic_main_application_version = await rvr.get_main_application_version(target=SpheroRvrTargets.primary.value) 26 | print('Nordic main application version (target 1): ', nordic_main_application_version) 27 | 28 | st_main_application_version = await rvr.get_main_application_version(target=SpheroRvrTargets.secondary.value) 29 | print('ST main application version (target 2): ', st_main_application_version) 30 | 31 | await rvr.close() 32 | 33 | 34 | if __name__ == '__main__': 35 | try: 36 | loop.run_until_complete( 37 | main() 38 | ) 39 | 40 | except KeyboardInterrupt: 41 | print('\nProgram terminated with keyboard interrupt.') 42 | 43 | loop.run_until_complete( 44 | rvr.close() 45 | ) 46 | 47 | finally: 48 | if loop.is_running(): 49 | loop.close() 50 | -------------------------------------------------------------------------------- /getting_started/observer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/api_and_shell/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/api_and_shell/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/api_and_shell/echo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import SpheroRvrTargets 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def echo_handler(echo_response): 14 | print('Echo response: ', echo_response) 15 | 16 | 17 | def main(): 18 | """ This program demonstrates how to use the echo command, which sends data to RVR and RVR returns 19 | the same data. Echo can be used to check to see if RVR is connected. RVR does not need to be awake 20 | for this operation. 21 | """ 22 | 23 | rvr.echo( 24 | data=[0, 1, 2], 25 | handler=echo_handler, 26 | target=SpheroRvrTargets.primary.value 27 | ) 28 | 29 | # Give RVR time to respond 30 | time.sleep(1) 31 | 32 | rvr.echo( 33 | data=[3, 4, 5], 34 | handler=echo_handler, 35 | target=SpheroRvrTargets.secondary.value 36 | ) 37 | 38 | # Sleep for one second such that RVR has time to send data back 39 | time.sleep(1) 40 | 41 | rvr.close() 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /getting_started/observer/api_and_shell/generate_api_error.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import SpheroRvrTargets 8 | from sphero_sdk import ApiResponseCodesEnum 9 | from sphero_sdk.common.log_level import LogLevel 10 | 11 | rvr = SpheroRvrObserver(log_level=LogLevel.Debug_Verbose) 12 | 13 | 14 | def main(): 15 | """ This sample uses the generate_api_error command to intentionally generate an error response from RVR 16 | with the specified response code. Under normal circumstances certain commands request a response from RVR. 17 | If an error response is detected then it can be handled by the SDK's response logic. However, if a 18 | command does not have expected output, and therefore doesn't request a response (e.g. drive_with_heading), 19 | then RVR does not generate an error response if one occurs. Setting the request_error_responses_only flag 20 | on RVR will enable it to generate error responses even if no output is expected, and give a program the 21 | ability to catch any of the following 10 error response codes: 22 | 23 | Response Code 0x00: success 24 | Response Code 0x01: bad_did 25 | Response Code 0x02: bad_cid 26 | Response Code 0x03: not_yet_implemented 27 | Response Code 0x04: restricted 28 | Response Code 0x05: bad_data_length 29 | Response Code 0x06: failed 30 | Response Code 0x07: bad_data_value 31 | Response Code 0x08: busy 32 | Response Code 0x09: bad_tid (bad target id) 33 | Response Code 0x0A: target_unavailable 34 | 35 | Note a response code of 0x00 indicates a successful command, and is therefore is not considered an error. 36 | """ 37 | try: 38 | # Since the generate_api_error command doesn't expect any output, the enable_error_responses_only flag must 39 | # be set True in order for RVR to generate an error. This flag will remain true until otherwise specified, 40 | # or when the program terminates. 41 | rvr.request_error_responses_only = True 42 | 43 | rvr.generate_api_error( 44 | error=ApiResponseCodesEnum.bad_cid, # Specify code 0x01 - 0x0A to receive that specific error response from RVR. 45 | target=SpheroRvrTargets.secondary.value, 46 | timeout=3 47 | ) 48 | 49 | # Sleep for one second such that RVR has time to send data back 50 | time.sleep(1) 51 | except KeyboardInterrupt: 52 | print('\nProgram terminated with keyboard interrupt.') 53 | except Exception: 54 | print("ERROR ERROR ERROR") 55 | finally: 56 | rvr.close() 57 | 58 | 59 | if __name__ == '__main__': 60 | main() 61 | -------------------------------------------------------------------------------- /getting_started/observer/color_sensor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/color_sensor/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/color_sensor/color_detection.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RvrStreamingServices 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def color_detected_handler(color_detected_data): 14 | print('Color detection data response: ', color_detected_data) 15 | 16 | 17 | def main(): 18 | """ This program demonstrates how to use the color sensor on RVR (located on the down side of RVR, facing the floor) 19 | to report colors detected. 20 | """ 21 | 22 | try: 23 | rvr.wake() 24 | 25 | # Give RVR time to wake up 26 | time.sleep(2) 27 | 28 | rvr.enable_color_detection(is_enabled=True) 29 | rvr.sensor_control.add_sensor_data_handler( 30 | service=RvrStreamingServices.color_detection, 31 | handler=color_detected_handler 32 | ) 33 | rvr.sensor_control.start(interval=250) 34 | 35 | # Allow this program to run for 10 seconds 36 | time.sleep(10) 37 | 38 | except KeyboardInterrupt: 39 | print('\nProgram terminated with keyboard interrupt.') 40 | 41 | finally: 42 | rvr.sensor_control.clear() 43 | 44 | # Delay to allow RVR issue command before closing 45 | time.sleep(.5) 46 | 47 | rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /getting_started/observer/driving/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/driving/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_raw_motors.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RawMotorModesEnum 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def main(): 14 | """ This program has RVR drive around in different directions. 15 | """ 16 | 17 | try: 18 | rvr.wake() 19 | 20 | # Give RVR time to wake up 21 | time.sleep(2) 22 | 23 | rvr.reset_yaw() 24 | 25 | rvr.raw_motors( 26 | left_mode=RawMotorModesEnum.forward.value, 27 | left_duty_cycle=128, # Valid duty cycle range is 0-255 28 | right_mode=RawMotorModesEnum.forward.value, 29 | right_duty_cycle=128 # Valid duty cycle range is 0-255 30 | ) 31 | 32 | # Delay to allow RVR to drive 33 | time.sleep(1) 34 | 35 | rvr.raw_motors( 36 | left_mode=RawMotorModesEnum.reverse.value, 37 | left_duty_cycle=64, # Valid duty cycle range is 0-255 38 | right_mode=RawMotorModesEnum.reverse.value, 39 | right_duty_cycle=64 # Valid duty cycle range is 0-255 40 | ) 41 | 42 | # Delay to allow RVR to drive 43 | time.sleep(1) 44 | 45 | rvr.raw_motors( 46 | left_mode=RawMotorModesEnum.reverse.value, 47 | left_duty_cycle=128, # Valid duty cycle range is 0-255 48 | right_mode=RawMotorModesEnum.forward.value, 49 | right_duty_cycle=128 # Valid duty cycle range is 0-255 50 | ) 51 | 52 | # Delay to allow RVR to drive 53 | time.sleep(1) 54 | 55 | rvr.raw_motors( 56 | left_mode=RawMotorModesEnum.forward.value, 57 | left_duty_cycle=128, # Valid duty cycle range is 0-255 58 | right_mode=RawMotorModesEnum.forward.value, 59 | right_duty_cycle=128 # Valid duty cycle range is 0-255 60 | ) 61 | 62 | # Delay to allow RVR to drive 63 | time.sleep(1) 64 | 65 | rvr.raw_motors( 66 | left_mode=RawMotorModesEnum.off.value, 67 | left_duty_cycle=0, # Valid duty cycle range is 0-255 68 | right_mode=RawMotorModesEnum.off.value, 69 | right_duty_cycle=0 # Valid duty cycle range is 0-255 70 | ) 71 | 72 | # Delay to allow RVR to drive 73 | time.sleep(1) 74 | 75 | except KeyboardInterrupt: 76 | print('\nProgram terminated with keyboard interrupt.') 77 | 78 | finally: 79 | rvr.close() 80 | 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_rc_normalized.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | # Handler for the active controller stopped notification. 11 | # After sending a stop command, your program can wait for 12 | # this async to confirm that the robot has come to a stop 13 | def stopped_handler(): 14 | print('RVR has stopped') 15 | 16 | 17 | def main(): 18 | """ This program has RVR drive around using the normalized RC drive command. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | # Give RVR time to wake up 25 | time.sleep(2) 26 | 27 | # Register the handler for the stopped notification 28 | rvr.on_robot_has_stopped_notify(handler=stopped_handler) 29 | 30 | rvr.reset_yaw() 31 | 32 | print("sending drive command") 33 | 34 | rvr.drive_rc_normalized( 35 | linear_velocity=20, # Valid linear velocity values are -127..127 36 | yaw_angular_velocity=0, # Valid angular velocity values are -127..127 37 | flags=0 38 | ) 39 | 40 | # Delay to allow RVR to drive 41 | time.sleep(2) 42 | 43 | # Continue driving forward, while turning left 44 | rvr.drive_rc_normalized( 45 | linear_velocity=20, # Valid linear velocity values are -127..127 46 | yaw_angular_velocity=20, # Valid angular velocity values are -127..127 47 | flags=0 48 | ) 49 | 50 | # Delay to allow RVR to turn 51 | time.sleep(1) 52 | 53 | # Drive in new forward direction 54 | rvr.drive_rc_normalized( 55 | linear_velocity=20, # Valid linear velocity values are -127..127 56 | yaw_angular_velocity=0, # Valid angular velocity values are -127..127 57 | flags=0 58 | ) 59 | 60 | # Delay to allow RVR to drive 61 | time.sleep(2) 62 | 63 | print("sending stop command") 64 | 65 | # Stop driving, with deceleration rate of 2 m/s^2 66 | rvr.drive_stop(2.0) 67 | 68 | # Delay to allow RVR to stop 69 | time.sleep(1) 70 | 71 | except KeyboardInterrupt: 72 | print('\nProgram terminated with keyboard interrupt.') 73 | 74 | finally: 75 | rvr.close() 76 | 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_rc_si_units.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | # Handler for the active controller stopped notification. 11 | # After sending a stop command, your program can wait for 12 | # this async to confirm that the robot has come to a stop 13 | def stopped_handler(): 14 | print('RVR has stopped') 15 | 16 | 17 | def main(): 18 | """ This program has RVR drive around using the normalized RC drive command. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | # Give RVR time to wake up 25 | time.sleep(2) 26 | 27 | # Register the handler for the stopped notification 28 | rvr.on_robot_has_stopped_notify(handler=stopped_handler) 29 | 30 | rvr.reset_yaw() 31 | 32 | print("sending drive command") 33 | 34 | rvr.drive_rc_si_units( 35 | linear_velocity=.3, # Valid velocity values are in the range of [-2..2] m/s 36 | yaw_angular_velocity=0, # RVR will spin at up to 624 degrees/s. Values outside of [-624..624] will saturate internally. 37 | flags=0 38 | ) 39 | 40 | # Delay to allow RVR to drive 41 | time.sleep(1) 42 | 43 | # The control system timeout can be modified to keep a command running longer 44 | # than the default 2 seconds. This remains in effect until changed back, 45 | # or until a reboot occurs. Note that this is in milliseconds. 46 | rvr.set_custom_control_system_timeout(command_timeout=20000) 47 | 48 | # Continue driving forward, while turning left 49 | rvr.drive_rc_si_units( 50 | linear_velocity=.1, 51 | yaw_angular_velocity=20, 52 | flags=0 53 | ) 54 | 55 | # Delay to allow RVR to drive 56 | time.sleep(18) # Oh look, there'll be 2 seconds of driving to go! 57 | 58 | print("sending stop command") 59 | 60 | # Stop early, with a custom deceleration rate of 2 m/s^2. 61 | rvr.drive_stop(2.0) 62 | 63 | # Restore the default control system timeout to keep things more normal after this. 64 | rvr.restore_default_control_system_timeout() 65 | 66 | # Delay to allow RVR to stop 67 | time.sleep(1) 68 | 69 | except KeyboardInterrupt: 70 | print('\nProgram terminated with keyboard interrupt.') 71 | 72 | finally: 73 | rvr.close() 74 | 75 | 76 | if __name__ == '__main__': 77 | main() -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_tank_normalized.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | 11 | def main(): 12 | """ This program has RVR drive around in different directions using the function drive_tank_normalized. 13 | This function commands a normalized linear velocity target for each tread. Velocity targets 14 | are normalized in the range [-127..127] 15 | """ 16 | try: 17 | rvr.wake() 18 | 19 | # Give RVR time to wake up 20 | time.sleep(2) 21 | 22 | rvr.reset_yaw() 23 | 24 | # drive forward, 50% speed 25 | rvr.drive_tank_normalized( 26 | left_velocity=64, # Valid velocity values are [-127..127] 27 | right_velocity=64 # Valid velocity values are [-127..127] 28 | ) 29 | 30 | # Delay to allow RVR to drive 31 | time.sleep(1) 32 | 33 | # drive reverse, 50% speed 34 | rvr.drive_tank_normalized( 35 | left_velocity=-64, # Valid velocity values are [-127..127] 36 | right_velocity=-64 # Valid velocity values are [-127..127] 37 | ) 38 | 39 | # Delay to allow RVR to drive 40 | time.sleep(1) 41 | 42 | # Spin in place slowly 43 | rvr.drive_tank_normalized( 44 | left_velocity=5, # Valid velocity values are [-127..127] 45 | right_velocity=-5 # Valid velocity values are [-127..127] 46 | ) 47 | 48 | # Delay to allow RVR to drive 49 | time.sleep(2) 50 | 51 | # Spin in place quickly 52 | rvr.drive_tank_normalized( 53 | left_velocity=-127, # Valid velocity values are [-127..127] 54 | right_velocity=127 # Valid velocity values are [-127..127] 55 | ) 56 | 57 | # Delay to allow RVR to drive 58 | time.sleep(2) 59 | 60 | rvr.drive_tank_normalized( 61 | left_velocity=0, # Valid velocity values are [-127..127] 62 | right_velocity=0 # Valid velocity values are [-127..127] 63 | ) 64 | 65 | # Delay to allow RVR to drive 66 | time.sleep(1) 67 | 68 | except KeyboardInterrupt: 69 | print('\nProgram terminated with keyboard interrupt.') 70 | 71 | finally: 72 | rvr.close() 73 | 74 | 75 | if __name__ == '__main__': 76 | main() -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_tank_si.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | 11 | def main(): 12 | """ This program has RVR drive around in different directions using the function drive_tank_si. 13 | This function commands a floating point linear velocity target for each tread in meters per second. 14 | Achievable velocity targets are in the range of [-1.555..1.555] 15 | """ 16 | 17 | try: 18 | rvr.wake() 19 | 20 | # Give RVR time to wake up 21 | time.sleep(2) 22 | 23 | rvr.reset_yaw() 24 | 25 | # drive forward, 50% speed 26 | rvr.drive_tank_si_units( 27 | left_velocity=0.75, # Valid velocity values are [-1.555..1.555] 28 | right_velocity=0.75 29 | ) 30 | 31 | # Delay to allow RVR to drive 32 | time.sleep(1) 33 | 34 | # drive reverse, ~50% speed 35 | rvr.drive_tank_si_units( 36 | left_velocity=-0.75, 37 | right_velocity=-0.75 38 | ) 39 | 40 | # Delay to allow RVR to drive 41 | time.sleep(1) 42 | 43 | # Spin in place slowly 44 | rvr.drive_tank_si_units( 45 | left_velocity=0.1, 46 | right_velocity=-0.1 47 | ) 48 | 49 | # Delay to allow RVR to drive 50 | time.sleep(2) 51 | 52 | # Spin in place quickly 53 | rvr.drive_tank_si_units( 54 | left_velocity=-1.5, 55 | right_velocity=1.5 56 | ) 57 | 58 | # Delay to allow RVR to drive 59 | time.sleep(2) 60 | 61 | rvr.drive_tank_si_units( 62 | left_velocity=0, 63 | right_velocity=0 64 | ) 65 | 66 | # Delay to allow RVR to drive 67 | time.sleep(1) 68 | 69 | except KeyboardInterrupt: 70 | print('\nProgram terminated with keyboard interrupt.') 71 | 72 | finally: 73 | rvr.close() 74 | 75 | 76 | if __name__ == '__main__': 77 | main() 78 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_with_heading.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import DriveFlagsBitmask 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def main(): 14 | """ This program has RVR drive around in different directions using the function drive_with_heading. 15 | """ 16 | 17 | try: 18 | rvr.wake() 19 | 20 | # Give RVR time to wake up 21 | time.sleep(2) 22 | 23 | rvr.reset_yaw() 24 | 25 | rvr.drive_with_heading( 26 | speed=128, # Valid speed values are 0-255 27 | heading=0, # Valid heading values are 0-359 28 | flags=DriveFlagsBitmask.none.value 29 | ) 30 | 31 | # Delay to allow RVR to drive 32 | time.sleep(1) 33 | 34 | rvr.drive_with_heading( 35 | speed=128, # Valid speed values are 0-255 36 | heading=0, # Valid heading values are 0-359 37 | flags=DriveFlagsBitmask.drive_reverse.value 38 | ) 39 | 40 | # Delay to allow RVR to drive 41 | time.sleep(1) 42 | 43 | rvr.drive_with_heading( 44 | speed=128, # Valid speed values are 0-255 45 | heading=90, # Valid heading values are 0-359 46 | flags=DriveFlagsBitmask.none.value 47 | ) 48 | 49 | # Delay to allow RVR to drive 50 | time.sleep(1) 51 | 52 | rvr.drive_with_heading( 53 | speed=128, # Valid speed values are 0-255 54 | heading=270, # Valid heading values are 0-359 55 | flags=DriveFlagsBitmask.none.value 56 | ) 57 | 58 | # Delay to allow RVR to drive 59 | time.sleep(1) 60 | 61 | rvr.drive_with_heading( 62 | speed=0, # Valid heading values are 0-359 63 | heading=0, # Valid heading values are 0-359 64 | flags=DriveFlagsBitmask.none.value 65 | ) 66 | 67 | # Delay to allow RVR to drive 68 | time.sleep(1) 69 | 70 | except KeyboardInterrupt: 71 | print('\nProgram terminated with keyboard interrupt.') 72 | 73 | finally: 74 | rvr.close() 75 | 76 | 77 | if __name__ == '__main__': 78 | main() 79 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_with_heading_reverse_mode.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import DriveFlagsBitmask 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def main(): 14 | """ This program has RVR drive around in different directions using the function drive_with_heading. 15 | """ 16 | 17 | try: 18 | rvr.wake() 19 | 20 | # Give RVR time to wake up 21 | time.sleep(2) 22 | 23 | rvr.reset_yaw() 24 | 25 | rvr.drive_with_heading( 26 | speed=128, # Valid speed values are 0-255 27 | heading=90, # Valid heading values are 0-359 28 | flags=DriveFlagsBitmask.drive_reverse.value 29 | ) 30 | 31 | # Delay to allow RVR to drive 32 | time.sleep(1) 33 | 34 | rvr.drive_with_heading( 35 | speed=0, # Valid heading values are 0-359 36 | heading=0, # Valid heading values are 0-359 37 | flags=DriveFlagsBitmask.none.value 38 | ) 39 | 40 | # Delay to allow RVR to drive 41 | time.sleep(1) 42 | 43 | except KeyboardInterrupt: 44 | print('\nProgram terminated with keyboard interrupt.') 45 | 46 | finally: 47 | rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def main(): 13 | """ This program has RVR drive with how to drive RVR using the drive control helper. 14 | """ 15 | 16 | try: 17 | rvr.wake() 18 | 19 | # Give RVR time to wake up 20 | time.sleep(2) 21 | 22 | rvr.drive_control.reset_heading() 23 | 24 | rvr.drive_control.drive_forward_seconds( 25 | speed=64, 26 | heading=0, # Valid heading values are 0-359 27 | time_to_drive=1 28 | ) 29 | 30 | # Delay to allow RVR to drive 31 | time.sleep(1) 32 | 33 | rvr.drive_control.drive_backward_seconds( 34 | speed=64, 35 | heading=0, # Valid heading values are 0-359 36 | time_to_drive=1 37 | ) 38 | 39 | # Delay to allow RVR to drive 40 | time.sleep(1) 41 | 42 | rvr.drive_control.turn_left_degrees( 43 | heading=0, # Valid heading values are 0-359 44 | amount=90 45 | ) 46 | 47 | # Delay to allow RVR to drive 48 | time.sleep(1) 49 | 50 | except KeyboardInterrupt: 51 | print('\nProgram terminated with keyboard interrupt.') 52 | 53 | finally: 54 | rvr.close() 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /getting_started/observer/driving/drive_with_helper_roll.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def main(): 13 | """ This program has RVR drive with how to drive RVR using the drive control helper. 14 | """ 15 | 16 | try: 17 | rvr.wake() 18 | 19 | # Give RVR time to wake up 20 | time.sleep(2) 21 | 22 | rvr.drive_control.reset_heading() 23 | 24 | rvr.drive_control.roll_start( 25 | speed=64, 26 | heading=90 27 | ) 28 | 29 | # Delay to allow RVR to drive 30 | time.sleep(1) 31 | 32 | rvr.drive_control.roll_stop(heading=270) 33 | 34 | # Delay to allow RVR to drive 35 | time.sleep(1) 36 | 37 | except KeyboardInterrupt: 38 | print('\nProgram terminated with keyboard interrupt.') 39 | 40 | finally: 41 | rvr.close() 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /getting_started/observer/driving/get_encoder_counts.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | 11 | def get_encoder_counts_response_handler(response): 12 | print('Encoder counts response: ', response) 13 | 14 | 15 | def main(): 16 | """ This program demonstrates how to get encoder counts on RVR. 17 | """ 18 | 19 | try: 20 | rvr.wake() 21 | 22 | # Give RVR time to wake up 23 | time.sleep(2) 24 | 25 | rvr.get_encoder_counts(handler=get_encoder_counts_response_handler) 26 | 27 | # Give RVR time to respond 28 | time.sleep(1) 29 | 30 | except KeyboardInterrupt: 31 | print('\nProgram terminated with keyboard interrupt.') 32 | 33 | finally: 34 | rvr.close() 35 | 36 | 37 | if __name__ == '__main__': 38 | main() 39 | -------------------------------------------------------------------------------- /getting_started/observer/infrared/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/infrared/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/infrared/broadcast_ir.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import InfraredCodes 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.start_robot_to_robot_infrared_broadcasting( 25 | far_code=InfraredCodes.one.value, 26 | near_code=InfraredCodes.zero.value 27 | ) 28 | 29 | for i in range(2): 30 | rvr.raw_motors( 31 | left_mode=RawMotorModesEnum.forward.value, 32 | left_duty_cycle=64, # Valid duty cycle range is 0-255 33 | right_mode=RawMotorModesEnum.forward.value, 34 | right_duty_cycle=64 # Valid duty cycle range is 0-255 35 | ) 36 | 37 | # Delay to allow RVR to drive 38 | time.sleep(2) 39 | 40 | except: 41 | print('\nProgram terminated with keyboard interrupt.') 42 | 43 | finally: 44 | rvr.stop_robot_to_robot_infrared_broadcasting() 45 | 46 | # Delay to allow RVR issue command before closing 47 | time.sleep(.5) 48 | 49 | rvr.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /getting_started/observer/infrared/broadcast_ir_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import InfraredCodes 8 | from sphero_sdk import RawMotorModesEnum 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.infrared_control.start_robot_to_robot_infrared_broadcasting( 25 | far_code=InfraredCodes.one.value, 26 | near_code=InfraredCodes.zero.value 27 | ) 28 | 29 | rvr.raw_motors( 30 | left_mode=RawMotorModesEnum.forward.value, 31 | left_duty_cycle=64, # Valid duty cycle range is 0-255 32 | right_mode=RawMotorModesEnum.forward.value, 33 | right_duty_cycle=64 # Valid duty cycle range is 0-255 34 | ) 35 | 36 | # Delay to allow RVR to drive 37 | time.sleep(4) 38 | 39 | except: 40 | print('\nProgram terminated with keyboard interrupt.') 41 | 42 | finally: 43 | rvr.stop_robot_to_robot_infrared_broadcasting() 44 | 45 | # Delay to allow RVR issue command before closing 46 | time.sleep(.5) 47 | 48 | rvr.close() 49 | 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /getting_started/observer/infrared/listen_for_and_send_ir.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def infrared_message_received_handler(infrared_message): 13 | print('Infrared message response: ', infrared_message) 14 | 15 | 16 | def main(): 17 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 18 | """ 19 | 20 | try: 21 | rvr.wake() 22 | 23 | # Give RVR time to wake up 24 | time.sleep(2) 25 | 26 | rvr.on_robot_to_robot_infrared_message_received_notify(handler=infrared_message_received_handler) 27 | 28 | rvr.enable_robot_infrared_message_notify(is_enabled=True) 29 | 30 | infrared_code = 3 31 | strength = 64 32 | 33 | for _ in range(20): 34 | rvr.send_infrared_message( 35 | infrared_code=infrared_code, 36 | front_strength=strength, 37 | left_strength=strength, 38 | right_strength=strength, 39 | rear_strength=strength 40 | ) 41 | 42 | print('Infrared message sent with code: {0}'.format(infrared_code)) 43 | 44 | time.sleep(2) 45 | 46 | except KeyboardInterrupt: 47 | print('\nProgram terminated with keyboard interrupt.') 48 | 49 | finally: 50 | rvr.stop_robot_to_robot_infrared_broadcasting() 51 | 52 | # Delay to allow RVR issue command before closing 53 | time.sleep(.5) 54 | 55 | rvr.close() 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /getting_started/observer/infrared/listen_for_and_send_ir_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import InfraredCodes 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def infrared_message_received_handler(infrared_message): 14 | print('Infrared message response: ', infrared_message) 15 | 16 | 17 | def main(): 18 | """ This program sets up RVR to communicate with another robot, e.g. BOLT, capable of infrared communication. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | # Give RVR time to wake up 25 | time.sleep(2) 26 | 27 | rvr.infrared_control.listen_for_infrared_message(handler=infrared_message_received_handler) 28 | 29 | codes = [ 30 | InfraredCodes.zero, 31 | InfraredCodes.one, 32 | InfraredCodes.two, 33 | InfraredCodes.three 34 | ] 35 | 36 | for _ in range(20): 37 | rvr.infrared_control.send_infrared_messages( 38 | messages=codes, 39 | strength=64 40 | ) 41 | 42 | print('Infrared message sent with codes: {0}'.format([code.value for code in codes])) 43 | 44 | time.sleep(2) 45 | 46 | except KeyboardInterrupt: 47 | print('\nProgram terminated with keyboard interrupt.') 48 | 49 | finally: 50 | rvr.stop_robot_to_robot_infrared_broadcasting() 51 | 52 | # Delay to allow RVR issue command before closing 53 | time.sleep(.5) 54 | 55 | rvr.close() 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /getting_started/observer/leds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/leds/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/leds/set_all_leds.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program demonstrates how to set the all the LEDs. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.set_all_leds( 25 | led_group=RvrLedGroups.all_lights.value, 26 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 27 | ) 28 | 29 | # Delay to show LEDs change 30 | time.sleep(1) 31 | 32 | rvr.set_all_leds( 33 | led_group=RvrLedGroups.all_lights.value, 34 | led_brightness_values=[color for _ in range(10) for color in [255, 0, 0]] 35 | ) 36 | 37 | # Delay to show LEDs change 38 | time.sleep(1) 39 | 40 | except KeyboardInterrupt: 41 | print('\nProgram terminated with keyboard interrupt.') 42 | 43 | finally: 44 | rvr.close() 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /getting_started/observer/leds/set_all_leds_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def main(): 14 | """ This program demonstrates how to set the all the LEDs of RVR using the LED control helper. 15 | """ 16 | 17 | try: 18 | rvr.wake() 19 | 20 | # Give RVR time to wake up 21 | time.sleep(2) 22 | 23 | rvr.led_control.turn_leds_off() 24 | 25 | # Delay to show LEDs change 26 | time.sleep(1) 27 | 28 | rvr.led_control.set_all_leds_color(color=Colors.yellow) 29 | 30 | # Delay to show LEDs change 31 | time.sleep(1) 32 | 33 | rvr.led_control.turn_leds_off() 34 | 35 | # Delay to show LEDs change 36 | time.sleep(1) 37 | 38 | rvr.led_control.set_all_leds_rgb(red=255, green=144, blue=0) 39 | 40 | # Delay to show LEDs change 41 | time.sleep(1) 42 | 43 | except KeyboardInterrupt: 44 | print('\nProgram terminated with keyboard interrupt.') 45 | 46 | finally: 47 | rvr.close() 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /getting_started/observer/leds/set_multiple_leds.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program demonstrates how to set multiple LEDs. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.set_all_leds( 25 | led_group=RvrLedGroups.all_lights.value, 26 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 27 | ) 28 | 29 | # Delay to show LEDs change 30 | time.sleep(1) 31 | 32 | rvr.set_all_leds( 33 | led_group=RvrLedGroups.headlight_left.value | RvrLedGroups.headlight_right.value, 34 | led_brightness_values=[ 35 | 255, 0, 0, 36 | 0, 0, 255 37 | ] 38 | ) 39 | 40 | # Delay to show LEDs change 41 | time.sleep(1) 42 | 43 | except KeyboardInterrupt: 44 | print('\nProgram terminated with keyboard interrupt.') 45 | 46 | finally: 47 | rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /getting_started/observer/leds/set_multiple_leds_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program demonstrates how to set multiple LEDs on RVR using the LED control helper. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.led_control.turn_leds_off() 25 | 26 | # Delay to show LEDs change 27 | time.sleep(1) 28 | 29 | rvr.led_control.set_multiple_leds_with_enums( 30 | leds=[ 31 | RvrLedGroups.headlight_left, 32 | RvrLedGroups.headlight_right 33 | ], 34 | colors=[ 35 | Colors.green, 36 | Colors.blue 37 | ] 38 | ) 39 | 40 | # Delay to show LEDs change 41 | time.sleep(1) 42 | 43 | rvr.led_control.set_multiple_leds_with_rgb( 44 | leds=[ 45 | RvrLedGroups.headlight_left, 46 | RvrLedGroups.headlight_right 47 | ], 48 | colors=[ 49 | 255, 0, 0, 50 | 0, 255, 0 51 | ] 52 | ) 53 | 54 | # Delay to show LEDs change 55 | time.sleep(1) 56 | 57 | except KeyboardInterrupt: 58 | print('\nProgram terminated with keyboard interrupt.') 59 | 60 | finally: 61 | rvr.close() 62 | 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /getting_started/observer/leds/set_single_led.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program demonstrates how to set a single LED. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.set_all_leds( 25 | led_group=RvrLedGroups.all_lights.value, 26 | led_brightness_values=[color for _ in range(10) for color in Colors.off.value] 27 | ) 28 | 29 | # Delay to show LEDs change 30 | time.sleep(1) 31 | 32 | rvr.set_all_leds( 33 | led_group=RvrLedGroups.headlight_right.value, # 0xe00 34 | led_brightness_values=[255, 0, 0] 35 | ) 36 | 37 | # Delay to show LEDs change 38 | time.sleep(1) 39 | 40 | rvr.set_all_leds( 41 | led_group=RvrLedGroups.headlight_left.value, # 0x1c0 42 | led_brightness_values=[0, 255, 0] 43 | ) 44 | 45 | # Delay to show LEDs change 46 | time.sleep(1) 47 | 48 | except KeyboardInterrupt: 49 | print('\nProgram terminated with keyboard interrupt.') 50 | 51 | finally: 52 | rvr.close() 53 | 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /getting_started/observer/leds/set_single_led_with_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import Colors 8 | from sphero_sdk import RvrLedGroups 9 | 10 | 11 | rvr = SpheroRvrObserver() 12 | 13 | 14 | def main(): 15 | """ This program demonstrates how to set a single LED on RVR using the LED control helper. 16 | """ 17 | 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.led_control.turn_leds_off() 25 | 26 | # Delay to show LEDs change 27 | time.sleep(1) 28 | 29 | rvr.led_control.set_led_rgb( 30 | led=RvrLedGroups.headlight_right, 31 | red=255, 32 | green=0, 33 | blue=0 34 | ) 35 | 36 | # Delay to show LEDs change 37 | time.sleep(1) 38 | 39 | rvr.led_control.set_led_color( 40 | led=RvrLedGroups.headlight_left, 41 | color=Colors.green 42 | ) 43 | 44 | # Delay to show LEDs change 45 | time.sleep(1) 46 | 47 | except KeyboardInterrupt: 48 | print('\nProgram terminated with keyboard interrupt.') 49 | 50 | finally: 51 | rvr.close() 52 | 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /getting_started/observer/magnetometer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/magnetometer/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/magnetometer/get_magnetometer_reading.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | 10 | 11 | def get_magnetometer_reading_response_handler(response): 12 | print('Magnetometer reading response: ', response) 13 | 14 | 15 | def main(): 16 | """ This program demonstrates how to get a reading from the magnetometer on RVR. 17 | """ 18 | try: 19 | rvr.wake() 20 | 21 | # Give RVR time to wake up 22 | time.sleep(2) 23 | 24 | rvr.get_magnetometer_reading(handler=get_magnetometer_reading_response_handler) 25 | 26 | # Keep the script running briefly so we actually get to report the response. 27 | time.sleep(1) 28 | 29 | except KeyboardInterrupt: 30 | print('\nProgram terminated with keyboard interrupt.') 31 | 32 | finally: 33 | rvr.close() 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /getting_started/observer/motors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/motors/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/motors/get_motor_fault_state.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RawMotorModesEnum 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def motor_fault_handler(response): 14 | print('Motor fault state response:', response) 15 | 16 | def main(): 17 | """ In the rare event that a motor fault occurs, this program demonstrates how to retrieve the motor fault state 18 | on RVR. In order to detect a motor fault, there must be an attempt to use them. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | # Give RVR time to wake up 25 | time.sleep(2) 26 | 27 | rvr.raw_motors( 28 | left_mode=RawMotorModesEnum.forward.value, 29 | left_duty_cycle=128, # Valid duty cycle range is 0-255 30 | right_mode=RawMotorModesEnum.forward.value, 31 | right_duty_cycle=128 # Valid duty cycle range is 0-255 32 | ) 33 | 34 | # Delay to allow RVR to drive 35 | time.sleep(2) 36 | 37 | rvr.get_motor_fault_state(handler=motor_fault_handler) 38 | 39 | # Delay to allow callback 40 | time.sleep(1) 41 | 42 | except KeyboardInterrupt: 43 | print('\nProgram terminated with keyboard interrupt.') 44 | 45 | finally: 46 | rvr.close() 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /getting_started/observer/motors/get_thermal_protection_status.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RawMotorModesEnum 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def thermal_protection_handler(response): 14 | print('Thermal protection status response', response) 15 | 16 | def main(): 17 | """ This program demonstrates how to get motor thermal protection status, in the event RVR's motors have already 18 | been stopped to prevent overheating. This can be used to check if the motors are no longer in a thermal 19 | protection state. RVR does not need to be awake in order to run this operation. 20 | """ 21 | 22 | try: 23 | rvr.get_motor_fault_state(handler=thermal_protection_handler) 24 | 25 | # Delay to allow the callback to be invoked 26 | time.sleep(2) 27 | 28 | except KeyboardInterrupt: 29 | print('\nProgram terminated with keyboard interrupt.') 30 | 31 | finally: 32 | rvr.close() 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /getting_started/observer/motors/motor_fault_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RawMotorModesEnum 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def motor_fault_handler(response): 14 | print('Motor fault response:', response) 15 | 16 | def main(): 17 | """ In the rare event that a motor fault occurs while operating RVR, this program demonstrates how to register 18 | a handler for a motor fault notification. In order to receive a motor fault notification, RVR's motors 19 | must be in use. 20 | """ 21 | 22 | try: 23 | rvr.wake() 24 | 25 | rvr.enable_motor_fault_notify(is_enabled=True) 26 | 27 | rvr.on_motor_fault_notify(handler=motor_fault_handler) 28 | 29 | # Give RVR time to wake up 30 | time.sleep(2) 31 | 32 | rvr.raw_motors( 33 | left_mode=RawMotorModesEnum.forward.value, 34 | left_duty_cycle=128, # Valid duty cycle range is 0-255 35 | right_mode=RawMotorModesEnum.forward.value, 36 | right_duty_cycle=128 # Valid duty cycle range is 0-255 37 | ) 38 | 39 | # Delay to allow RVR to drive 40 | time.sleep(2) 41 | 42 | except KeyboardInterrupt: 43 | print('\nProgram terminated with keyboard interrupt.') 44 | 45 | finally: 46 | rvr.close() 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /getting_started/observer/motors/motor_stall_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RawMotorModesEnum 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def motor_stall_handler(response): 14 | print('Motor stall response:', response) 15 | 16 | def main(): 17 | """ This program demonstrates how to receive motor stall notifications, in the event that RVR's treads become 18 | obstructed, and is unable to move. In order to receive the notification, RVR's motors must be in use. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | rvr.enable_motor_stall_notify(is_enabled=True) 25 | 26 | rvr.on_motor_stall_notify(handler=motor_stall_handler) 27 | 28 | # Give RVR time to wake up 29 | time.sleep(2) 30 | 31 | rvr.raw_motors( 32 | left_mode=RawMotorModesEnum.forward.value, 33 | left_duty_cycle=128, # Valid duty cycle range is 0-255 34 | right_mode=RawMotorModesEnum.forward.value, 35 | right_duty_cycle=128 # Valid duty cycle range is 0-255 36 | ) 37 | 38 | # Delay to allow RVR to drive 39 | time.sleep(2) 40 | 41 | except KeyboardInterrupt: 42 | print('\nProgram terminated with keyboard interrupt.') 43 | 44 | finally: 45 | rvr.close() 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /getting_started/observer/motors/thermal_protection_notification.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import TemperatureSensorsEnum 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def thermal_protection_handler(response): 13 | print('Motor thermal protection response:', response) 14 | 15 | 16 | def main(): 17 | """ This program demonstrates how to register a handler for a motor thermal protection notification, in the event 18 | RVR's motors are at risk of overheating. In order to receive the notification, RVR's motors must be heavily 19 | used for an extended period. 20 | 21 | For visibility into the motor temperatures, they are printed to the console every minute. 22 | """ 23 | try: 24 | printing_loop_counter=9; 25 | 26 | rvr.wake() 27 | 28 | rvr.enable_motor_thermal_protection_status_notify(is_enabled=True) 29 | 30 | rvr.on_motor_thermal_protection_status_notify(handler=thermal_protection_handler) 31 | 32 | # Give RVR time to wake up 33 | time.sleep(1) 34 | 35 | print('Press CTRL+C to stop this program anytime.') 36 | 37 | # Allow RVR to drive infinitely 38 | while True: 39 | rvr.drive_tank_normalized( 40 | left_velocity=127, # Valid linear velocity values are [-127..127] 41 | right_velocity=-127 # Valid linear velocity values are [-127..127] 42 | ) 43 | 44 | time.sleep(1) 45 | 46 | printing_loop_counter += 1 47 | if(++printing_loop_counter>=10): 48 | # It's been 1 minute. Zero the counter 49 | printing_loop_counter = 0 50 | 51 | # Query the temperature 52 | response = rvr.get_temperature( 53 | id0=TemperatureSensorsEnum.left_motor_temperature.value, 54 | id1=TemperatureSensorsEnum.right_motor_temperature.value 55 | ) 56 | 57 | # 2 Decimal places are displayed only to make changes more visible. 58 | # Motor thermal modeling is not actually that precise in practice. 59 | print("L={0:.2f}C, R={1:.2f}C".format(response["temp0"], response["temp1"])) 60 | 61 | except KeyboardInterrupt: 62 | print('\nProgram terminated with keyboard interrupt.') 63 | 64 | finally: 65 | rvr.close() 66 | 67 | 68 | if __name__ == '__main__': 69 | main() -------------------------------------------------------------------------------- /getting_started/observer/power/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/power/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/power/get_battery_state.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import BatteryVoltageStatesEnum as VoltageStates 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def battery_percentage_handler(battery_percentage): 14 | print('Battery percentage: ', battery_percentage) 15 | 16 | 17 | def battery_voltage_handler(battery_voltage_state): 18 | print('Voltage state: ', battery_voltage_state) 19 | 20 | state_info = '[{}, {}, {}, {}]'.format( 21 | '{}: {}'.format(VoltageStates.unknown.name, VoltageStates.unknown.value), 22 | '{}: {}'.format(VoltageStates.ok.name, VoltageStates.ok.value), 23 | '{}: {}'.format(VoltageStates.low.name, VoltageStates.low.value), 24 | '{}: {}'.format(VoltageStates.critical.name, VoltageStates.critical.value) 25 | ) 26 | print('Voltage states: ', state_info) 27 | 28 | 29 | def main(): 30 | """ This program demonstrates how to retrieve the battery state of RVR. 31 | """ 32 | 33 | try: 34 | rvr.wake() 35 | 36 | # Give RVR time to wake up 37 | time.sleep(2) 38 | 39 | rvr.get_battery_percentage(handler=battery_percentage_handler) 40 | 41 | # Sleep for one second such that RVR has time to send data back 42 | time.sleep(1) 43 | 44 | rvr.get_battery_voltage_state(handler=battery_voltage_handler) 45 | 46 | # Sleep for one second such that RVR has time to send data back 47 | time.sleep(1) 48 | 49 | except KeyboardInterrupt: 50 | print('\nProgram terminated with keyboard interrupt.') 51 | 52 | finally: 53 | rvr.close() 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /getting_started/observer/power/get_battery_state_notifications.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def battery_voltage_state_change_handler(battery_voltage_state): 13 | print('Battery voltage state: ', battery_voltage_state) 14 | 15 | 16 | def main(): 17 | """ This program demonstrates how to enable battery state change notifications. 18 | """ 19 | 20 | try: 21 | rvr.wake() 22 | 23 | # Give RVR time to wake up 24 | time.sleep(2) 25 | 26 | rvr.on_battery_voltage_state_change_notify(handler=battery_voltage_state_change_handler) 27 | rvr.enable_battery_voltage_state_change_notify(is_enabled=True) 28 | 29 | except KeyboardInterrupt: 30 | print('\nProgram terminated with keyboard interrupt.') 31 | 32 | finally: 33 | rvr.close() 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /getting_started/observer/power/sleep_monitoring.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def will_sleep_handler(): 13 | print('RVR is about to sleep...') 14 | 15 | # here we could issue a command to RVR, e.g. wake() such that the sleep timer is reset 16 | 17 | 18 | def did_sleep_handler(): 19 | print('RVR is asleep...') 20 | 21 | 22 | def main(): 23 | """ This program demonstrates how to register handlers for a) the event received 10 seconds 24 | before RVR will sleep unless some new command is issued and b) the event received 25 | when RVR does go to sleep. 26 | 27 | Note that these notifications are received without the need to enable them on the robot. 28 | """ 29 | 30 | try: 31 | rvr.wake() 32 | 33 | # Give RVR time to wake up 34 | time.sleep(2) 35 | 36 | rvr.on_will_sleep_notify(will_sleep_handler) 37 | 38 | rvr.on_did_sleep_notify(did_sleep_handler) 39 | 40 | # Sleep for 310 seconds such that we see the aforementioned events have time to occur 41 | time.sleep(310) 42 | 43 | except KeyboardInterrupt: 44 | print('\nProgram terminated with keyboard interrupt.') 45 | 46 | finally: 47 | rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /getting_started/observer/sensor_streaming/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/sensor_streaming/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/sensor_streaming/multi_sensor_stream.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RvrStreamingServices 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def imu_handler(imu_data): 14 | print('IMU data response: ', imu_data) 15 | 16 | 17 | def color_detected_handler(color_detected_data): 18 | print('Color detection data response: ', color_detected_data) 19 | 20 | 21 | def accelerometer_handler(accelerometer_data): 22 | print('Accelerometer data response: ', accelerometer_data) 23 | 24 | 25 | def ambient_light_handler(ambient_light_data): 26 | print('Ambient light data response: ', ambient_light_data) 27 | 28 | def encoder_handler(encoder_data): 29 | print('Encoder data response: ', encoder_data) 30 | 31 | 32 | def main(): 33 | """ This program demonstrates how to enable multiple sensors to stream. 34 | """ 35 | 36 | try: 37 | rvr.wake() 38 | 39 | # Give RVR time to wake up 40 | time.sleep(2) 41 | 42 | rvr.sensor_control.add_sensor_data_handler( 43 | service=RvrStreamingServices.imu, 44 | handler=imu_handler 45 | ) 46 | rvr.sensor_control.add_sensor_data_handler( 47 | service=RvrStreamingServices.color_detection, 48 | handler=color_detected_handler 49 | ) 50 | rvr.sensor_control.add_sensor_data_handler( 51 | service=RvrStreamingServices.accelerometer, 52 | handler=accelerometer_handler 53 | ) 54 | rvr.sensor_control.add_sensor_data_handler( 55 | service=RvrStreamingServices.ambient_light, 56 | handler=ambient_light_handler 57 | ) 58 | rvr.sensor_control.add_sensor_data_handler( 59 | service=RvrStreamingServices.encoders, 60 | handler=encoder_handler 61 | ) 62 | 63 | rvr.sensor_control.start(interval=250) 64 | 65 | while True: 66 | # Delay to allow RVR to stream sensor data 67 | time.sleep(1) 68 | 69 | except KeyboardInterrupt: 70 | print('\nProgram terminated with keyboard interrupt.') 71 | 72 | finally: 73 | rvr.sensor_control.clear() 74 | 75 | # Delay to allow RVR issue command before closing 76 | time.sleep(.5) 77 | 78 | rvr.close() 79 | 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /getting_started/observer/sensor_streaming/single_sensor_stream.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RvrStreamingServices 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def accelerometer_handler(accelerometer_data): 14 | print('Accelerometer data response: ', accelerometer_data) 15 | 16 | 17 | def main(): 18 | """ This program demonstrates how to enable a single sensor to stream. 19 | """ 20 | 21 | try: 22 | rvr.wake() 23 | 24 | # Give RVR time to wake up 25 | time.sleep(2) 26 | 27 | rvr.sensor_control.add_sensor_data_handler( 28 | service=RvrStreamingServices.accelerometer, 29 | handler=accelerometer_handler 30 | ) 31 | 32 | rvr.sensor_control.start(interval=250) 33 | 34 | while True: 35 | # Delay to allow RVR to stream sensor data 36 | time.sleep(1) 37 | 38 | except KeyboardInterrupt: 39 | print('\nProgram terminated with keyboard interrupt.') 40 | 41 | finally: 42 | rvr.sensor_control.clear() 43 | 44 | # Delay to allow RVR issue command before closing 45 | time.sleep(.5) 46 | 47 | rvr.close() 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /getting_started/observer/system/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/getting_started/observer/system/__init__.py -------------------------------------------------------------------------------- /getting_started/observer/system/disable_notifications_and_active_commands.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import RvrStreamingServices 8 | 9 | rvr = SpheroRvrObserver() 10 | 11 | 12 | def imu_handler(imu_data): 13 | print('IMU data response: ', imu_data) 14 | 15 | 16 | def color_detected_handler(color_detected_data): 17 | print('Color detection data response: ', color_detected_data) 18 | 19 | 20 | def main(): 21 | """ This program demonstrates how to disable all notifications and active commands. 22 | """ 23 | 24 | try: 25 | rvr.wake() 26 | 27 | # Give RVR time to wake up 28 | time.sleep(2) 29 | 30 | print('Initiate streaming IMU and color sensor data...') 31 | rvr.enable_color_detection(is_enabled=True) 32 | rvr.sensor_control.add_sensor_data_handler( 33 | service=RvrStreamingServices.imu, 34 | handler=imu_handler 35 | ) 36 | rvr.sensor_control.add_sensor_data_handler( 37 | service=RvrStreamingServices.color_detection, 38 | handler=color_detected_handler 39 | ) 40 | rvr.sensor_control.start(interval=1000) 41 | 42 | print('Set the control system timeout to 10s and initiate a drive command...') 43 | rvr.set_custom_control_system_timeout(command_timeout=10000) 44 | rvr.drive_with_yaw_normalized( 45 | linear_velocity=32, # Valid linear_velocity values are in the range [-127..+127] 46 | yaw_angle=0 # Valid yaw values are traditionally [-179..+180], but will continue wrapping outside of that range 47 | ) 48 | 49 | # Delay to allow commands to run 50 | time.sleep(5) 51 | 52 | # Disable notifications and active commands 53 | rvr.disable_notifications_and_active_commands() 54 | print('Disabling notifications and active commands...') 55 | 56 | # Delay to allow observation that notifications and active commands have been disabled 57 | time.sleep(5) 58 | 59 | # Restore the default timeout (2 seconds) 60 | rvr.restore_default_control_system_timeout() 61 | 62 | except KeyboardInterrupt: 63 | print('\nProgram terminated with keyboard interrupt.') 64 | 65 | finally: 66 | rvr.close() 67 | 68 | 69 | if __name__ == '__main__': 70 | main() -------------------------------------------------------------------------------- /getting_started/observer/system/get_main_app_version.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 5 | 6 | from sphero_sdk import SpheroRvrObserver 7 | from sphero_sdk import SpheroRvrTargets 8 | 9 | 10 | rvr = SpheroRvrObserver() 11 | 12 | 13 | def get_nordic_main_application_version_handler(nordic_main_application_version): 14 | print('Nordic main application version (target 1): ', nordic_main_application_version) 15 | 16 | 17 | def get_st_main_application_version_handler(st_main_application_version): 18 | print('ST main application version (target 2): ', st_main_application_version) 19 | 20 | 21 | def main(): 22 | """ This program demonstrates how to obtain the firmware version for a specific processor. RVR does not need 23 | to be awake for this operation. 24 | """ 25 | 26 | try: 27 | rvr.wake() 28 | 29 | # Give RVR time to wake up 30 | time.sleep(2) 31 | 32 | rvr.get_main_application_version( 33 | handler=get_nordic_main_application_version_handler, 34 | target=SpheroRvrTargets.primary.value 35 | ) 36 | 37 | # Sleep for one second such that RVR has time to send data back 38 | time.sleep(1) 39 | 40 | rvr.get_main_application_version( 41 | handler=get_st_main_application_version_handler, 42 | target=SpheroRvrTargets.secondary.value 43 | ) 44 | 45 | # Sleep for one second such that RVR has time to send data back 46 | time.sleep(1) 47 | 48 | except KeyboardInterrupt: 49 | print('\nProgram terminated with keyboard interrupt.') 50 | 51 | finally: 52 | rvr.close() 53 | 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/__init__.py -------------------------------------------------------------------------------- /projects/keyboard_control/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.python.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | termios = "*" 8 | tty = '*' 9 | 10 | 11 | [dev-packages] 12 | 13 | 14 | [requires] 15 | python_full_version = "3.5.3" -------------------------------------------------------------------------------- /projects/keyboard_control/README.md: -------------------------------------------------------------------------------- 1 | # Keyboard Control 2 | You can find the tutorial for this demo [here]. 3 | 4 | [here]: https://sdk.sphero.com/docs/samples_content/raspberry_pi/python/keyboard_control_sample/ 5 | -------------------------------------------------------------------------------- /projects/keyboard_control/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/keyboard_control/__init__.py -------------------------------------------------------------------------------- /projects/keyboard_control/helper_keyboard_input.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import termios 3 | import tty 4 | 5 | 6 | class KeyboardHelper: 7 | 8 | def __init__(self): 9 | self.__key_code = -1 10 | self.__loop = True 11 | self.__callback = None 12 | self.__original_settings = termios.tcgetattr(sys.stdin) 13 | 14 | @property 15 | def key_code(self): 16 | return self.__key_code 17 | 18 | @key_code.setter 19 | def key_code(self, value): 20 | self.__key_code = value 21 | 22 | def set_callback(self, callback): 23 | self.__callback = callback 24 | 25 | def get_key_continuous(self): 26 | """continuous_get_key records keystrokes in a while loop controlled by the private variable __loop. 27 | 28 | """ 29 | while self.__loop: 30 | self.__get_key() 31 | 32 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.__original_settings) 33 | 34 | def end_get_key_continuous(self): 35 | """end_loop sets the private variable __loop to false so that the while loop from continuous_get_key is stopped. 36 | 37 | """ 38 | self.__loop = False 39 | 40 | def __get_key(self): 41 | tty.setcbreak(sys.stdin) 42 | key_code = ord(sys.stdin.read(1)) 43 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.__original_settings) 44 | self.__callback(key_code) 45 | -------------------------------------------------------------------------------- /projects/rc_rvr/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/rc_rvr/__init__.py -------------------------------------------------------------------------------- /projects/rc_rvr/autostart_rc_rvr.sh: -------------------------------------------------------------------------------- 1 | # This shell script will help with auto-starting the python script 2 | # specified below, after the raspberry-pi boots up. Typically, shell 3 | # sessions start in the /home/pi/ directory, so all path changes are 4 | # relative to that location. 5 | 6 | cd 7 | pipenv run python projects/rc_rvr/rc_async_rvr.py 96666 8 | #scrot 9 | -------------------------------------------------------------------------------- /projects/rc_rvr/debug/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/rc_rvr/debug/__init__.py -------------------------------------------------------------------------------- /projects/rc_rvr/debug/sbus_drive_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) 4 | 5 | import time 6 | from projects.rc_rvr.pysbus.sbus import SBUS 7 | from projects.rc_rvr.pysbus.constants import SBUSConsts 8 | from projects.rc_rvr.pysbus.serial_parser import SerialParser 9 | 10 | tty = sys.argv[1] 11 | baud = sys.argv[2] 12 | 13 | sbus = SBUS( 14 | SerialParser(tty, baud) 15 | ) 16 | sbus.begin() 17 | 18 | channels = [0] * SBUSConsts.NUM_CHANNELS 19 | ch_max = 1811 20 | ch_min = 172 21 | ch_range = ch_max - ch_min 22 | current_heading = 0 23 | current_speed = 0 24 | reverse = False 25 | max_yaw_rate = 180 26 | last_millis = 0 27 | last_aux_value = 0 28 | 29 | 30 | def normalize(ch_value): 31 | ch_diff = ch_max - ch_value 32 | return round(1 - (ch_diff / ch_range),2) 33 | 34 | 35 | def centralize(norm_value): 36 | return 2*norm_value - 1 37 | 38 | 39 | def lerp(v0, v1, t): 40 | return (1 - t) * v0 + t * v1 41 | 42 | 43 | def get_delta_time(): 44 | global last_millis 45 | 46 | current_millis = time.time() 47 | 48 | if last_millis == 0: 49 | last_millis = current_millis 50 | 51 | delta = current_millis - last_millis 52 | last_millis = current_millis 53 | return delta 54 | 55 | 56 | def wrap_heading(heading): 57 | if heading > 0: 58 | heading%360 59 | 60 | def check_aux_toggle(aux_value): 61 | global last_aux_value 62 | toggled = aux_value > 0 and aux_value != last_aux_value 63 | last_aux_value = aux_value 64 | return toggled 65 | 66 | 67 | try: 68 | while True: 69 | payload_ready, failsafe, lost_frame = sbus.read(channels) 70 | 71 | if payload_ready: 72 | norm_thr = normalize(channels[2]) 73 | norm_yaw = normalize(channels[0]) 74 | norm_aux = normalize(channels[4]) 75 | cent_yaw = centralize(norm_yaw) 76 | yaw_rate = max_yaw_rate * cent_yaw 77 | current_heading += yaw_rate * get_delta_time() 78 | current_heading = round(current_heading % 360) 79 | current_speed = round(255 * norm_thr) 80 | reverse_toggled = check_aux_toggle(norm_aux) 81 | if reverse_toggled: 82 | reverse = not reverse 83 | 84 | print("heading: {0}, speed: {1}, reverse: {2}".format(current_heading,current_speed,reverse)) 85 | except: 86 | raise() 87 | finally: 88 | sbus.close() 89 | sys.exit(1) 90 | -------------------------------------------------------------------------------- /projects/rc_rvr/debug/serial_print_bytes.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | from projects.rc_rvr.pysbus.serial_parser import SerialParser 6 | 7 | tty = sys.argv[1] 8 | baud = int(sys.argv[2]) 9 | parser = SerialParser(tty, baud) 10 | parser.begin() 11 | 12 | try: 13 | while True: 14 | byte = parser.parse_raw() 15 | print(byte) 16 | finally: 17 | parser.close() 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /projects/rc_rvr/debug/serial_print_channels.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | from projects.rc_rvr.pysbus.sbus import SBUS 6 | from projects.rc_rvr.pysbus.serial_parser import SerialParser 7 | from projects.rc_rvr.pysbus.constants import SBUSConsts 8 | 9 | tty = sys.argv[1] 10 | baud = sys.argv[2] 11 | sbus = SBUS( 12 | SerialParser(tty, baud) 13 | ) 14 | 15 | channels = [0] * SBUSConsts.NUM_CHANNELS 16 | 17 | sbus.begin() 18 | 19 | try: 20 | while True: 21 | payload_ready, failsafe, lost_frame = sbus.read(channels) 22 | print(channels,"Payload: {0} | Failsafe: {1} | Lost Frame: {2}".format(payload_ready,failsafe,lost_frame)) 23 | finally: 24 | sbus.close() 25 | sys.exit(1) 26 | 27 | -------------------------------------------------------------------------------- /projects/rc_rvr/debug/serial_print_payload.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../'))) 4 | 5 | from projects.rc_rvr.pysbus.serial_parser import SerialParser 6 | from projects.rc_rvr.pysbus.constants import SBUSConsts 7 | 8 | tty = sys.argv[1] 9 | baud = sys.argv[2] 10 | parser = SerialParser(tty, baud) 11 | payload = [0] * SBUSConsts.PAYLOAD_SIZE 12 | 13 | parser.begin() 14 | 15 | try: 16 | while True: 17 | success = parser.parse(payload) 18 | length = SBUSConsts.PAYLOAD_SIZE 19 | hex_string = "[" 20 | for i in range(length): 21 | hex_string += "{0:#0{1}x}".format(payload[i], 4) 22 | if i < length-1: 23 | hex_string += ", " 24 | hex_string += "] {0}".format(success) 25 | print(hex_string) 26 | except: 27 | parser.close() 28 | sys.exit(1) 29 | raise() 30 | -------------------------------------------------------------------------------- /projects/rc_rvr/images/SBUS_RVR_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/rc_rvr/images/SBUS_RVR_Diagram.png -------------------------------------------------------------------------------- /projects/rc_rvr/images/X8R_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/rc_rvr/images/X8R_Diagram.png -------------------------------------------------------------------------------- /projects/rc_rvr/pysbus/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/rc_rvr/pysbus/constants.py: -------------------------------------------------------------------------------- 1 | class SBUSConsts: 2 | 3 | BAUD_RATE = 98000 4 | NUM_CHANNELS = 16 5 | SBUS_HEADER = b'\x0F' 6 | SBUS_FOOTER = b'\x00' 7 | SBUS2_FOOTER = b'\x04' 8 | SBUS2_MASK = b'\x0F' 9 | SBUS_TIMEOUT_MS = 7 10 | PAYLOAD_SIZE = 25 11 | PAYLOAD_MASK = b'\x07FF' 12 | SBUS_LOST_FRAME = b'\x04' 13 | SBUS_FAILSAFE = b'\x08' 14 | DEFAULT_MIN = 171 15 | DEFAULT_MAX = 1811 16 | -------------------------------------------------------------------------------- /projects/rc_rvr/pysbus/sbus.py: -------------------------------------------------------------------------------- 1 | from .constants import SBUSConsts 2 | 3 | 4 | class SBUS: 5 | def __init__(self, parser): 6 | self._parser = parser 7 | self._payload = [0]*SBUSConsts.PAYLOAD_SIZE 8 | 9 | def begin(self): 10 | self._parser.begin() 11 | 12 | def close(self): 13 | self._parser.close() 14 | 15 | def read(self, channels): 16 | 17 | failsafe = False 18 | lost_frame = False 19 | payload_ready = self._parser.parse(self._payload) 20 | 21 | if payload_ready: 22 | if channels is not None: 23 | payload = self._payload 24 | channels[0] = (payload[1] | payload[2] << 8) & 0x07FF 25 | channels[1] = (payload[2] >> 3 | payload[3] << 5) & 0x07FF 26 | channels[2] = (payload[3] >> 6 | payload[4] << 2 | payload[5] << 10) & 0x07FF 27 | channels[3] = (payload[5] >> 1 | payload[6] << 7) & 0x07FF 28 | channels[4] = (payload[6] >> 4 | payload[7] << 4) & 0x07FF 29 | channels[5] = (payload[7] >> 7 | payload[8] << 1 | payload[9] << 9) & 0x07FF 30 | channels[6] = (payload[9] >> 2 | payload[10] << 6) & 0x07FF 31 | channels[7] = (payload[10] >> 5 | payload[11] << 3) & 0x07FF 32 | channels[8] = (payload[12] | payload[13] << 8) & 0x07FF 33 | channels[9] = (payload[13] >> 3 | payload[14] << 5) & 0x07FF 34 | channels[10] = (payload[14] >> 6 | payload[15] << 2 | payload[16] << 10) & 0x07FF 35 | channels[11] = (payload[16] >> 1 | payload[17] << 7) & 0x07FF 36 | channels[12] = (payload[17] >> 4 | payload[18] << 4) & 0x07FF 37 | channels[13] = (payload[18] >> 7 | payload[19] << 1 | payload[20] << 9) & 0x07FF 38 | channels[14] = (payload[20] >> 2 | payload[21] << 6) & 0x07FF 39 | channels[15] = (payload[21] >> 5 | payload[22] << 3) & 0x07FF 40 | 41 | lost_frame = (payload[23] & SBUSConsts.SBUS_LOST_FRAME[0]) > 0 42 | failsafe = (payload[23] & SBUSConsts.SBUS_FAILSAFE[0]) > 0 43 | 44 | return payload_ready, failsafe, lost_frame 45 | 46 | -------------------------------------------------------------------------------- /projects/rc_rvr/pysbus/serial_parser.py: -------------------------------------------------------------------------------- 1 | from serial import Serial 2 | from .constants import SBUSConsts 3 | 4 | 5 | class SerialParser: 6 | def __init__(self, tty, baud): 7 | self._ser = None 8 | self._tty = tty 9 | self._baud = baud 10 | self._parse_state = 0 11 | self._prev_byte = b'\x00' 12 | self._cur_byte = b'\x00' 13 | 14 | def begin(self): 15 | # initialize parse state 16 | self._parse_state = 0 17 | 18 | # begin serial port for SBUS 19 | self._ser = Serial(self._tty) 20 | self._ser.baudrate = self._baud 21 | 22 | def close(self): 23 | self._ser.flush() 24 | self._ser.close() 25 | 26 | def parse_raw(self): 27 | return self._ser.read(1) 28 | 29 | def parse(self, payload): 30 | header = SBUSConsts.SBUS_HEADER[0] 31 | footer = SBUSConsts.SBUS_FOOTER[0] 32 | self._cur_byte = b'\x00' 33 | self._prev_byte = b'\x00' 34 | 35 | # see if serial data is available 36 | while self._ser.readable(): 37 | self._cur_byte = self._ser.read(1) 38 | #print(self._cur_byte) 39 | 40 | if len(self._cur_byte) == 0: 41 | break 42 | 43 | cur_byte = self._cur_byte[0] 44 | prev_byte = self._prev_byte[0] 45 | 46 | # find the header 47 | if self._parse_state == 0: 48 | #print("_parser_state = 0") 49 | if cur_byte == header and prev_byte == footer: 50 | #print("header") 51 | payload[self._parse_state] = cur_byte 52 | self._parse_state += 1 53 | else: 54 | self._parse_state = 0 55 | else: 56 | # strip off the data 57 | if self._parse_state < SBUSConsts.PAYLOAD_SIZE: 58 | payload[self._parse_state] = cur_byte 59 | self._parse_state += 1 60 | 61 | # check the end byte 62 | if self._parse_state == SBUSConsts.PAYLOAD_SIZE: 63 | #print("_parser_state = 25") 64 | if cur_byte == footer: 65 | #print("footer") 66 | self._parse_state = 0 67 | return True 68 | else: 69 | #print("no footer") 70 | self._parse_state = 0 71 | return False 72 | 73 | self._prev_byte = self._cur_byte 74 | 75 | # return false if partial packet 76 | return False 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /projects/rvr_bolt_ir/README.md: -------------------------------------------------------------------------------- 1 | # Bolt RVR Follow 2 | You can find the tutorial for this demo [here]. 3 | 4 | [here]: https://sdk.sphero.com/docs/samples_content/raspberry_pi/python/rvr_bolt_ir_sample/ 5 | -------------------------------------------------------------------------------- /projects/rvr_bolt_ir/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/rvr_bolt_ir/__init__.py -------------------------------------------------------------------------------- /projects/rvr_bolt_ir/rvr_ir_broadcast.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))) 4 | 5 | import time 6 | from sphero_sdk import SpheroRvrObserver 7 | 8 | rvr = SpheroRvrObserver() 9 | green1 = [0, 255, 0] 10 | green2 = [0, 128, 0] 11 | 12 | 13 | def main(): 14 | rvr.wake() 15 | time.sleep(2) 16 | rvr.start_robot_to_robot_infrared_broadcasting(far_code=1,near_code=0) 17 | 18 | try: 19 | while True: 20 | rvr.set_all_leds(0x3FFFFFFF, [color for i in range(10) for color in green1]) 21 | time.sleep(1) 22 | rvr.set_all_leds(0x3FFFFFFF, [color for i in range(10) for color in green2]) 23 | time.sleep(2) 24 | except KeyboardInterrupt: 25 | rvr.stop_robot_to_robot_infrared_broadcasting() 26 | time.sleep(.1) 27 | rvr.close() 28 | 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /projects/ultrasonic_rvr/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | RPi.GPIO = "*" 10 | asyncio = "*" 11 | 12 | [requires] 13 | python_full_version = "3.5.3" 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /projects/ultrasonic_rvr/README.md: -------------------------------------------------------------------------------- 1 | # Ultrasonic RVR 2 | You can find the tutorial for this demo [here]. 3 | 4 | [here]: https://sdk.sphero.com/docs/samples_content/raspberry_pi/python/ultrasonic_rvr_sample/ 5 | -------------------------------------------------------------------------------- /projects/ultrasonic_rvr/images/Mounting_Suggestion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/ultrasonic_rvr/images/Mounting_Suggestion.jpg -------------------------------------------------------------------------------- /projects/ultrasonic_rvr/images/Ultrasonic_RVR_Diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/projects/ultrasonic_rvr/images/Ultrasonic_RVR_Diagram.jpg -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp 2 | requests 3 | websocket-client 4 | pytest-asyncio 5 | pytest 6 | twine 7 | pyserial 8 | pyserial-asyncio -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from io import open 2 | from os import path 3 | from setuptools import setup, find_packages 4 | 5 | 6 | here = path.abspath(path.dirname(__file__)) 7 | 8 | with open(path.join(here, 'README.md'), encoding='utf-8') as f: 9 | long_description = f.read() 10 | 11 | version_dict = {} 12 | with open(path.join(here, 'sphero_sdk', '__version__.py')) as f: 13 | exec(f.read(), version_dict) 14 | print('Version: {}'.format(version_dict)) 15 | 16 | 17 | setup( 18 | author='Sphero', 19 | name='sphero_sdk', 20 | version=version_dict['__version__'], 21 | author_email='sdk@sphero.com', 22 | url='sdk.sphero.com', 23 | description='Provides an API for interfacing with Sphero RVR', 24 | long_description=long_description, 25 | long_description_content_type='text/markdown', 26 | python_requires='>=3.5.3', 27 | packages=find_packages(), 28 | classifiers=[ 29 | 'Programming Language :: Python :: 3', 30 | 'License :: Other/Proprietary License', 31 | 'Operating System :: OS Independent', 32 | ], 33 | install_requires=[ 34 | 'aiohttp == 3.7.4', 35 | 'requests == 2.21.0', 36 | 'websocket-client == 0.54.0', 37 | 'pyserial == 3.4', 38 | 'pyserial-asyncio == 0.4', 39 | 'twine == 1.13.0' 40 | ] 41 | ) 42 | -------------------------------------------------------------------------------- /sphero_sdk/__version__.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.0.0' 2 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/client/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/client/dal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/client/dal/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/client/firmware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/client/firmware/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/client/firmware/rvr_fw_check_async.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | from sphero_sdk import SpheroRvrTargets 4 | from sphero_sdk.common.firmware.cms_fw_check_base import CmsFwCheckBase 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | 9 | class RvrFwCheckAsync(CmsFwCheckBase): 10 | 11 | def __init__(self): 12 | CmsFwCheckBase.__init__(self) 13 | self.__rvr = self 14 | 15 | async def _check_rvr_fw(self): 16 | """Checks the RVR's firmware on the Nordic and ST chips against the CMS, if an internet connection is available. 17 | """ 18 | root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../')) 19 | 20 | # Have more than 7 days elapsed since last check? 21 | if not self._should_run_fw_check(): 22 | return 23 | 24 | if not self._network_available(): 25 | self._write_timestamp() 26 | return 27 | 28 | print('Checking RVR firmware versions...') 29 | 30 | rvr_nordic_version = await self.__rvr.get_main_application_version(target=SpheroRvrTargets.primary.value, timeout=3) 31 | rvr_st_version = await self.__rvr.get_main_application_version(target=SpheroRvrTargets.secondary.value, timeout=3) 32 | 33 | if rvr_nordic_version is None or rvr_st_version is None: 34 | logger.error('Unable to retrieve Nordic and/or ST versions from RVR.') 35 | return 36 | 37 | print('Checking CMS firmware versions...') 38 | cms_nordic_version = await self._get_cms_fw_version(self._nordic_cms_url) 39 | logger.info('CMS Nordic Version:', cms_nordic_version) 40 | 41 | cms_st_version = await self._get_cms_fw_version(self._st_cms_url) 42 | logger.info('CMS ST Version:', cms_st_version) 43 | 44 | # Proceed only if both versions are acquired from the CMS. 45 | if cms_nordic_version is not None or cms_st_version is not None: 46 | 47 | # Record timestamp of this check 48 | self._write_timestamp() 49 | 50 | warning_displayed = self._check_update_available(rvr_nordic_version, cms_nordic_version) 51 | 52 | # Check ST version only if Nordic version check return false 53 | if not warning_displayed: 54 | self._check_update_available(rvr_st_version, cms_st_version) 55 | 56 | print('Firmware check complete.') 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/client/toys/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/client/toys/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/config/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/controls/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/controls/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/__init__.py: -------------------------------------------------------------------------------- 1 | from .handler.api_sphero_handler import Handler 2 | from .handler.sphero_handler_base import SpheroHandlerBase 3 | from .parser.api_sphero_parser import Parser 4 | from .port.serial_sphero_port import SerialSpheroPort 5 | from .toy.sphero_toy_base import SpheroToyBase 6 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/conftest.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/handler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/handler/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/handler/sphero_handler_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SpheroHandlerBase: 5 | 6 | __slots__ = ['_port'] 7 | 8 | def __init__(self, port): 9 | 10 | self._port = port 11 | 12 | async def message_handler(self, msg): 13 | 14 | raise NotImplementedError 15 | 16 | async def error_handler(self, msg): 17 | 18 | raise NotImplementedError 19 | 20 | @staticmethod 21 | def from_type_string(type_string): 22 | 23 | if type_string == 'api': 24 | import handler.api_sphero_handler as api_sphero_handler 25 | return api_sphero_handler.Handler 26 | if type_string == 'shell': 27 | return NotImplementedError 28 | else: 29 | raise AttributeError 30 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/parser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/parser/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/parser/sphero_parser_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SpheroParserBase: 5 | """The base class for the parser.""" 6 | __slots__ = ['_message_handler', '_error_handler'] 7 | 8 | def __init__(self, message_handler, error_handler): 9 | """The base class for the parser. 10 | 11 | Args: 12 | message_handler (func): A function that takes a Message as input. 13 | error_handler (func): A function that takes a malformed message in the form of a bytearray as input. 14 | """ 15 | self._message_handler = message_handler 16 | self._error_handler = error_handler 17 | 18 | def feed(self, data): 19 | """Feeds the Parser new raw byte data. 20 | 21 | Calls message_handler and error_handler. 22 | 23 | Raises: 24 | NotImplementedError: This function must be implemented by the class that inherits from SpheroParserBase. 25 | """ 26 | raise NotImplementedError 27 | 28 | def set_message_handler(self, message_handler): 29 | """Sets this parser's message handler. 30 | 31 | Args: 32 | message_handler (func): A function that takes a Message as input. 33 | 34 | """ 35 | self._message_handler = message_handler 36 | 37 | def set_error_handler(self, error_handler): 38 | """Sets this parser's error handler. 39 | 40 | Args: 41 | error_handler (func): A function that takes a malformed message in the form of a bytearray as input. 42 | 43 | """ 44 | self._error_handler = error_handler 45 | 46 | @staticmethod 47 | def from_type_string(type_string): 48 | """ 49 | Gives the parser class corresponding to the input type_string. 50 | 51 | Args: 52 | type_string (str): A string indicating the desired type of parser. 53 | Currently only 'api' and 'shell' types are supported, but 'shell' must be implemented by the inheriting 54 | class. 55 | 56 | Raises: 57 | NotImplementedError: Support for the 'shell' type is not currently implemented. 58 | AttributeError: Raised if the input type_string is not supported. 59 | 60 | Returns: 61 | The parser class corresponding to the input type_string. 62 | 63 | """ 64 | if type_string == 'api': 65 | import parser.api_sphero_parser as api_sphero_parser 66 | return api_sphero_parser.Parser 67 | if type_string == 'shell': 68 | raise NotImplementedError 69 | else: 70 | raise AttributeError 71 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/port/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/port/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/port/serial_sphero_port.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import asyncio 4 | import serial 5 | import logging 6 | from serial_asyncio import SerialTransport 7 | from .sphero_port_base import SpheroPortBase 8 | 9 | logger = logging.getLogger(__name__) 10 | 11 | 12 | class SerialSpheroPort(SpheroPortBase, asyncio.Protocol): 13 | __slots__ = ['__loop', '__transport'] 14 | 15 | def __init__(self, loop, port_id, 16 | parser_factory, handler_factory, dev, baud=115200): 17 | """Class that moves bytes from a serial port to a Parser 18 | and messages to that serial port (typically from the Handler) 19 | 20 | Args: 21 | loop: asyncio event loop 22 | port_id: an ID for the port, used mostly by Handler 23 | parser_factory: Parser Class 24 | handler_factory: Handler Class 25 | dev: Serial Device 26 | baud: Serial Device baud rate 27 | """ 28 | SpheroPortBase.__init__(self, port_id, parser_factory, handler_factory) 29 | asyncio.Protocol.__init__(self) 30 | self.__loop = loop 31 | ser = serial.Serial(dev, baud) 32 | self.__transport = SerialTransport(loop, self, ser) 33 | 34 | def connection_made(self, transport): 35 | 36 | self.__transport = transport 37 | 38 | def connection_lost(self, exc): 39 | pass 40 | 41 | def send(self, msg): 42 | """Send a Message instance to the port 43 | 44 | Args: 45 | msg (Message): Instance of Message 46 | 47 | """ 48 | data = msg.serialise() 49 | logger.debug('Writing serial data: [{}]'.format(', '.join('0x{:02x}'.format(x) for x in data))) 50 | self.__transport.write(data) 51 | 52 | def data_received(self, data): 53 | logger.debug('Reading serial data: [{}]'.format(', '.join('0x{:02x}'.format(x) for x in data))) 54 | self._parser.feed(data) 55 | 56 | def pause_writing(self): 57 | pass 58 | 59 | def resume_writing(self): 60 | """Not implemented 61 | 62 | """ 63 | pass 64 | 65 | def eof_received(self): 66 | pass 67 | 68 | def close(self): 69 | self.__transport.close() 70 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/port/sphero_port_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from ..parser.sphero_parser_base import SpheroParserBase 4 | from ..handler.sphero_handler_base import SpheroHandlerBase 5 | 6 | 7 | class SpheroPortBase: 8 | __slots__ = ['_port_id', '_handler', '_parser'] 9 | 10 | def __init__(self, port_id, parser_factory, handler_factory): 11 | 12 | if not issubclass(parser_factory, SpheroParserBase): 13 | raise TypeError 14 | if not issubclass(handler_factory, SpheroHandlerBase): 15 | raise TypeError 16 | self._port_id = port_id 17 | self._handler = handler_factory(self) 18 | self._parser = parser_factory(self.handler.message_handler, 19 | self.handler.error_handler) 20 | 21 | @property 22 | def port_id(self): 23 | 24 | return self._port_id 25 | 26 | @port_id.setter 27 | def port_id(self, ID): 28 | 29 | self._port_id = ID 30 | 31 | @property 32 | def handler(self): 33 | 34 | return self._handler 35 | 36 | def send(self, msg): 37 | 38 | raise NotImplementedError 39 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/service/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/service/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/service/api_robo_service.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from service.robo_service_base import RoboServiceBase 4 | from service.robo_service_channel import RoboServiceChannel 5 | 6 | 7 | class Service(RoboServiceBase): 8 | __MAXIMUM_NODE_COUNT = 16 9 | __MAXIMUM_PORT_COUNT = 16 10 | 11 | def __init__(self): 12 | RoboServiceBase.__init__(self) 13 | self.nodes = RoboServiceChannel(self.__MAXIMUM_NODE_COUNT) 14 | self.ports = RoboServiceChannel(self.__MAXIMUM_PORT_COUNT) 15 | 16 | def register_as_node(self): 17 | node_id = self.nodes.register() 18 | return node_id 19 | 20 | def unregister_node(self, ID): 21 | self.nodes.unregister(ID) 22 | 23 | def register_port(self, portDict): 24 | pass 25 | 26 | def unregister_port(self, ID): 27 | self.ports.unregister(ID) 28 | 29 | def list_registered_ports(self): 30 | return [str(self.ports.used)] 31 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/service/robo_service_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class RoboServiceBase: 5 | def __init__(self): 6 | return 7 | 8 | def register_as_node(self): 9 | raise NotImplementedError 10 | 11 | def unregister_node(self, node_id): 12 | raise NotImplementedError 13 | 14 | def register_port(self): 15 | raise NotImplementedError 16 | 17 | def unregister_port(self): 18 | raise NotImplementedError 19 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/service/robo_service_channel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class RoboServiceChannel: 5 | '''A Channel is a generic class used for interfacing with the 6 | Sphero Communication Protocol 7 | ''' 8 | def __init__(self, max_count): 9 | self.__used = [] 10 | self.__instances = {} 11 | self.__available = list(range(1, max_count)) 12 | 13 | @property 14 | def used(self): 15 | return self.__used 16 | 17 | @property 18 | def instances(self): 19 | return self.__instances 20 | 21 | def register(self, instance=None): 22 | try: 23 | channel_id = self.__available.pop() 24 | self.__instances[channel_id] = instance 25 | self.__used.append(channel_id) 26 | return channel_id 27 | except IndexError: 28 | return 0 29 | 30 | def unregister(self, channel_id): 31 | try: 32 | self.__used.remove(channel_id) 33 | self.__instances.pop(channel_id) 34 | self.__available.append(channel_id) 35 | except: 36 | raise 37 | -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/toy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/asyncio/server/toy/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/asyncio/server/toy/sphero_toy_base.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python333 2 | 3 | class SpheroToyBase: 4 | def __init__(self, port, node_id): 5 | self._port = port 6 | self._node_id = node_id 7 | 8 | @property 9 | def port(self): 10 | return self._port 11 | 12 | @property 13 | def node_id(self): 14 | return self._node_id 15 | -------------------------------------------------------------------------------- /sphero_sdk/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/client/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/client/dal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/client/dal/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/client/dal/sphero_dal_base.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | class SpheroDalBase: 5 | def __init__(self): 6 | self.request_error_responses_only = False 7 | 8 | def close(self): 9 | raise NotImplementedError 10 | 11 | def send_command(self, did, cid, seq, target, timeout=None, inputs=[], outputs=[]): 12 | raise NotImplementedError 13 | 14 | def on_command(self, did, cid, target, handler, timeout=None, outputs=[]): 15 | raise NotImplementedError 16 | -------------------------------------------------------------------------------- /sphero_sdk/common/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/commands/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/commands/api_and_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x10-api_and_shell.json 4 | # Device ID: 0x10 5 | # Device Name: api_and_shell 6 | # Timestamp: 08/20/2020 @ 02:17:14.020679 (UTC) 7 | 8 | from sphero_sdk.common.enums.api_and_shell_enums import CommandsEnum 9 | from sphero_sdk.common.devices import DevicesEnum 10 | from sphero_sdk.common.parameter import Parameter 11 | from sphero_sdk.common.sequence_number_generator import SequenceNumberGenerator 12 | 13 | 14 | def echo(data, target, timeout): 15 | return { 16 | 'did': DevicesEnum.api_and_shell, 17 | 'cid': CommandsEnum.echo, 18 | 'seq': SequenceNumberGenerator.get_sequence_number(), 19 | 'target': target, 20 | 'timeout': timeout, 21 | 'inputs': [ 22 | Parameter( 23 | name='data', 24 | data_type='uint8_t', 25 | index=0, 26 | value=data, 27 | size=16 28 | ), 29 | ], 30 | 'outputs': [ 31 | Parameter( 32 | name='data', 33 | data_type='uint8_t', 34 | index=0, 35 | size=16, 36 | ), 37 | ] 38 | } 39 | 40 | 41 | def generate_api_error(error, target, timeout): 42 | return { 43 | 'did': DevicesEnum.api_and_shell, 44 | 'cid': CommandsEnum.generate_api_error, 45 | 'seq': SequenceNumberGenerator.get_sequence_number(), 46 | 'target': target, 47 | 'timeout': timeout, 48 | 'inputs': [ 49 | Parameter( 50 | name='error', 51 | data_type='uint8_t', 52 | index=0, 53 | value=error, 54 | size=1 55 | ), 56 | ], 57 | } 58 | -------------------------------------------------------------------------------- /sphero_sdk/common/commands/connection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x19-peer_connection.json 4 | # Device ID: 0x19 5 | # Device Name: connection 6 | # Timestamp: 08/20/2020 @ 02:17:13.931960 (UTC) 7 | 8 | from sphero_sdk.common.enums.connection_enums import CommandsEnum 9 | from sphero_sdk.common.devices import DevicesEnum 10 | from sphero_sdk.common.parameter import Parameter 11 | from sphero_sdk.common.sequence_number_generator import SequenceNumberGenerator 12 | 13 | 14 | def get_bluetooth_advertising_name(target, timeout): 15 | return { 16 | 'did': DevicesEnum.connection, 17 | 'cid': CommandsEnum.get_bluetooth_advertising_name, 18 | 'seq': SequenceNumberGenerator.get_sequence_number(), 19 | 'target': target, 20 | 'timeout': timeout, 21 | 'outputs': [ 22 | Parameter( 23 | name='name', 24 | data_type='std::string', 25 | index=0, 26 | size=1, 27 | ), 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /sphero_sdk/common/devices.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Timestamp: 08/20/2020 @ 02:17:14.224708 (UTC) 4 | 5 | from enum import IntEnum 6 | from sphero_sdk.common import commands 7 | from sphero_sdk.common.helpers import text_to_pascal_case 8 | 9 | 10 | class DevicesEnum(IntEnum): 11 | api_and_shell = 0x10 12 | system_info = 0x11 13 | power = 0x13 14 | drive = 0x16 15 | sensor = 0x18 16 | connection = 0x19 17 | io = 0x1A 18 | 19 | 20 | def get_device_path_by_did(did): 21 | device_name = DevicesEnum(did).name 22 | return text_to_pascal_case(device_name) 23 | 24 | 25 | def get_command_path_by_cid(did, cid): 26 | device_name = DevicesEnum(did).name 27 | 28 | command_name = eval( 29 | 'commands.{}.CommandsEnum({}).name'.format( 30 | device_name, 31 | cid 32 | ) 33 | ) 34 | 35 | return text_to_pascal_case(command_name) 36 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/enums/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/enums/api_and_shell_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x10-api_and_shell.json 4 | # Device ID: 0x10 5 | # Device Name: api_and_shell 6 | # Timestamp: 08/20/2020 @ 02:17:14.021821 (UTC) 7 | 8 | from enum import IntEnum 9 | 10 | 11 | __all__ = ['ApiResponseCodesEnum'] 12 | 13 | 14 | class CommandsEnum(IntEnum): 15 | echo = 0x00 16 | generate_api_error = 0x09 17 | 18 | 19 | class ApiResponseCodesEnum(IntEnum): 20 | api_success = 0 21 | bad_did = 1 22 | bad_cid = 2 23 | not_yet_implemented = 3 24 | restricted = 4 25 | bad_data_length = 5 26 | failed = 6 27 | bad_data_value = 7 28 | busy = 8 29 | bad_tid = 9 30 | target_unavailable = 10 31 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/colors_enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class Colors(Enum): 5 | red = [0xFF, 0x00, 0x00] 6 | green = [0x00, 0xFF, 0x00] 7 | blue = [0x00, 0x00, 0xFF] 8 | off = [0x00, 0x00, 0x00] 9 | white = [0xFF, 0xFF, 0xFF] 10 | yellow = [0xFF, 0x90, 0x00] 11 | purple = [0xFF, 0x00, 0xFF] 12 | orange = [0xFF, 0x20, 0x00] 13 | pink = [0xFF, 0x66, 0xB2] 14 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/connection_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x19-peer_connection.json 4 | # Device ID: 0x19 5 | # Device Name: connection 6 | # Timestamp: 08/20/2020 @ 02:17:13.933060 (UTC) 7 | 8 | from enum import IntEnum 9 | 10 | 11 | class CommandsEnum(IntEnum): 12 | get_bluetooth_advertising_name = 0x05 13 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/infrared_codes_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from enum import Enum 4 | 5 | 6 | class InfraredCodes(Enum): 7 | """ InfraredCodes are the enums for the InfraredHelpers class 8 | """ 9 | 10 | zero = 0 11 | one = 1 12 | two = 2 13 | three = 3 14 | four = 4 15 | five = 5 16 | six = 6 17 | seven = 7 18 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/io_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x1A-user_io.json 4 | # Device ID: 0x1A 5 | # Device Name: io 6 | # Timestamp: 08/20/2020 @ 02:17:13.936353 (UTC) 7 | 8 | from enum import IntEnum 9 | 10 | 11 | __all__ = ['SpecdrumsColorPaletteIndiciesEnum'] 12 | 13 | 14 | class CommandsEnum(IntEnum): 15 | set_all_leds = 0x1A 16 | get_active_color_palette = 0x44 17 | set_active_color_palette = 0x45 18 | get_color_identification_report = 0x46 19 | load_color_palette = 0x47 20 | save_color_palette = 0x48 21 | release_led_requests = 0x4E 22 | 23 | 24 | class SpecdrumsColorPaletteIndiciesEnum(IntEnum): 25 | default = 0 26 | midi = 1 27 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/number_bounds_enums.py: -------------------------------------------------------------------------------- 1 | from enum import IntEnum 2 | 3 | 4 | class IntBounds(IntEnum): 5 | int_32_min = -2147483648 6 | int_32_max = 2147483647 7 | int_64_min = -9223372036854775808 8 | int_64_max = 9223372036854775807 9 | 10 | 11 | class UintBounds(IntEnum): 12 | uint_8_max = 255 13 | uint_16_max = 65535 14 | uint_32_max = 4294967295 15 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/power_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x13-power.json 4 | # Device ID: 0x13 5 | # Device Name: power 6 | # Timestamp: 08/20/2020 @ 02:17:13.914447 (UTC) 7 | 8 | from enum import IntEnum 9 | 10 | 11 | __all__ = ['BatteryVoltageStatesEnum', 12 | 'BatteryVoltageReadingTypesEnum', 13 | 'AmplifierIdsEnum'] 14 | 15 | 16 | class CommandsEnum(IntEnum): 17 | sleep = 0x01 18 | wake = 0x0D 19 | get_battery_percentage = 0x10 20 | get_battery_voltage_state = 0x17 21 | will_sleep_notify = 0x19 22 | did_sleep_notify = 0x1A 23 | enable_battery_voltage_state_change_notify = 0x1B 24 | battery_voltage_state_change_notify = 0x1C 25 | get_battery_voltage_in_volts = 0x25 26 | get_battery_voltage_state_thresholds = 0x26 27 | get_current_sense_amplifier_current = 0x27 28 | 29 | 30 | class BatteryVoltageStatesEnum(IntEnum): 31 | unknown = 0 32 | ok = 1 33 | low = 2 34 | critical = 3 35 | 36 | 37 | class BatteryVoltageReadingTypesEnum(IntEnum): 38 | calibrated_and_filtered = 0 39 | calibrated_and_unfiltered = 1 40 | uncalibrated_and_unfiltered = 2 41 | 42 | 43 | class AmplifierIdsEnum(IntEnum): 44 | left_motor = 0 45 | right_motor = 1 46 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/sphero_rvr_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Toy Name: Sphero RVR 4 | # Prefix: RV 5 | # Timestamp: 08/20/2020 @ 02:17:14.203024 (UTC) 6 | 7 | from enum import IntEnum 8 | 9 | 10 | class SpheroRvrTargets(IntEnum): 11 | primary = 1 12 | secondary = 2 13 | 14 | 15 | class SpheroRvrLedBitmasks(IntEnum): 16 | right_headlight_red = 0x00000001 17 | right_headlight_green = 0x00000002 18 | right_headlight_blue = 0x00000004 19 | left_headlight_red = 0x00000008 20 | left_headlight_green = 0x00000010 21 | left_headlight_blue = 0x00000020 22 | left_status_indication_red = 0x00000040 23 | left_status_indication_green = 0x00000080 24 | left_status_indication_blue = 0x00000100 25 | right_status_indication_red = 0x00000200 26 | right_status_indication_green = 0x00000400 27 | right_status_indication_blue = 0x00000800 28 | battery_door_rear_red = 0x00001000 29 | battery_door_rear_green = 0x00002000 30 | battery_door_rear_blue = 0x00004000 31 | battery_door_front_red = 0x00008000 32 | battery_door_front_green = 0x00010000 33 | battery_door_front_blue = 0x00020000 34 | power_button_front_red = 0x00040000 35 | power_button_front_green = 0x00080000 36 | power_button_front_blue = 0x00100000 37 | power_button_rear_red = 0x00200000 38 | power_button_rear_green = 0x00400000 39 | power_button_rear_blue = 0x00800000 40 | left_brakelight_red = 0x01000000 41 | left_brakelight_green = 0x02000000 42 | left_brakelight_blue = 0x04000000 43 | right_brakelight_red = 0x08000000 44 | right_brakelight_green = 0x10000000 45 | right_brakelight_blue = 0x20000000 46 | undercarriage_white = 0x40000000 47 | -------------------------------------------------------------------------------- /sphero_sdk/common/enums/system_info_enums.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is automatically generated! 3 | # Source File: 0x11-system_info.json 4 | # Device ID: 0x11 5 | # Device Name: system_info 6 | # Timestamp: 08/20/2020 @ 02:17:13.949883 (UTC) 7 | 8 | from enum import IntEnum 9 | 10 | 11 | class CommandsEnum(IntEnum): 12 | get_main_application_version = 0x00 13 | get_bootloader_version = 0x01 14 | get_board_revision = 0x03 15 | get_mac_address = 0x06 16 | get_stats_id = 0x13 17 | get_processor_name = 0x1F 18 | get_sku = 0x38 19 | get_core_up_time_in_milliseconds = 0x39 20 | -------------------------------------------------------------------------------- /sphero_sdk/common/exceptions.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | class BaseError(Exception): 4 | pass 5 | 6 | class BadConnection(BaseError): 7 | pass 8 | 9 | class BadResponse(BaseError): 10 | def __init__(self): 11 | pass 12 | 13 | def __str__(self): 14 | return '''The Response returned from the Server suggests a mismatch between library versions''' 15 | -------------------------------------------------------------------------------- /sphero_sdk/common/firmware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/firmware/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/helpers.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | def text_to_pascal_case(text, remove_spaces=True): 5 | if text is None or len(text) == 0: 6 | return '' 7 | 8 | if remove_spaces: 9 | return text.replace('_', ' ').replace('-', ' ').title().replace(' ', '') 10 | 11 | return text.replace('_', ' ').replace('-', ' ').title() 12 | 13 | 14 | def normalize(value, in_min, in_max, out_min, out_max): 15 | return ( ((value - in_min)/(in_max - in_min)) * (out_max - out_min)) + out_min 16 | -------------------------------------------------------------------------------- /sphero_sdk/common/log_level.py: -------------------------------------------------------------------------------- 1 | class LogLevel: 2 | Silent = 0 3 | Errors = 1 4 | Debug_Verbose = 2 5 | -------------------------------------------------------------------------------- /sphero_sdk/common/parameter.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | class Parameter: 5 | __slots__ = ['__name', '__data_type', '__index', '__size', '__value'] 6 | 7 | def __init__(self, *, name, data_type, index, size, value=None): 8 | self.__name = name 9 | self.__data_type = data_type 10 | self.__index = index 11 | self.__size = size 12 | self.__value = value 13 | 14 | @property 15 | def name(self): 16 | return self.__name 17 | 18 | @property 19 | def data_type(self): 20 | return self.__data_type 21 | 22 | @property 23 | def index(self): 24 | return self.__index 25 | 26 | @property 27 | def size(self): 28 | return self.__size 29 | 30 | @property 31 | def value(self): 32 | return self.__value 33 | 34 | @value.setter 35 | def value(self, new_value): 36 | self.__value = new_value 37 | -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/__init__.py: -------------------------------------------------------------------------------- 1 | from .api_sphero_protocol import ErrorCode, Flags 2 | from .api_sphero_message import Message 3 | from .api_sphero_header import Header -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/api_sphero_protocol.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from enum import IntEnum 4 | import logging 5 | import struct 6 | 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | 11 | class Flags(IntEnum): 12 | packet_is_response = 1 13 | packet_requests_response = 2 14 | packet_requests_response_if_error = 4 15 | packet_is_activity = 8 16 | packet_has_target = 16 17 | packet_has_source = 32 18 | packet_unused_flag_bit = 64 19 | packet_has_more_flags = 128 20 | 21 | 22 | class ErrorCode(IntEnum): 23 | success = 0x00 24 | bad_did = 0x01 25 | bad_cid = 0x02 26 | not_yet_implemented = 0x03 27 | restricted = 0x04 28 | bad_data_length = 0x05 29 | failed = 0x06 30 | bad_data_value = 0x07 31 | busy = 0x08 32 | bad_tid = 0x09 33 | target_unavailable = 0x0A 34 | 35 | 36 | class Pack: 37 | @staticmethod 38 | def int8(value): 39 | return struct.pack('b', value) 40 | 41 | @staticmethod 42 | def uint8(value): 43 | return struct.pack('B', value) 44 | 45 | @staticmethod 46 | def uint16(value): 47 | return struct.pack('>H', value) 48 | 49 | @staticmethod 50 | def int16(value): 51 | return struct.pack('>h', value) 52 | 53 | @staticmethod 54 | def int32(value): 55 | return struct.pack('>i', value) 56 | 57 | @staticmethod 58 | def uint32(value): 59 | return struct.pack('>I', value) 60 | 61 | @staticmethod 62 | def float32(value): 63 | return struct.pack('>f', value) 64 | 65 | @staticmethod 66 | def bool8(value): 67 | return struct.pack('>?', value) 68 | 69 | 70 | class Unpack: 71 | @staticmethod 72 | def int8(buf): 73 | return struct.unpack('b', buf[:1])[0] 74 | 75 | @staticmethod 76 | def uint8(buf): 77 | return struct.unpack('B', buf[:1])[0] 78 | 79 | @staticmethod 80 | def uint16(buf): 81 | return struct.unpack('>H', buf[:2])[0] 82 | 83 | @staticmethod 84 | def int16(buf): 85 | return struct.unpack('>h', buf[:2])[0] 86 | 87 | @staticmethod 88 | def int32(buf): 89 | return struct.unpack('>i', buf[:4])[0] 90 | 91 | @staticmethod 92 | def uint32(buf): 93 | return struct.unpack('>I', buf[:4])[0] 94 | 95 | @staticmethod 96 | def float32(buf): 97 | return struct.unpack('>f', buf[:4])[0] 98 | 99 | @staticmethod 100 | def bool8(buf): 101 | return struct.unpack('>?', buf[:1])[0] 102 | 103 | @staticmethod 104 | def string(buf): 105 | size = len(buf) 106 | fmt = '{}s'.format(size) 107 | string_bytes = struct.unpack(fmt, buf[:size])[0] 108 | return string_bytes.decode('utf-8') -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/sphero_async_url.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from sphero_sdk.common.protocol.sphero_url_base import SpheroUrlBase 4 | 5 | 6 | class SpheroAsyncUrl(SpheroUrlBase): 7 | def __init__(self, scheme, domain, port): 8 | """A SpheroAsyncUrl takes the form: 9 | scheme://domain:port/stream 10 | 11 | """ 12 | SpheroUrlBase.__init__( 13 | self, 14 | scheme, 15 | domain, 16 | port, 17 | 'stream' 18 | ) 19 | -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/sphero_command_url.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from sphero_sdk.common.protocol.sphero_url_base import SpheroUrlBase 4 | 5 | 6 | class SpheroCommandUrl(SpheroUrlBase): 7 | def __init__(self, scheme, domain, port, 8 | version, toy, device_name, command_name, target): 9 | '''A SpheroApiUrl takes the form: 10 | scheme://domain:port/api/version/toy/device_name/command_name/target 11 | 12 | ''' 13 | SpheroUrlBase.__init__( 14 | self, 15 | scheme, 16 | domain, 17 | port, 18 | 'api', 19 | 'v1.0', 20 | device_name, 21 | command_name, 22 | str(target) 23 | ) 24 | -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/sphero_header_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SpheroHeaderBase: 5 | def __init__(self): 6 | pass 7 | 8 | @staticmethod 9 | def from_buffer(buf): 10 | raise NotImplementedError 11 | 12 | def serialise(self): 13 | raise NotImplementedError 14 | -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/sphero_message_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SpheroMessageBase: 5 | def __init__(self): 6 | pass 7 | 8 | @staticmethod 9 | def from_buffer(buf): 10 | raise NotImplementedError 11 | 12 | def serialise(self): 13 | raise NotImplementedError 14 | -------------------------------------------------------------------------------- /sphero_sdk/common/protocol/sphero_url_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SpheroUrlBase: 5 | def __init__(self, scheme, domain, port, *paths): 6 | '''A Base URL takes form: 7 | scheme://domain:port/path 8 | 9 | Example: 10 | http://localhost:8080/api/v0.6.2/rvr/system_info/get_main_application_version/1 11 | ''' 12 | self.__scheme = scheme 13 | self.__domain = domain 14 | self.__port = port 15 | self.__paths = paths 16 | 17 | def __str__(self): 18 | url_string = '://'.join(( 19 | self.__scheme, 20 | '/'.join(( 21 | ':'.join(( 22 | self.__domain, 23 | str(self.__port) 24 | )), 25 | '/'.join(path for path in self.__paths) 26 | )) 27 | )) 28 | return url_string 29 | -------------------------------------------------------------------------------- /sphero_sdk/common/rvr_streaming_services.py: -------------------------------------------------------------------------------- 1 | class RvrStreamingServices: 2 | color_detection = 'ColorDetection' 3 | ambient_light = 'AmbientLight' 4 | quaternion = 'Quaternion' 5 | imu = 'IMU' 6 | accelerometer = 'Accelerometer' 7 | gyroscope = 'Gyroscope' 8 | locator = 'Locator' 9 | velocity = 'Velocity' 10 | speed = 'Speed' 11 | core_time = 'CoreTime' 12 | encoders = 'Encoders' 13 | -------------------------------------------------------------------------------- /sphero_sdk/common/sensors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/common/sensors/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/common/sensors/sensor_stream_attribute.py: -------------------------------------------------------------------------------- 1 | class SensorStreamAttribute: 2 | 3 | __slots__ = ['__name', '__min_value', '__max_value', '__number_type'] 4 | 5 | def __init__(self, name, min_value, max_value): 6 | self.__name = name 7 | self.__min_value = min_value 8 | self.__max_value = max_value 9 | 10 | # Determine if this attribute is a float or int 11 | test_value = self.__min_value + self.__max_value 12 | self.__number_type = int if isinstance(test_value, int) else float 13 | 14 | @property 15 | def name(self): 16 | return self.__name 17 | 18 | @property 19 | def minimum_value(self): 20 | return self.__min_value 21 | 22 | @property 23 | def maximum_value(self): 24 | return self.__max_value 25 | 26 | @property 27 | def number_type(self): 28 | return self.__number_type 29 | -------------------------------------------------------------------------------- /sphero_sdk/common/sequence_number_generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | class SequenceNumberGenerator: 5 | """This class generates a 0-255 sequence number for outgoing API packets. 6 | """ 7 | 8 | __sequence_number = 0 9 | 10 | @staticmethod 11 | def get_sequence_number(): 12 | num = SequenceNumberGenerator.__sequence_number 13 | num += 1 14 | if num > 255: 15 | num = 0 16 | SequenceNumberGenerator.__sequence_number = num 17 | return num 18 | -------------------------------------------------------------------------------- /sphero_sdk/observer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/client/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/client/dal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/client/dal/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/client/dal/observer_parser.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import logging 4 | from sphero_sdk.common.protocol.api_sphero_message import Message 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | 9 | class ObserverParser: 10 | __slots__ = ['__buf', '__dispatcher'] 11 | 12 | def __init__(self, dispatcher): 13 | self.__buf = bytearray() 14 | self.__dispatcher = dispatcher 15 | 16 | def feed(self, data): 17 | self.__buf += data 18 | logger.debug('Appending bytes: [{}]'.format(', '.join('0x{:02x}'.format(x) for x in self.__buf))) 19 | self.__read() 20 | 21 | def __read(self): 22 | # Discard Any bytes received before a SOP is received 23 | try: 24 | start_index = self.__buf.index(Message.START_OF_PACKET) 25 | self.__buf = self.__buf[start_index:] 26 | except Exception as e: 27 | self.__buf.clear() 28 | return 29 | 30 | # Try to Parse a Message 31 | msg = None 32 | skip_future_reads = False 33 | try: 34 | msg = Message.from_buffer(self.__buf) 35 | except ValueError: # Missing SOP, EOP 36 | logger.debug('Packet missing SOP/EOP!') 37 | skip_future_reads = True 38 | return 39 | except AttributeError: # Bad Packet 40 | logger.error('Invalid packet received!') 41 | error_buf = (self.__buf[self.__buf.index(Message.START_OF_PACKET): 42 | self.__buf.index(Message.END_OF_PACKET) + 1]) 43 | self.__handle_error(error_buf) 44 | else: 45 | skip_future_reads = True 46 | logger.info('Parsing packet complete: %s', msg) 47 | self.__dispatcher.handle_message(msg) 48 | finally: 49 | # Regardless of outcome, we should rerun _read until no SOP or EOP 50 | if not skip_future_reads: 51 | self.__read() 52 | 53 | # Consume the bytes from the buffer 54 | try: 55 | logger.debug('Consuming bytes in packet.') 56 | self.__buf = self.__buf[self.__buf.index(Message.END_OF_PACKET) + 1:] 57 | except Exception: 58 | self.__buf.clear() 59 | 60 | def __handle_error(self, buf): 61 | ''' 62 | try: 63 | asyncio.ensure_future(self._error_handler(buf)) 64 | except TypeError: 65 | logger.warning('Parser Fed without Error Handler Set') 66 | raise 67 | except Exception as e: 68 | logger.critical('Exception in Error Handler: {}'.format(e)) 69 | raise 70 | ''' 71 | pass 72 | 73 | -------------------------------------------------------------------------------- /sphero_sdk/observer/client/dal/serial_observer_port.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import logging 4 | from threading import Thread 5 | from queue import Queue 6 | from serial import Serial 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | 11 | class SerialObserverPort: 12 | def __init__(self, parser, port_id, baud): 13 | """SerialObserverPort is responsible opening, writing, and reading bytes coming from the UART port. 14 | 15 | Args: 16 | parser (ObserverParser): Used to parse bytes read from the port. 17 | port_id (str): id for the serial port. 18 | baud (int): Baud rate. 19 | """ 20 | self.__parser = parser 21 | self.__ser = Serial(port_id, baud) 22 | self.__running = True 23 | self.__write_queue = Queue() 24 | self.__serial_thread = Thread(name='serial_thread', target=self.__serial_rw) 25 | self.__serial_thread.start() 26 | 27 | def close(self): 28 | """Closes the port and joins the thread managing reading and writing. 29 | 30 | """ 31 | logger.info('Read/Write thread joining.') 32 | self.__running = False 33 | self.__serial_thread.join() 34 | logger.info('Closing serial port.') 35 | self.__ser.close() 36 | 37 | def send(self, message): 38 | """Enqueues a Message instance which will be serialized and written to the port at a later time. 39 | 40 | Args: 41 | message (Message): Instance of a Message object 42 | 43 | """ 44 | self.__write_queue.put(message.serialise()) 45 | 46 | def __serial_rw(self): 47 | while self.__running: 48 | self.__write_bytes() 49 | self.__read_bytes() 50 | 51 | def __read_bytes(self): 52 | bytes_in_waiting = self.__ser.in_waiting 53 | if bytes_in_waiting > 0: 54 | data = self.__ser.read(bytes_in_waiting) 55 | logger.debug('Read {} bytes: [{}]'.format(bytes_in_waiting, ', '.join('0x{:02x}'.format(x) for x in data))) 56 | self.__parser.feed(data) 57 | 58 | def __write_bytes(self): 59 | if not self.__write_queue.empty(): 60 | data = self.__write_queue.get() 61 | logger.debug('Writing bytes: [{}]'.format(', '.join('0x{:02x}'.format(x) for x in data))) 62 | self.__ser.write(data) 63 | -------------------------------------------------------------------------------- /sphero_sdk/observer/client/firmware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/client/firmware/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/client/toys/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/client/toys/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/config/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/controls/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/controls/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/controls/sensor_control_observer.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from sphero_sdk import SpheroRvrTargets 3 | from sphero_sdk.common.sensors.sensor_streaming_control import SensorStreamingControl 4 | 5 | logger = logging.getLogger(__name__) 6 | 7 | 8 | class SensorControlObserver(SensorStreamingControl): 9 | def __init__(self, rvr): 10 | SensorStreamingControl.__init__(self, rvr) 11 | 12 | def _configure_streaming_service(self, token_id, configuration, processor): 13 | self._rvr.configure_streaming_service( 14 | token=token_id, 15 | configuration=configuration, 16 | target=processor 17 | ) 18 | 19 | def _add_streaming_service_data_notify_handler(self, processor): 20 | handler = self.__nordic_streaming_data_handler \ 21 | if processor == SpheroRvrTargets.primary.value \ 22 | else self.__st_streaming_data_handler 23 | 24 | self._rvr.on_streaming_service_data_notify( 25 | handler=handler, 26 | target=processor 27 | ) 28 | 29 | def _start_streaming_service(self, interval, processor): 30 | self._rvr.start_streaming_service( 31 | period=interval, 32 | target=processor 33 | ) 34 | 35 | def _stop_streaming_service(self, processor): 36 | self._rvr.stop_streaming_service( 37 | target=processor 38 | ) 39 | 40 | def _stop_and_clear_streaming_service(self, processor): 41 | self._rvr.clear_streaming_service( 42 | target=processor 43 | ) 44 | 45 | def __nordic_streaming_data_handler(self, response): 46 | self.__dispatch_user_callback(SpheroRvrTargets.primary.value, response) 47 | 48 | def __st_streaming_data_handler(self, response): 49 | self.__dispatch_user_callback(SpheroRvrTargets.secondary.value, response) 50 | 51 | def __dispatch_user_callback(self, processor, response): 52 | response_dictionary = SensorStreamingControl._process_streaming_response(self, processor, response) 53 | if response_dictionary is None: 54 | logger.error('Streaming response dictionary processed from streaming data is null!') 55 | return 56 | 57 | sensors_in_response = response_dictionary.keys() 58 | for sensor_name in self.enabled_sensors: 59 | if sensor_name in sensors_in_response: 60 | handler = self._sensor_handlers[sensor_name] 61 | handler(response_dictionary) 62 | -------------------------------------------------------------------------------- /sphero_sdk/observer/events/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sphero-inc/sphero-sdk-raspberrypi-python/cc82b799a70e583773a93b33c151a64ddce727c3/sphero_sdk/observer/events/__init__.py -------------------------------------------------------------------------------- /sphero_sdk/observer/events/event_dispatcher.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from sphero_sdk.common.protocol import ErrorCode 3 | from sphero_sdk.observer.observer_base import Observer 4 | 5 | logger = logging.getLogger(__name__) 6 | 7 | 8 | class EventDispatcher: 9 | def __init__(self): 10 | pass 11 | 12 | def handle_message(self, message): 13 | """Uses the message did and cid properties as keys to check if a handler exists in the master dictionary of 14 | registered handlers. If an entry is found, an event is raised. 15 | 16 | Args: 17 | message (Message): Used to look for registered handlers for this message. 18 | 19 | """ 20 | 21 | if message.err is not None and message.err is not ErrorCode.success: 22 | raise Exception(message.err.name) 23 | 24 | if message.is_response: 25 | key = (message.did, message.cid, message.seq, message.source) 26 | logger.debug( 27 | 'Looking for entries with key (CID: 0x{:02x}, DID: 0x{:02x}, Seq: {}, Source: {})'.format( 28 | key[0], key[1], key[2], key[3] 29 | ) 30 | ) 31 | else: 32 | key = (message.did, message.cid, message.source) 33 | logger.debug( 34 | 'Looking for entries with key (CID: 0x{:02x}, DID: 0x{:02x}, Source: {})'.format( 35 | key[0], key[1], key[2] 36 | ) 37 | ) 38 | 39 | for observer in Observer.observers: 40 | if key in observer.handlers: 41 | handler, outputs = observer.handlers[key] 42 | 43 | if message.is_response: 44 | observer.unregister_handler(key) 45 | 46 | logger.debug('Entry found, dispatching!') 47 | self.__dispatch_event(handler, outputs, message) 48 | break 49 | 50 | def __dispatch_event(self, handler, outputs, message): 51 | if len(outputs) > 0: 52 | logger.debug('Unpacking output from message') 53 | response_dictionary = {} 54 | for param in sorted(outputs, key=lambda x: x.index): 55 | response_dictionary[param.name] = message.unpack( 56 | param.data_type, 57 | count=param.size 58 | ) 59 | logger.debug('Invoking callback with response data: {}'.format(response_dictionary)) 60 | handler(response_dictionary) 61 | else: 62 | logger.debug('No outputs expected, invoking callback.') 63 | handler() 64 | 65 | -------------------------------------------------------------------------------- /sphero_sdk/observer/observer_base.py: -------------------------------------------------------------------------------- 1 | class Observer: 2 | observers = [] 3 | 4 | def __init__(self): 5 | self.observers.append(self) 6 | self.handlers = {} 7 | 8 | def _register_handler(self, handler, **kwargs): 9 | did = kwargs['did'] 10 | cid = kwargs['cid'] 11 | seq = kwargs.get('seq', -1) 12 | target = kwargs['target'] 13 | 14 | if seq != -1: 15 | key = (did, cid, seq, target) 16 | else: 17 | key = (did, cid, target) 18 | 19 | outputs = [] 20 | if 'outputs' in kwargs: 21 | outputs = kwargs['outputs'] 22 | 23 | self.handlers[key] = (handler, outputs) 24 | 25 | def unregister_handler(self, key): 26 | """Removes entry with specified key values from handlers dictionary. 27 | 28 | Args: 29 | key (tuple): a tuple key that contains did, cid, seq (if command is not an async), and target 30 | """ 31 | self.handlers.pop(key, None) 32 | -------------------------------------------------------------------------------- /tools/pi-uart-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ask whether the UART is enabled, and give the user a chance to fix it if needed. 4 | while true; do 5 | read -ep $'By default, the RVR SDK uses the UART on /dev/ttys0 to communicate with RVR.\nDo you have Serial Port enabled and Serial Shell disabled in Raspberry Pi Configuration?\n(y/n):' yn 6 | case $yn in 7 | [Yy]* ) exit;; 8 | [Nn]* ) 9 | read -p $'Would you like to open the command line raspi-config tool now to change these settings?\nYou can do this at any time with \'sudo raspi-config\'\n(y/n):' yn2 10 | case $yn2 in 11 | [Yy]* ) sudo raspi-config; break;; 12 | [Nn]* ) exit;; 13 | * ) echo "Please answer yes or no.";; 14 | esac 15 | break;; 16 | * ) echo "Please answer yes or no.";; 17 | esac 18 | done -------------------------------------------------------------------------------- /tools/pipenv-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt-get update -y 4 | 5 | sudo apt-get install -y make \ 6 | build-essential \ 7 | llvm \ 8 | libssl-dev \ 9 | bzip2 \ 10 | zlib1g-dev \ 11 | libbz2-dev \ 12 | libreadline6 \ 13 | libreadline-dev \ 14 | libsqlite3-dev \ 15 | libncurses5-dev \ 16 | libncursesw5-dev \ 17 | xz-utils \ 18 | tk-dev \ 19 | libffi-dev \ 20 | liblzma-dev 21 | 22 | pip3 install pipenv 23 | 24 | # Reload ~/.profile. In recent Raspberry Pi OS releases, this automatically includes $HOME/.local/bin in the path once it exists. 25 | source ~/.profile 26 | 27 | # Test whether pipenv is in the system path now 28 | if ! which pipenv ; then 29 | # It's not in the path, so we should add it on boot 30 | printf "\n# Add $HOME/.local/bin to PATH for pipenv.\n# This was automatically added by Sphero RVR SDK first-time-setup.sh\n" >> ~/.profile 31 | printf "PATH=\"\$HOME/.local/bin:\$PATH\"\n" >> ~/.profile 32 | 33 | # Apply the ~/.profile update to this session as well 34 | source ~/.profile 35 | fi 36 | 37 | python3 -m pipenv --python /usr/bin/python3.7 38 | 39 | # The cryptography package is a dependency, but for some reason pipenv can't always install it correctly, so we'll use pip instead. ¯\_(ツ)_/¯ 40 | python3 -m pipenv run pip install cryptography 41 | 42 | python3 -m pipenv install 43 | 44 | # Provide an opportunity to correct the UART settings if needed. 45 | ./pi-uart-check.sh 46 | --------------------------------------------------------------------------------