{"id":33430532,"url":"https://github.com/russmac/python_rover_robot","last_synced_at":"2026-04-12T19:57:24.380Z","repository":{"id":46118135,"uuid":"277411643","full_name":"russmac/python_rover_robot","owner":"russmac","description":"A multi-threaded ultrasonic \u0026 magnetic navigating rover.","archived":false,"fork":false,"pushed_at":"2024-04-06T01:28:03.000Z","size":2784,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-06T15:54:34.451Z","etag":null,"topics":["opencv","raspberry-pi","robot","robotics","rover"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/russmac.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-06T01:07:01.000Z","updated_at":"2024-04-06T02:07:21.000Z","dependencies_parsed_at":"2022-09-03T22:02:36.717Z","dependency_job_id":null,"html_url":"https://github.com/russmac/python_rover_robot","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/russmac/python_rover_robot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russmac%2Fpython_rover_robot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russmac%2Fpython_rover_robot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russmac%2Fpython_rover_robot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russmac%2Fpython_rover_robot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/russmac","download_url":"https://codeload.github.com/russmac/python_rover_robot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russmac%2Fpython_rover_robot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286079811,"owners_count":27282121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-24T02:00:07.096Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opencv","raspberry-pi","robot","robotics","rover"],"created_at":"2025-11-24T08:05:34.177Z","updated_at":"2025-11-24T08:05:35.016Z","avatar_url":"https://github.com/russmac.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Python Rover Robot\nThis is a Python Rover project which currently uses 3 ultrasonic sensors and a magnetometer to navigate. Its a fairly specific thing I used as a learning tool perhaps someone may find as a useful example. \n\nIt is capable of streaming basic OpenCV image processing done onboard at roughly 700ms frequency (very slow), helper scripts are included to calibrate a lens for image processing. \n\nIt does not navigate by the houghline detection it performs due to the capability being limited by the visual frequency. Of roughly 2.5fps which would be impacted further by additional processing. \n\nI am currently developing a rover on a far more capable vehicle platform and compute platform.\n\n![Robot](/doc/robot.png)\n\nThe lens calibration seen in this stream is atrocious. This was a 30s job. ROI cropping failed accordingly.\nFor best results move rover and hold still for a second in each position. You will get a proper square feed.\nFor perfect results, symmetrically align all your pictures along a predefined schema and take single stable shots.\n(need to refactor calibration_capture to wait for keypress then capture)\n\n![Stream](/doc/stream.png)\n\n## Supported OS.\nRaspbian Stable/Raspberry Pi OS Bookworm\n```\nRaspberry Pi OS with desktop\n\n    Release date: March 15th 2024\n    System: 64-bit\n    Kernel version: 6.6\n    Debian version: 12 (bookworm)\n    Size: 1,105MB\n```\n\n## Instructions\nInstall everything in Linuxfile with apt\n```\nfor package in `cat Linuxfile`; do\napt -y install $package\ndone\n```\n\nCreate a venv for the files, The drivers used require root access.\n```python\ncd ~\ngit clone https://github.com/russmac/python_rover robot\ncd robot \u0026\u0026 python3 -m venv venv\n. venv/bin/activate\npip3 install -r requirements.txt\n```\nEdit instance/config.py\n```\ncamera_selection = \"picamera_v2_vga\"\n\ncamera_configurations = {\n    \"picamera_v2_vga\": {\n        \"id\": \"picamera_v2_vga\",\n        \"fisheye\": True,\n        \"canny_auto_levels\": True,\n        \"stream_canny\": False,\n        \"camera_x\": 640,\n        \"camera_y\": 480,\n        \"canny_params\": {\"upper\": 160,\n                         \"lower\": 40},\n        \"hough_params\": {\"minLineLength\": 100,\n                         \"maxLineGap\": 5,\n                         \"probabilistic\": True},\n    },\n}\n\nmotor_configuration = {\n    \"enable_pin\": 17,\n    \"slew_pin\": 27,\n    \"left\": {\n        \"pwm_pin\": 13,\n        \"forward_pin\": 6,\n        \"reverse_pin\": 5,\n        \"state_flag_pin\": 11,\n    },\n    \"right\": {\n        \"pwm_pin\": 12,\n        \"forward_pin\": 20,\n        \"reverse_pin\": 16,\n        \"state_flag_pin\": 26,\n    },\n}\n\n# Tweaking these values can dramatically effect navigation.\nMy specific rover can competently navigate around chair legs and furniture under and rarely if ever gets stuck. \n\nultrasonic_configuration = {\n    \"ussl_pin\": 7,\n    \"ussc_pin\": 25,\n    \"ussr_pin\": 8,\n    # How many cm is considered clear from center sensor\n    \"clear_distance_c\": 35,\n    # How many cm is considered clear from side sensors\n    \"clear_distance_side\": 35,\n    # What cm is a clear path.\n    \"path_distance\": 48,\n}\n\n\n```\nAnd to start up\n```python\npython3 start_threads.py\n```\n\nThe app looks for a camera calibration in ./config matching the camera id in instance/config.py , The same config is used in the calibration helper scripts so the files should be correctly named.\n\nThe robot will concurrently look for a locally saved Bosch BNO055 calibration, Whichever parts are present will be used, You will be prompted to calibrate the rest. \n\nhttps://www.youtube.com/watch?v=Bw0WuAyGsnY\n\nThis can \"glitch\" in that the sensor rejects the saved calibration due to some validation.\nAt time calibration can seem like magic and some commenters noted dancing with the sensor (robot) is more effective.\nI have not tried this. \n\n```\nroot@media-desktop:/robot/python_rover_robot# python3 threaded.py \nWARNING | Orientation | Expecting value: line 1 column 1 (char 0)\nINFO | Orientation | Calibrate now!\nINFO | Orientation | \nGyroscope: 0\nAcceleromter: 0\nMagnetometer: 0\n\n...\n\nFollow calibration video instructions\n\n...\n\nINFO | Orientation | \nGyroscope: 3\nAcceleromter: 1\nMagnetometer: 3\n\nINFO | Orientation | Fully calibrated\nINFO | Orientation | Switching to config mode\nINFO | Orientation | Saving to cache: GYR_OFFSET_X_LSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: GYR_OFFSET_X_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: GYR_OFFSET_Y_LSB\nINFO | Orientation | 3\nINFO | Orientation | Saving to cache: GYR_OFFSET_Y_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: GYR_OFFSET_Z_LSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: GYR_OFFSET_Z_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: MAG_OFFSET_X_LSB\nINFO | Orientation | 24\nINFO | Orientation | Saving to cache: MAG_OFFSET_X_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: MAG_OFFSET_Y_LSB\nINFO | Orientation | 86\nINFO | Orientation | Saving to cache: MAG_OFFSET_Y_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: MAG_OFFSET_Z_LSB\nINFO | Orientation | 215\nINFO | Orientation | Saving to cache: MAG_OFFSET_Z_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: ACC_OFFSET_X_LSB\nINFO | Orientation | 200\nINFO | Orientation | Saving to cache: ACC_OFFSET_X_MSB\nINFO | Orientation | 255\nINFO | Orientation | Saving to cache: ACC_OFFSET_Y_LSB\nINFO | Orientation | 22\nINFO | Orientation | Saving to cache: ACC_OFFSET_Y_MSB\nINFO | Orientation | 0\nINFO | Orientation | Saving to cache: ACC_OFFSET_Z_LSB\nINFO | Orientation | 227\nINFO | Orientation | Saving to cache: ACC_OFFSET_Z_MSB\nINFO | Orientation | 255\nINFO | Orientation | Saving to cache: ACC_RADIUS_LSB\nINFO | Orientation | 232\nINFO | Orientation | Saving to cache: ACC_RADIUS_MSB\nINFO | Orientation | 3\nINFO | Orientation | Saving to cache: MAG_RADIUS_LSB\nINFO | Orientation | 189\nINFO | Orientation | Saving to cache: MAG_RADIUS_MSB\nINFO | Orientation | 2\nINFO | Orientation | Configured calibration cache\nINFO | Orientation | Switching back to NDOF mode\nINFO | Driver | Sensor data populated\nWARNING | Driver | I think its clear... driving\n```\n\n\n## Using the calibration tools \nhttps://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html#\n\n1. Run ./calibration_capture.py on your Rpi and take your captures, This process is really important to get right as without an undistorted image machine vision algorithms are ineffective.\n2. You need to rsync or scp ~/robot/calibration to ~/samples/calibration on your local machine when you're done.\n3. You then run calibrate.py, it will show you progress as it attempts to find chessboard corners.\n4. Successfully chess-boarded calibration images will be saved (and drawn on) under samples/results , Failures will be deleted from samples/calibration.\n5. Numpy binary arrays will be saved under samples/config , You need to SCP or Rsync these to ~/robot/config (including sample_image.jpg).\n\n## Viewing the camera feed\nNavigate to http://robot:8000 where robot is your robots IP address.\n\n## Hardware list\n##### Microcontroller\n- Raspberry Pi 4B (used in my project)\n\nOther options; \n- Raspberry Pi 3B\n- Nvidia Jetson Developer kit\n- Nvidia Xavier NX\n\n##### Platform\n- DFRobot \"Devastator\" platform (any two motor rover will do)\n- Polulu Dual MC33926 Motor Driver\n\n##### Navigation\n\n- 3x DFRobot URM37 v5.0 Ultrasonic rangefinders. (these are fairly inaccurate but do the job)\n- Adafruit ADS 1015 12 bit ADC\n- DFRobot 10DOF AHRS (Bosch BNO055 \u0026 BMP280)\n\n##### Vision\n- PiCamera V2\n\n##### Power\n- Adafruit PowerBoost 1000 Charger 5v 1A\n- Polymer Lithium Ion Battery (LiPo) 3.7V 6000mAh\n- 3A USB plug pack for charging / power supply while operating.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frussmac%2Fpython_rover_robot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frussmac%2Fpython_rover_robot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frussmac%2Fpython_rover_robot/lists"}