Giter Club home page Giter Club logo

sights's Introduction

Sights Logo

Build status GitHub license GitHub issues GitHub forks

Sights is a complete teleoperation interface for a wide range of robotics hardware.

Screenshot of the interface

Features

  • All Sights configuration is done through a single configuration file which can be edited visually from within the interface, even if the Sights service is stopped or has crashed
  • A powerful and extensible modular sensor system
    • A sensor plugin system to allow new sensors to be added with ease
    • Sensor wrapper classes that can use existing Python libraries to access sensors over I2C. No need to write libraries specifically for Sights
    • User can define which sensors are enabled, where they go on the interface, how they are displayed, and what type of graph they are displayed on
    • Sensors can be displayed on multiple graphs, or two sensors can be displayed on the same graph
    • Includes sensor plugins for:
      • Thermal cameras
      • Ambient and IR temperature sensors
      • Distance (Time of Flight) sensors
      • CO2 and TVOC sensors
      • System memory usage
      • CPU usage and temperature
      • System uptime
      • Disk space usage
    • Includes sensor graphs:
      • Line graph (supports multiple sensors on a single graph)
      • Percentage circle chart
      • Thermal camera with overlay features
      • Text box (with optional uptime display box)
  • An extremely powerful interface that allows the operator to control every aspect of the robot
    • Up to four video camera streams through Motion
    • Integrated tabbed SSH console allowing advanced access to the underlying OS
    • Full gamepad and keyboard support
    • Full visual configuration file editor and an advanced text-based editor
    • Configuration file management allowing you to swap the active configuration file at runtime, even if the Sights service is stopped or has crashed
    • Keep track of old revisions of your config file to easily restore to a previous version
    • Light and dark themes
    • Ability for the operator to safely shut down or restart the robot through the interface
  • Motor control with support for both Dynamixel AX-series servos and DC motors using a Sabertooth motor controller
    • Intuitive gamepad and keyboard control directly from the interface
    • Ability to assign different Dynamixel IDs to different groups, representing parts of the robot (such as left and right side servos)
    • Support for adding additional motor connection handlers in a similar manner to sensors
  • Built entirely using open protocols and open-source software.

All configuration for Sights is done in the .json files within the configs/ directory, which can be edited through the web interface. The active configuration file can be changed through the interface at any time, even if the Sights service is stopped or has crashed. This gives you the ability to fix any configuration issue without physical access to the robot.

Requirements

Officially supported operating systems:

  • Ubuntu 18.04 LTS Bionic Beaver
  • Ubuntu 20.04 LTS Focal Fossa
  • Debian 10 Buster
  • Raspbian 10 Buster

Python >= 3.6 is required. All the officially supported distributions ship with Python 3.6+.

Installation

To install on a robot, just download and run the installer as root:

wget https://raw.githubusercontent.com/sightsdev/sights/master/install.sh
chmod +x install.sh
sudo ./install.sh

Through the installer you can do a complete install, or just install and setup individual parts of the software suite.

SIGHTS installer

Detected OS: ubuntu bionic
Using a supported OS

1) Complete Install           6) Setup ShellInABox
2) Install Dependencies       7) Setup Supervisor
3) Install Sights Software    8) Enable I2C
4) Setup Apache               9) Update
5) Setup Motion              10) Detect IPs
Enter a number (1-10) or q to quit:

For manual installation see docs/manual_install.md.

Then visit the robot's IP address in any web browser on the same network.

Documentation

Documentation can be found at https://sights.js.org.

It can also be accessed through the Sights interface itself, even without an internet connection.

Contributing

If you have an idea, suggestion or bug report for the Sights project, or want to make a contribution of your own, we'd love to work with you to make it happen! Take a look at our contributing page for more information.

sights's People

Contributors

brucbr avatar cavallialexander avatar conr86 avatar matt-w99 avatar williamsjack avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

sights's Issues

Current config indicator does not always reflect actual loaded config

Describe the bug
The current config indicator (#current_config) should show the actual loaded config that the host is currently running, instead it shows the config that will be the current config when the service is restarted. This happens when setting a new active config file.

This is just a result of the current implementation of config file handling.

Steps To Reproduce
Steps to reproduce the behaviour:

  1. Select another config file from the config selector
  2. Click the enable button to set it as active
  3. Click 'Refresh List' button

Expected behaviour
The current config indicator (#current_config) should show the actual loaded config that the host is currently running. Instead it shows the config that will be the current config when the service is restarted.

Host/Robot Information:

  • OS: Ubuntu
  • OS Version: Bionic Beaver 18.04.3 LTS
  • SIGHTS Software versions [On the interface, in the settings modal, on the about tab]
    • SIGHTSRobot version: v0.12-14-g7b2649c
    • SIGHTSInterface version: v0.15-13-g47cb8f5

Controller (where you access the interface from. Remove this section if you weren't using the interface):

  • OS: Windows 10
  • OS Version: Build 18362
  • Browser: Edge Dev
  • Browser version: 80

Additional context
The current loaded config filename used to be passed through the WebSocket during the initial message. If we add this again, we use this instead of the XML-RPC call to get the active config, it will accurately show the actual loaded config. I'd suggest calling it loaded_config to avoid confusion with active_config which might not be one and the same.

Sensor data server needs to send non-important data less often

At the moment, non-important data such as uptime is sent way too many times per second. Some stuff needs to be sent this fast, like the thermal camera, but some of it does not.

A simple method would be to only send uptime every x ticks, but a time-based solution would probably be better. After all, uptime only needs to be sent every second, since it's measured in seconds.

Implement methods for sending and receiving config files

Is your feature request related to a problem? Please describe.
The config is currently sent to the interface and saved to SIGHTSRobot via websocket, while the rest of config management (deleting, switching) is handled by the Supervisor extension.

Describe the solution you'd like
Replace websocket config management with xmlrpc requests using Supervisor. This allows users to completely manage their config files while the robot is offline.

Most logic should be able to be moved from SIGHTSRobot with little to no changes. This includes automatic backups.
Automatic backup restoration is not required. Since the config file can be edited while the SIGHTSRobot service is stopped, a better workflow would be to attempt to load the config file, fail, and let the user edit it rather than deleting the broken config and going to a previous working version.

Related:
#34
https://github.com/SFXRescue/SIGHTSInterface/issues/34

Implement better exception handling in ServoParty

At the moment, check out what happens when something goes catastrophically wrong.

Error in connection handler
Traceback (most recent call last):
  File "/home/sart/SARTRobot/servo_party.py", line 68, in move_raw
    self.sc.set_speed(Servo.LEFT_FRONT, left)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 1482, in set_speed
    self.write_data(dynamixel_id, pk.MOVING_SPEED, params)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 216, in write_data
    self.send(inst_packet)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 102, in send
    self.flush()      # TODO: make a (synchronous) flush_in() and flush_out() instead
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 161, in flush
    self.serial_connection.flushInput()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialutil.py", line 584, in flushInput
    self.reset_input_buffer()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 595, in reset_input_buffer
    termios.tcflush(self.fd, termios.TCIFLUSH)
termios.error: (5, 'Input/output error')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/websockets/server.py", line 152, in handler
    yield from self.ws_handler(self, path)
  File "/home/sart/SARTRobot/control_receiver.py", line 179, in main
    self.message_handler(buf)
  File "/home/sart/SARTRobot/control_receiver.py", line 137, in message_handler
    self.keyboard_handler(control, value)
  File "/home/sart/SARTRobot/control_receiver.py", line 71, in keyboard_handler
    self.servo_party.move(speed, speed)
  File "/home/sart/SARTRobot/servo_party.py", line 123, in move
    self.move_raw(left, right)
  File "/home/sart/SARTRobot/servo_party.py", line 74, in move_raw
    self.crash(left, right)
  File "/home/sart/SARTRobot/servo_party.py", line 93, in crash
    self.close()
  File "/home/sart/SARTRobot/servo_party.py", line 56, in close
    self.stop();
  File "/home/sart/SARTRobot/servo_party.py", line 47, in stop
    self.sc.set_speed(1, 0)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 1482, in set_speed
    self.write_data(dynamixel_id, pk.MOVING_SPEED, params)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 216, in write_data
    self.send(inst_packet)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 102, in send
    self.flush()      # TODO: make a (synchronous) flush_in() and flush_out() instead
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 161, in flush
    self.serial_connection.flushInput()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialutil.py", line 584, in flushInput
    self.reset_input_buffer()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 595, in reset_input_buffer
    termios.tcflush(self.fd, termios.TCIFLUSH)
termios.error: (5, 'Input/output error')

I have a crash handler function which tries to stop the servos and close the connection, but that just throws another exception. So, what do we do?

Possibly, in the crash handler, rather than attempt to stop the servos and close the connection, we try to reopen it, and then stop the servos.

Just an idea.

Implement the ability to make new config files from interface

Currently the only way to make a new config file is through the SSH interface. A simple New Config file button would suffice (with a popup text box or something to set the name). Perhaps also a rename button actually, now that I think about it.

This will likely require additional functions in supervisor_sart_config which is cool. Probably a createConfig(filename) and renameConfig(oldfilename, new_filename) function.

Accent Colour Theming

Is your feature request related to a problem? Please describe.
SARTRobot and SARTInterface were renamed to SIGHTS to debrand from S.A.R.T. to welcome more external collaboration on the project. We the maintainers have been discussing a basic theming system to allow users to set the accent colour of their installation to be more in line with their brand or team without having to edit the CSS directly.

Describe the solution you'd like
Allow users to set an accent colour. The accent colour should be used for:

  • The word "SIGHTS" in the page title
  • The loading spinner (which is actually still yellow even in the S.A.R.T. theme)
  • The no-feed stream images
  • The circle.css based percentage circle graphs
    Anything else deemed appropriate by the developer implementing accent colour theming.

Describe alternatives you've considered
Forcing everyone to use our specific brand of S.A.R.T. International Orange, specifically #FF5A00

Additional context
Will need to add an option to the config for accent colour, probably in a new section under "Interface" called "Theme". This includes updating the config schema and config documentation. Set the default colour code to #FF5A00 for obvious reasons.
Add a CSS class to all elements that can be themed (e.g. accent-colour)
When the config file is received, set the accent colour to the code provided by the config in the config. Use jquery to select all elements with accent-colour and apply the new style.

Something to extend this: Store the last used colour code in a cookie so that a config file doesn't have to be loaded to set the accent colour.

Disabling sensors causes robot service to crash on start

Disabling a sensor in the config editor will omit the frequency property from the saved config. This causes an error when re/starting the robot:

2019-11-06 01:08:57,984 INFO __main__: Starting manager process
2019-11-06 01:08:57,985 INFO __main__: Using config file: /opt/sart/SARTRobot/configs/virtual.json
2019-11-06 01:08:57,988 INFO __main__: PID 3130
Traceback (most recent call last):
  File "manager.py", line 106, in <module>
    while(manager.run()):
  File "manager.py", line 45, in run
    self.sensor_process = SensorStream(1, self.sensor_pipe, self.config_file)
  File "/opt/sart/SARTRobot/sensor_stream.py", line 39, in __init__
    sensor.load_config(self.config['sensors'])
  File "/opt/sart/SARTRobot/sensor_wrapper.py", line 16, in load_config
    self.frequency = config[self._key]['frequency']
KeyError: 'frequency'

Update demo mode features

At the time of writing, there have been 87 commits to master since the last non-trivial revision to demo mode, with more flowing in every day. Demo mode is falling behind, meaning potential users and contributors may come to the incorrect conclusion that SIGHTS software is unstable or buggy.

It may be a good idea to include a dismissable alert in demo mode explaining that bugs may exist in demo mode that do not exist in the full version of SIGHTS.

Key areas:

  • Visual config editor
  • Bootoast notifications - some wording may be different between demo and normal modes
  • Don't attempt requests to /RPC2 while in demo mode
  • Display mock data for service and message logs
  • Set service state to "running"

Small optional additions/extras:

  • Increment uptime counter
  • Generate random data (every second?) for CPU temp, CO2 level and TVOC level
  • Slowly decrease charge level
  • Populate config selector with dummy configs (doesn't need to be selectable)
  • Disconnect dummy websockets if the user shuts down or restarts the robot
  • Update keyboard speed indicator when keys are pressed

Part of this process will include stripping out https://picsum.photos and completing issue SFXRescue/SIGHTSInterface#23.

This issue should be completed before the announcement of SIGHTS v1.0 release, and the demo at https://www.sfxrescue.com/interfacedemo/ updated.

Implement SARTRobot as a Service (SaaS)

With multiple paid tiers to appeal to enterprise customers.
Just kidding.
We do, however, need the SARTRobot software (specifically manager.py) to run as a service on Linux systems. Exactly how this is to be implemented is undecided and unknown.
Ideally, the software can be managed in typical Linux fashion with commands such as:
sudo service sart restart

This will also tie into #10 regarding logging, as sudo service sart status should print the logs from the current run, unless I'm mistaken.

Interface pagination

Is your feature request related to a problem? Please describe.
At the moment, we have two 'views' on the interface, the camera view and the sensor view. This is naturally limiting already, and with the modular sensor rewrite happening, it's only going to get worse.

Cameras / sensors view is a bit confusing, since the cameras view also has sensors. And sensors view usually has a camera.

Describe the solution you'd like
A paginated interface. With the upcoming modular sensor interface update, we'll likely add an option within the config file to set order and position of sensor graphs. I'd like to extend this to be very flexible and allow for multiple pages.

Slight side note here, but I'm thinking on a controller, the select button will act as an 'interface' button. While holding select, any button presses will not be sent to the host, but instead allow for controlling the interface itself.

Hold select and press the left or right bumper buttons to change page on a controller. If using a mouse and keyboard, there should be small arrows on each side of the page, or similar. Perhaps use the arrow keys on the keyboard as well (and don't use them to control the robot, leaving that to the WASD keys exclusively).

Describe alternatives you've considered
Alternatively, there are a few options:

  • Scrolling views instead of pagination
  • Keep the two page view and opt for a "primary" and "secondary" view system. Essentially limit it to two pages that can be toggled with the select button, as we have now, but allow for any content on any page.

Add a help section to the interface

We're slowly writing up documentation for the project, and it would be great for that to be easily accessible through the interface. It would be akin to the legacy interface's help page.

At the moment the documentation is in the SIGHTSRobot repository. We'll need to figure out how to let the SIGHTSInterface repository parse it easily. Solved with Apache aliases.

Current proxy directives causing screenshot download issues.

Describe the bug
Screenshot downloads fail. Browser says "Failed - Server problem" and I get a 502 proxy error when visiting http://192.168.1.201/stream/1/current. Apache error log is equally unhelpful, "specific information not available":

[Wed Nov 20 16:10:18.864577 2019] [proxy_http:error] [pid 2287:tid 140147651761920] (20014)Internal error (specific information not available): [client 192.168.1.211:62223] AH01102: error reading status line from remote server localhost:8081     
[Wed Nov 20 16:10:18.864650 2019] [proxy:error] [pid 2287:tid 140147651761920] [client 192.168.1.211:62223] AH00898: Error reading from remote server returned by /stream/1/current

This is an odd issue considering screenshot downloads were working just a few days ago. Perhaps a recent Ubuntu or Apache patch has changed something?

Current proxy directives in SIGHTSInterface.conf:

    ProxyPass "/stream" "http://localhost:8081/"
    ProxyPassReverse "/stream" "http://localhost:8081/"

image

The two downloads on the right (pictured above) were done with the trailing forward slash on the remote url argument of the proxy directives.
The slash was removed, Apache restarted, and the downloads were attempted again, resulting in the two successes shown on the left.

Proposed new proxy directives (trailing forward slash removed):

    ProxyPass "/stream" "http://localhost:8081"
    ProxyPassReverse "/stream" "http://localhost:8081"

I'm creating this issue to see if other people can reproduce this behaviour.
Regardless of whether you are able to reproduce, try removing the trailing forward slash in the proxy directives in the SIGHTSInterface.conf site. Please report the results for both tests.

Steps To Reproduce
Steps to reproduce the behaviour:

  1. Click the screenshot button on a running stream

Expected behaviour
The screenshot should download.

Host/Robot Information:

  • OS: Ubuntu
  • OS Version: 18.04.3 LTS

Controller (where you access the interface from. Remove this section if you weren't using the interface):

  • OS: Windows 10
  • OS Version Build 18362
  • Browser: Chrome
  • Browser version: 78.0.3904.97

Remove legacy manager kill / restart scripts code

At the moment, the old kill and restart code is still in the main.py script.

Now that we're using Supervisor we no longer need it, and the buttons that use those methods have been removed.

We need to ensure that removing this code doesn't break the signal handler and leave zombie processes.

Implement a proper log system

At the moment, there is no logging system other than printing to the console.

We need a proper log system, I've been looking at loguru which looks excellent. We just need to sort out how to do it between processes. I think either sending the pickled log data or just the final log string over the process pipe should be fine.

Handle FileNotFoundError for configs

Describe the bug
A clear and concise description of what the bug is.

The SIGHTSRobot service can't handle loss (of the active config):

FileNotFoundError: [Errno 2] No such file or directory: 'configs/CONNOR WAS HERE'
Traceback (most recent call last):
  File "src/main.py", line 72, in <module>
    config = json.load(open(config_file))

We need to help it get through these tough times.

Steps To Reproduce
Steps to reproduce the behaviour:

  1. Use the SSH terminal (or hijack an XMLRPC request function is supervisor_sights_config??) to delete the active config file.
  2. Restart the SIGHTS service

Expected behaviour
Failover to the minimal.json config gracefully.

Screenshots
image

Host/Robot Information:

  • OS: Ubuntu
  • OS Version: 18.04
  • SIGHTS Software versions: [On the interface, in the settings modal, on the about tab]
    • SIGHTSRobot version: v0.15
    • SIGHTSInterface version: v0.18

Controller (where you access the interface from. Remove this section if you weren't using the interface):

  • OS: Windows 10
  • OS Version: 1909
  • Browser: Chrome
  • Browser version: 79.0.3945.130

Create a sensor wrapper for MLX90640 thermal cameras

At the moment there is no sensor wrapper for the thermal camera (MLX90640). The thermal camera grid on the interface does work with an AMG8833, so all that is needed is the sensor wrapper.
The MLX90640 driver seems to be a bit tricky to use, as it's written in C, but does provide a Python wrapper.

Config Revisions

Is your feature request related to a problem? Please describe.
Many moons ago, there was a feature that restored a config backup when something you misconfigured blew up in your face. This feature has been removed for some time now, since users are now able to edit their config files even when the service is stopped thanks to XML-RPC Config Management (see https://github.com/SFXRescue/supervisor_sights_config/pull/4).

However, some of the code for this system, specifically that which creates config backups, was never removed. I wish to utilise that code once again to create a revisions management system to allow users to easily restore older revisions of their configs.

Describe the solution you'd like
On the interface side, this requires the implementation of a pretty little "revisions" tab. A dropdown selector will list the available revisions. This will require an XMLRPC request to send the available revisions to the interface.
From this tab, users can view a revision, restore it over their current config, or delete it.
It might be cool to display the differences between the currently loaded config and the revision in question as well!
image

Describe alternatives you've considered
Removing the backup code altogether, which seems a shame.
Keeping the backup code and letting users figure out how to restore backups using Linux commands via SSH.

Additional context
I hope you're having a great day.

Switching configs does not update "output" elements

This results in inconsistencies such as:
image

In this case, the original config had the control property:

"control": {
		"default_gamepad_speed": 3,
		"default_keyboard_speed": 3
	},

And was switched to:

"control": {
		"default_gamepad_speed": 8,
		"default_keyboard_speed": 8
	},

The position of the sliders reflects the new config file (8 and 8) while the text still reflects the previous config (3 and 3).

A simple fix may simply be to destroy the current editor and create a new one when a new config is received rather than setting the JSON with setValue() as is done currently in the sights.sensors.js file.

Support modular sensor configuration and management

Is your feature request related to a problem? Please describe.

#36 will introduce modular sensor management. The interface in its current state cannot support this change, as the HTML that renders sensor output on the page and the javascript that receives sensor data is not modular.

Describe the solution you'd like

Quite simply, major overhaul in a few key areas:

The config editor and config schema need to be updated to support an array of sensor definition JSON objects. The format of the JSON objects is described in #36 and may be subject to change, so please follow the discussion on that issue.

Modular sensor rendering is required. We cannot hard-code HTML for an arbitrary number of, say, temperature sensors.
One solution is to have a folder of javascript sensor handlers and a sensor manager.
When a config file is received, the sensor manager can loop through every sensor defined and enabled in that config file. For each enabled sensor, the sensor manager can call the corresponding sensor handler to inject the sensor card into the page.

Since the WebSocket object supports.addEventListener(), the manager or handler can and add a (unique) event listener to the websocket for that sensor.

Additional context

Related: #36

Integrate interface with supervisord

We're using supervisord to manage running the SARTRobot software, as it provides suitable control over the process, and a very useful web api, and web interface.
Adding the functionality to the interface will all be done using supervisord's XML-RPC API.

  • Add start / stop / restart SARTRobot button to interface
  • Add live SARTRobot log tab to modal

Handle failed serial connection

SIGHTS crashes if the serial port is unavailable.

Dynamixel

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 265, in open
    self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
FileNotFoundError: [Errno 2] No such file or directory: '/dev/serial/by-id/'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "src/main.py", line 91, in <module>
    while(manager.run()):
  File "src/main.py", line 44, in run
    self.control_process = ControlReceiver(2, self.control_pipe, self.config_file)
  File "/opt/sights/SIGHTSRobot/src/control_receiver.py", line 18, in __init__
    self.motors = Motors(self.config)
  File "/opt/sights/SIGHTSRobot/src/motors.py", line 125, in __init__
    self.connection = DynamixelConnection(self.port, self.baudrate)
  File "/opt/sights/SIGHTSRobot/src/motors.py", line 52, in __init__
    port=port, baudrate=baudrate)
  File "/usr/local/lib/python3.6/dist-packages/pyax12/connection.py", line 85, in __init__
    stopbits=serial.STOPBITS_ONE)
  File "/usr/local/lib/python3.6/dist-packages/serial/serialutil.py", line 240, in __init__
    self.open()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 268, in open
    raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port /dev/serial/by-id/: [Errno 2] No such file or directory: '/dev/serial/by-id/'

Serial/Sabertooth

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 265, in open
    self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
FileNotFoundError: [Errno 2] No such file or directory: '/dev/serial/by-id/'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "src/main.py", line 91, in <module>
    while(manager.run()):
  File "src/main.py", line 44, in run
    self.control_process = ControlReceiver(2, self.control_pipe, self.config_file)
  File "/opt/sights/SIGHTSRobot/src/control_receiver.py", line 18, in __init__
    self.motors = Motors(self.config)
  File "/opt/sights/SIGHTSRobot/src/motors.py", line 123, in __init__
    self.connection = SerialConnection(self.port, self.baudrate)
  File "/opt/sights/SIGHTSRobot/src/motors.py", line 27, in __init__
    self.serial = serial.Serial(port=port, baudrate=baudrate)
  File "/usr/local/lib/python3.6/dist-packages/serial/serialutil.py", line 240, in __init__
    self.open()
  File "/usr/local/lib/python3.6/dist-packages/serial/serialposix.py", line 268, in open
    raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port /dev/serial/by-id/: [Errno 2] No such file or directory: '/dev/serial/by-id/'

A possible ways to handle this would be to reattempt the connection with exponential backoff, and start in safe mode with the minimal.json config if issues persist

Overhaul sensor configuration and management

Is your feature request related to a problem? Please describe.
At the moment, the temperature key in the config file (within the sensors section) will use the MLX90614 wrapper. I've written untested support for a different temp sensor as an example in some new documentation I'm writing and we could even make it a supported sensor. The issue is that temperature is hardcoded to mlx90614.

Describe the solution you'd like
We could change it to mlx90614 of course, that would fix the problem. This would mean using the sensor name as the key in the JSON file for sensors. So, bme280 for the new type of temperature sensor and mlx90614 for the type we use.

However, this still doesn't allow for multiple sensors of the same type.

My proposed solution would be to change the sensors section of the config file to an array.

Here's an example of how the sensors section will look. Note how we have multiple of one type of sensor, as well as multiple different types of temperature sensors.

"sensors": [
	{
		"type": "amg8833",
		"name": "Thermal Camera",
		"enabled": true,
		"frequency": 0.5,
		"width": 32,
		"height": 24
	},
	{
		"type": "mlx90614",
		"name": "Temperature Sensor (front)",
		"enabled": true,
		"frequency": 2,
		"address": "0x5A"
	},
	{
		
		"type": "bme280",
		"name": "Temperature Sensor (back)",
		"enabled": true,
		"frequency": 4
	},
	{ 
		"type": "vl53l0x",
		"name": "Distance Sensor (1)",
		"enabled": true,
		"frequency": 2,
		"address": "0x2A"
	},
	{ 
		"type": "vl53l0x",
		"name": "Distance Sensor (2)",
		"enabled": true,
		"frequency": 2,
		"address": "0x2B"
	},
	{
		"type": "sgp30",
		"name": "Gas Sensor",
		"enabled": true,
		"frequency": 2
	}
	{
		"type": "memory",
		"name": "System Memory",
		"enabled": true,
		"frequency": 3
	},
	{
		"type": "cpu_temp",
		"name": "CPU Temperature",
		"enabled": true,
		"frequency": 5
	},
},

Additionally, this means we can implement proper sensor management.

sensor_stream.py needs to look through the config file, find active sensors, lookup their respective SensorWrapper class (we need to make a basic lookup table) and create a new instance of that class and append it to the sensors array

The lookup table basically needs to function like this, that takes the type key from the configuration file and returns the appropriate class:

{
	"mlx90614": MLX90614Wrapper,
	"sgp30": SGP30Wrapper,
	"bme280": BME280Wrapper
}

Improve Jetson Nano support

At the moment, there are a few elements which need to be worked on to ensure it's fully compatible with the Nvidia Jetson Nano:

  • Ensure installer works on the Jetson Nano and properly sets up SIGHTS
  • Ensure I2C sensors work on the Jetson Nano and add any additional steps required to enable I2C to the installer.
  • Make the installer install ARM binaries for Motion on Jetson Nano (we may need to compile from source or provide our own binaries)
  • Test to ensure all software components work as expected.

Implement plugin system for sensor wrappers

Is your feature request related to a problem? Please describe.
At the moment, adding a new sensor wrapper involves adding it to the __init__.py file within the sensors directory.

It's messy, it's not intuitive and making the init file import everything in the directory instead is apparently a very bad idea. In the wise words of one StackOverflow user:

This is a very bad idea.

Describe the solution you'd like
Make sensor_stream.py scan the sensors directory and import each file, or plugin, automatically.

I would also propose referring to these files as plugins from hereon, to better clarify their modular nature.

From this StackOverflow post:

The way you normally do this is to iterate one or more plugin directories with os.listdir or os.walk, then, for each Python file, use importlib (or lower-level equivalents from imp, in Python 2.x) to import it by path.

Additional context

Useful reference:

Allow editing config files when SIGHTSRobot is not running

Is your feature request related to a problem? Please describe.
The config is currently sent to the interface and saved to SIGHTSRobot via websocket, while the rest of config management (deleting, switching) is handled by the Supervisor extension.

Describe the solution you'd like
Replace websocket config management with xmlrpc requests using Supervisor. This allows users to completely manage their config files while the robot is offline.

This may require major changes to sights.sensors.js.

Related:
#34
https://github.com/SFXRescue/supervisor_sights_config/issues/3

Implement a two-way VoIP solution using Roc

A brief history of two-way audio

In previous years, we have used a few methods to do two-way audio. Initially we had a speech to text and back again system to transmit data. Needless to say, this was quite limiting and not particularly... well, good.

This was replaced in 2018 with Mumble, a basic VoIP / chatroom server / client.

Ideally we were looking for a CLI VoIP server to put on the robot and a GUI client for the control panel but we couldn't really find any decent command-line VoIP servers, so we chose Mumble as it was pretty simple and free.

We did also experiment with some actual VoIP software (specifically Linphone) but all we had was issue after issue. We settled on Mumble, despite the lack of a CLI server, and I implemented it in an afternoon, a couple weeks before the competition.

There wasn't (and perhaps still isn't) a Mumble command-line server that I know of, so we ran the GUI server within a very hacky virtual X11 server onboard the robot. The control panel then ran the Mumble desktop client which connected to the server. This solution was very problematic, we couldn't see any errors or anything on the GUI since the server didn't include a CLI version we could use instead.

So I can very loudly declare: It's time for a proper solution.

The proposed solution

A while back I discovered Roc. It's a general-purpose C API and command-line tool which provides real-time audio streaming over a network. I've had this bookmarked for like a year, it's time to give it a shot.

Check out some of the features (I've emboldened features that I think are especially important to us):

  • real-time streaming with guaranteed latency;
  • restoring lost packets using Forward Erasure Correction codes;
  • converting between the sender and receiver clock domains;
  • CD-quality audio;
  • multiple profiles for different CPU and latency requirements;
  • portability;
  • relying on open, standard protocols.
  • detecting and restarting broken streams.
  • mixing simultaneous streams from multiple senders on the receiver;
  • binding receiver to multiple ports with different protocols;

Also have a look at this page of the docs which explains how to use the included command-line tools which sound almost perfect for our use already.

Parting words

At the moment, I plan on using this, since it seems perfect for our use case, but of course, if it turns out to not be suitable then we'll have a look at other options.

But at the very least, I can leave you with this overly verbose issue.

Let's see how it goes.

Make dark mode the default

Is your feature request related to a problem? Please describe.
Most people use dark mode, and frankly light mode just doesn't look as good anymore (both subjectively, but also because we've changed things to better suit dark mode, like button styles, and made light mode worse over time.)

Describe the solution you'd like
Dark mode should be the default. Light mode is an opt-in option.

Describe alternatives you've considered
Themes are certainly an option we could explore in the future. Users could provide a CSS file for a custom theme.

Need to implement command line arguments to load config in Manager

A command-line flag to specify config file will allow preset configurations, which is useful as it can allow bundled configs for the different robots. Also very useful when testing.

Preferably -c flag, although it'll probably be the only argument so we could just have no flag like manager.py my_robot.json.

Transition away from websocket based config in SIGHTSRobot

Is your feature request related to a problem? Please describe.
The config is currently sent to the interface and saved to SIGHTSRobot via websocket, while the rest of config management (deleting, switching) is handled by the Supervisor extension.

Describe the solution you'd like
Replace websocket config management with xmlrpc requests using Supervisor. This allows users to completely manage their config files while the robot is offline.

Some code must be moved to the Supervisor extension, and some can be removed entirely:
Backup creation and saving can be moved to the extension.
Automatic backup restoration can be removed altogether.

Related:
https://github.com/SFXRescue/SIGHTSInterface/issues/34
https://github.com/SFXRescue/supervisor_sights_config/issues/3

Live inverse kinematic view of the robot based on motor position and sensor data

Describe the solution you'd like
We would like a new graph on the interface that takes a new set of sensor data, that of the motor positions, and IMU data, and uses this to create a 2D (for now) side view of the arm, paddles and robot itself.

It would show the current position of the arm and paddles, based on data from the motor encoders. It would also use the IMU's gyroscopic sensor to show how the robot is tilted.

Describe alternatives you've considered
A 3D view is something we can consider in the future, but for now, it holds little advantage over a semi-transparent 2D view (so we can see the other paddle).

Additional context
Exactly how we go about creating this is up for discussion. There's plenty of new ways to create HTML5 canvas objects, so it's likely we can create a nice native JS implementation.

Reorganise JavaScript files

Is your feature request related to a problem? Please describe.

Directory interface/js is a mess, and we are using some libraries that we've modified but have not taken note of modifications made.

Describe the solution you'd like

  • Minify any unminified libraries
  • Move to subfolder lib/
  • Update any libraries that need updating
  • Track any libraries we've made changes to.
    • Add comments to modified libraries
    • Fork to SFXRescue organisation
    • This includes
      • json-editor (forked already)
      • bootast (added fontawesome support)
      • gamepad.js (using someone's fork to fix it)
  • Add to documentation what languages highlight.js needs to support, in case someone wants to update it.
  • Add to documentation a list of what libraries we've modified and a link to our fork

Dark mode

Easy on the eyes.

At some point it might be a good idea to store user preferences in cookies (per-control panel preferences) or in a/the robot config (per robot preferences).

  • Add CSS classes for all elements that can change theme
  • CSS file per theme
  • Dynamically load theme CSS files
"Needs more dark theme"
    ~ Aaron Maggs, 2019
"Dark theme!"
    ~ Connor Kneebone, 2019
"IT HAS DARK THEME AND I LOVE DARK THEMES"
    ~ Aaron Maggs, 2019
"Dark theme ๐Ÿ˜"
    ~ Aaron Maggs, 2019
"Dark mode all the things"
    ~ Aaron Maggs, 2019

Should we reorganize the root directory?

We can consider making a few changes before the v1.0 release such as:

  • rename manager.py to main.py to better reflect it's importance
  • move other scripts into a subdirectory (src/ perhaps?)
  • move sensor_wrapper.py into sensors/

Implement a debug screen

Is your feature request related to a problem? Please describe.

We're running out of screen real estate on the interface, so it's time we decide what will be shown on the interface by default and what will be hidden away unless needed.

We want a simple user experience, free of confusion and clutter for end users (drivers, first response, operators, etc.). However, we also need to have the advanced functionality there for developers to add features, debug issues, and probably heaps of other advanced use cases that I can't predict.

Describe the solution you'd like

It would be good to show more information that is useful for debugging. Something akin to Minecraft's debug screen.

Here's what I'm thinking at the moment.

  • System information
    • Network information (SSID, signal strength, stats, etc.)
    • SIGHTS process ID
  • WebSocket connection indicators
  • Active motor wrapper plugins
  • Active sensor wrapper plugins
  • List of active sensors
  • Current motor connection state

I'll add to the list as we think of ideas.

How this will be displayed is up for discussion. The issue with Minecraft's debug screen is that the data cannot be easily copied or logged.

Improve documentation

Need to improve the README with some things like:

  • What is SIGHTS?
  • A proper feature list
  • Simplified and revised installation instructions
  • Better indication of supported platforms
  • How to add new sensors.
  • Add README files to important subdirectories
  • Explain project layout and important files, etc.
  • Update manual installation instructions
  • Ensure code is nicely commented
  • Tutorials, etc.

Create a graphical configuration editor

At the moment, configuration editing is done through a YAML based editor window, which provides advanced control, but at the cost of usability.

At some point, a proper graphical editor should be implemented, but not until the exact contents of the configuration file are unlikely to change.

Create installer script

The installation instructions continue to get more and more complex. It's time to create an installer / updater script.

Set service state to disconnected when request to /RPC2 returns a 503 error

If the SIGHTS service suddenly becomes unavailable (for example when the host is shut down or restarted), the current service state (usually RUNNING) is not updated until supervisord becomes available again.
image

Instead, the service status should be set to DISCONNECTED to more accurately reflect the current state of the service.

Installer doesn't start service on boot on systems where rc.local does not exist

It appears the file rc.local does not exist in a fresh installation of Ubuntu 18.04.
install.sh assumes the file exists:

echo -e "\nAdding supervisord to /etc/rc.local..."
    if grep -Fxq "supervisord &" /etc/rc.local
    then
        echo -e "Already done..."
    else
        sed -i -e '$i \supervisord &\n' /etc/rc.local
    fi

Manually creating rc.local and adding the lines:

#!/bin/sh -e
supervisord
exit 0

and running sudo chmod +x /etc/rc.local has the desired effect of running SIGHTS on boot.

At this stage we can either update the install script to check for the missing file and create it if necessary, or find some alternative for starting the service on boot that will work with more operating systems.

Add close button to SSH tabs

Is your feature request related to a problem? Please describe.
There's no close button on the SSH tabs which isn't really a problem in most use cases, but it would be nice to have and it's something that users will expect, so I think it should be added (post-1.0 is fine).

Describe the solution you'd like
Close buttons on the SSH tabs, much like your everyday web browser.

Describe alternatives you've considered
A close button that's not in the tab is possible, but it's not intuitive and everything else in the world has the close buttons in the tabs.

Improve Raspberry Pi support

At the moment, there are a few elements which need to be worked on to ensure it's fully compatible with the Raspberry Pi (3/4):

  • Ensure installer works on Raspberry Pi and properly sets up SIGHTS
  • Ensure I2C sensors work (including multiple sensors at the same time) on the Raspberry Pi and add any additional steps required to enable I2C to the installer.
  • Make the installer install ARM binaries for Motion on the Raspberry Pi
  • Test to ensure all software components work as expected.

Overhaul motor support with motor groups

Allowing the user to create motor groups would add support for arms, paddles, and any other actuator a user might like to add to their robot.

This ideally includes support for both the Dynamixels and DC motors. They should be configured through the same config file as the rest of the robot.

This will require a rewrite of the entire motor handling code. So I'm keen to hear what the community would like.

Watch Page for multiple operators

Is your feature request related to a problem? Please describe.
If a second instance of the SIGHTSInterface is opened on another device, the original instance is disabled. This is done to ensure the robot is only receiving instructions from one individual at any given time.
This may be disadvantageous to multi-operator setups, where one individual is controlling the robot while other operators are analysing sensors or monitoring hardware.

Describe the solution you'd like
A watch page available at http://hostname/watch could provide these individuals with access to cameras, sensor data, logs and SSH terminals for analysis and monitoring on their own devices without giving unnecessary access to robot controls and configuration.

Describe alternatives you've considered
An alternative is to allow multiple operators on the main page and let end-users manage their teams correctly to ensure the robot does not receive instructions from multiple devices.

Implement the ability to delete inactive config files from interface

The ability to delete config files should be implemented, lest users are overrun by all the configs they can create (but not delete) with the implementation of SFXRescue/SIGHTSInterface#21.

Allowing the deletion of only inactive configs means that there should always be at least one valid config.

Here's a beautiful mockup by @Conr86:
image

Deletion should remove any backups (in case the user later creates a new file with the same name as a previously deleted one, the old backups may be restored over the new config if the user makes mistakes during their initial configuration setup).

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.