diff --git a/MANIFEST.in b/MANIFEST.in index 156e1d8..ad50cb8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,13 +1,7 @@ -recursive-include src/py/bbctrl/http * -include package.json README.md scripts/install.sh +include package.json README.md +graft scripts +graft src/py/bbctrl/http +graft src/py/camotics include src/avr/bbctrl-avr-firmware.hex include src/bbserial/bbserial.ko -include scripts/avr109-flash.py -include scripts/buildbotics.gc -include scripts/xinitrc -include scripts/ratpoisonrc -include scripts/rc.local -include scripts/bbctrl.service -include scripts/11-automount.rules -recursive-include src/py/camotics * global-exclude .gitignore diff --git a/scripts/Xresources b/scripts/Xresources new file mode 100644 index 0000000..e700215 --- /dev/null +++ b/scripts/Xresources @@ -0,0 +1,2 @@ +xterm*faceSize: 12 +xterm*faceName: DejaVu Sans Mono diff --git a/scripts/bbctrl-logrotate b/scripts/bbctrl-logrotate new file mode 100644 index 0000000..906336d --- /dev/null +++ b/scripts/bbctrl-logrotate @@ -0,0 +1,8 @@ +/var/log/bbctrl.log { + rotate 4 + weekly + compress + missingok + notifempty + copytruncate +} diff --git a/scripts/cron_d_reboot b/scripts/cron_d_reboot new file mode 100644 index 0000000..7fc7455 --- /dev/null +++ b/scripts/cron_d_reboot @@ -0,0 +1 @@ +@reboot root run-parts /etc/cron.reboot diff --git a/scripts/cron_reboot_logrotate b/scripts/cron_reboot_logrotate new file mode 100644 index 0000000..f4f56a9 --- /dev/null +++ b/scripts/cron_reboot_logrotate @@ -0,0 +1,4 @@ +#!/bin/sh + +test -x /usr/sbin/logrotate || exit 0 +/usr/sbin/logrotate /etc/logrotate.conf diff --git a/scripts/install.sh b/scripts/install.sh index ff06868..1019344 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -37,13 +37,13 @@ fi #chmod ug+s /usr/lib/xorg/Xorg # Use the full screen resolution -grep "^framebuffer_width=1280$" /boot/config.txt >/dev/null -if [ $? -eq 0 ]; then - mount -o remount,rw /boot && - sed -i 's/^\(framebuffer_.*\)$/#\1/g' /boot/config.txt - mount -o remount,ro /boot - REBOOT=true -fi +# grep "^framebuffer_width=1280$" /boot/config.txt >/dev/null +# if [ $? -eq 0 ]; then +# mount -o remount,rw /boot && +# sed -i 's/^\(framebuffer_.*\)$/#\1/g' /boot/config.txt +# mount -o remount,ro /boot +# REBOOT=true +# fi # Fix camera grep dwc_otg.fiq_fsm_mask /boot/cmdline.txt >/dev/null @@ -93,7 +93,9 @@ if [ $? -ne 0 ]; then REBOOT=true fi -# Install xinitrc +# Install .Xresources & .xinitrc +cp scripts/Xresources ~pi/.Xresources +chown pi:pi ~pi/.Xresources cp scripts/xinitrc ~pi/.xinitrc chmod +x ~pi/.xinitrc chown pi:pi ~pi/.xinitrc @@ -121,7 +123,7 @@ cp scripts/rc.local /etc/ # Ensure that the watchdog python library is installed pip3 list --format=columns | grep watchdog >/dev/null if [ $? -ne 0 ]; then - pip3 install scripts/watchdog-v0.10.6.tar.gz + pip3 install scripts/pathtools-0.1.2.tar.gz scripts/watchdog-v0.10.6.tar.gz fi # Install bbctrl @@ -133,6 +135,54 @@ if $UPDATE_PY; then chmod 777 $HTTP_DIR fi +# Expand the file system if necessary +chmod +x ./scripts/resize_root_fs.sh +./scripts/resize_root_fs.sh +if [ $? -eq 0 ]; then + REBOOT=true +fi + +# Install our logrotate config +cp ./scripts/bbctrl-logrotate /etc/logrotate.d/bbctrl +chown root:root /etc/logrotate.d/bbctrl + +# Ensure logrotate runs on every boot (for systems with no network, thus bad clock) +if [ ! -e /etc/cron.d/reboot ]; then + cp ./scripts/cron_d_reboot /etc/cron.d/reboot + mkdir -p /etc/cron.reboot + cp ./scripts/cron_reboot_logrotate /etc/cron.reboot/logrotate +fi + +########################################## +# Begin one-time cleanup tasks for 1.0.7 +########################################## + +# Delete the entire local Chromium configuration. Start clean. +rm -rf /home/pi/.config/chromium + +# Get rid of some old files that were left behind +rm -rf /home/pi/hostinfo.txt +rm -rf /home/pi/ssidinfo.txt +rm -rf /home/bbmc/bbctrl-1.0.0.tar.bz2 +rm -rf /home/bbmc/hostinfo.sh +rm -rf /home/bbmc/index.html +rm -rf /home/bbmc/favicon.ico + +# Force a logrotate to get everything into a known state +logrotate -f /etc/logrotate.conf + +# Clean up the log directory - get rid of everything old +rm -rf /var/log/*.gz +rm -rf /var/log/*.1 +rm -rf /var/log/*.old +rm -rf /var/log/bbctrl.2019*.install +rm -rf /var/log/bbctrl.2020*.install +rm -rf /var/log/bbctrl.log.* + +########################################## +# End one-time cleanup tasks for 1.0.7 +########################################## + sync if $REBOOT; then diff --git a/scripts/pathtools-0.1.2.tar.gz b/scripts/pathtools-0.1.2.tar.gz new file mode 100644 index 0000000..859d99f Binary files /dev/null and b/scripts/pathtools-0.1.2.tar.gz differ diff --git a/scripts/ratpoisonrc b/scripts/ratpoisonrc index 98b5e1d..6f4219a 100644 --- a/scripts/ratpoisonrc +++ b/scripts/ratpoisonrc @@ -4,3 +4,4 @@ set fgcolor white unbind c bind c exec x-terminal-emulator -fg white -bg black +bind C-c exec x-terminal-emulator -fg white -bg black diff --git a/scripts/resize2fs_once b/scripts/resize2fs_once new file mode 100644 index 0000000..38a4d47 --- /dev/null +++ b/scripts/resize2fs_once @@ -0,0 +1,25 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: resize2fs_once +# Required-Start: +# Required-Stop: +# Default-Start: 3 +# Default-Stop: +# Short-Description: Resize the root filesystem to fill partition +# Description: +### END INIT INFO +. /lib/lsb/init-functions +case "$1" in + start) + log_daemon_msg "Starting resize2fs_once" + ROOT_DEV=$(findmnt / -o source -n) && + resize2fs $ROOT_DEV && + update-rc.d resize2fs_once remove && + rm /etc/init.d/resize2fs_once && + log_end_msg $? + ;; + *) + echo "Usage: $0 start" >&2 + exit 3 + ;; +esac diff --git a/scripts/resize_root_fs.sh b/scripts/resize_root_fs.sh new file mode 100755 index 0000000..16a4619 --- /dev/null +++ b/scripts/resize_root_fs.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Used by the OneFinity firmware to determine if the root filesystem +# needs to be enlarged to maximize usage of the SD card. +# +# The majority of this code originates from /usr/lib/raspi-config/init_resize.sh + +get_fs_resize_variables () { + ROOT_PART_DEV=$(findmnt / -o source -n) + ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3) + ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4) + ROOT_DEV="/dev/${ROOT_DEV_NAME}" + ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition") + BOOT_PART_DEV=$(findmnt /boot -o source -n) + BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3) + BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4) + ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size") + TARGET_END=$((ROOT_DEV_SIZE - 1)) + PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's') + LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1) + ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:") + ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3) +} + +should_resize_root_partition() { + get_fs_resize_variables + + if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then + FAIL_REASON="Boot and root partitions are on different devices" + return 1 + fi + + if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then + FAIL_REASON="Root partition should be last partition" + return 1 + fi + + if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then + FAIL_REASON="Root partition runs past the end of device" + echo $FAIL_REASON + return 1 + fi + + if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then + FAIL_REASON="Could not determine partitions" + return 1 + fi + + if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then + FAIL_REASON="Root partition is already expanded" + return 1 + fi +} + +if should_resize_root_partition; then + grep "init_resize" /boot/cmdline.txt >/dev/null + if [ $? -ne 0 ]; then + # On the next boot, init_resize.sh will: + # Resize the root partition to use the rest of the SD card + # Remove itself from /boot/cmdline.txt + # Reboot the machine + sudo mount /boot -o rw,remount + sed -i 's/\(.*\)/\1 init=\/usr\/lib\/raspi-config\/init_resize.sh/' /boot/cmdline.txt + fi + + # On the first boot after init_resize, resize2fs_once will: + # Resize the root fs to fill its partition + # Remove itself from the registered systemd services + # Delete itself from the filesystem + # Therefore, never run again + cp scripts/resize2fs_once /etc/init.d/resize2fs_once + chmod +x /etc/init.d/resize2fs_once + systemctl enable resize2fs_once + + exit 0 +else + echo "Not resizing root partition: $FAIL_REASON" + exit 1 +fi diff --git a/scripts/xinitrc b/scripts/xinitrc index 69360a8..08af117 100644 --- a/scripts/xinitrc +++ b/scripts/xinitrc @@ -14,6 +14,8 @@ while true; do sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' $PREFS sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' $PREFS + xrdb /home/pi/.Xresources + # Start browser /usr/local/bin/browser --no-first-run --disable-infobars \ --noerrdialogs --disable-3d-apis http://localhost/ diff --git a/src/js/app.js b/src/js/app.js index 175ed11..b32ce2d 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -114,7 +114,11 @@ module.exports = new Vue({ motors: [{}, {}, {}, {}], version: '' }, - state: {messages: []}, + state: { + messages: [], + wait_for_probing_complete: false, + show_probe_complete_modal: false + }, video_size: cookie.get('video-size', 'small'), crosshair: cookie.get('crosshair', 'false') != 'false', errorTimeout: 30, diff --git a/src/js/message.js b/src/js/message.js index a720511..57c1fae 100644 --- a/src/js/message.js +++ b/src/js/message.js @@ -36,6 +36,12 @@ module.exports = { type: Boolean, required: true, twoWay: true + }, + + class: { + type: String, + required: false, + twoWay: false } } } diff --git a/src/js/path-viewer.js b/src/js/path-viewer.js index 3cd1d01..03d4d0b 100644 --- a/src/js/path-viewer.js +++ b/src/js/path-viewer.js @@ -27,23 +27,12 @@ var orbit = require('./orbit'); var cookie = require('./cookie')('bbctrl-'); -var api = require('./api'); var font = require('./helvetiker_regular.typeface.json') - -function get(obj, name, defaultValue) { - return typeof obj[name] == 'undefined' ? defaultValue : obj[name]; -} - - -var surfaceModes = ['cut', 'wire', 'solid', 'off']; - - module.exports = { template: '#path-viewer-template', props: ['toolpath'], - data: function () { return { enabled: false, @@ -62,7 +51,22 @@ module.exports = { computed: { - target: function () {return $(this.$el).find('.path-viewer-content')[0]} + target: function () { + return $(this.$el).find('.path-viewer-content')[0] + }, + + webglAvailable: function() { + // Create canvas element. The canvas is not added to the + // document itself, so it is never displayed in the + // browser window. + const canvas = document.createElement("canvas"); + + // Get WebGLRenderingContext from canvas element. + const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); + + // Report the result. + return gl && gl instanceof WebGLRenderingContext; + } }, @@ -122,6 +126,10 @@ module.exports = { methods: { update: function () { + if (!this.webglAvailable) { + return; + } + if (!this.state.selected) { this.dirty = true; this.scene = new THREE.Scene(); @@ -269,6 +277,10 @@ module.exports = { graphics: function () { + if (!this.webglAvailable) { + return; + } + try { // Renderer this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}); @@ -280,6 +292,7 @@ module.exports = { console.log('WebGL not supported: ', e); return; } + this.enabled = true; // Camera diff --git a/src/pug/templates/control-view.pug b/src/pug/templates/control-view.pug index 79f62e5..12f3080 100644 --- a/src/pug/templates/control-view.pug +++ b/src/pug/templates/control-view.pug @@ -175,10 +175,14 @@ script#control-view-template(type="text/x-template") button#jog_button_large(style="height:100px;width:100px", @click=`set_jog_incr('large')`) 100 tr td(style="height:100px", align="center", colspan="2") - button(style="height:100px;width:200px", :class="state['pw'] ? '' : 'load-on'", @click=`start_probe_test(() => { show_tool_diameter_modal = true })`) + button(:class="state['pw'] ? '' : 'load-on'", + style="height:100px;width:200px", + @click=`start_probe_test(() => { show_tool_diameter_modal = true })`) | Probe XYZ td(style="height:100px", align="center", colspan="2") - button(style="height:100px;width:200px", :class="state['pw'] ? '' : 'load-on'", @click=`start_probe_test(probe_z)`) + button(:class="state['pw'] ? '' : 'load-on'", + style="height:100px;width:200px", + @click=`start_probe_test(probe_z)`) | Probe Z td(style="vertical-align: top;") diff --git a/src/pug/templates/message.pug b/src/pug/templates/message.pug index 2b724ad..7257547 100644 --- a/src/pug/templates/message.pug +++ b/src/pug/templates/message.pug @@ -26,7 +26,7 @@ //-///////////////////////////////////////////////////////////////////////////// script#message-template(type="text/x-template") - .modal-mask(v-if="show") + .modal-mask(v-if="show", :class="class") .modal-wrapper .modal-container .modal-header diff --git a/src/py/bbctrl/Config.py b/src/py/bbctrl/Config.py index 9dc3685..ab557a8 100644 --- a/src/py/bbctrl/Config.py +++ b/src/py/bbctrl/Config.py @@ -147,11 +147,13 @@ class Config(object): for motor in config['motors']: motor['stall-microstep'] = 8 motor['stall-current'] = 1 + motor['idle-current'] = 1 motor['max-accel'] = 750 + motor['latch-backoff'] = 5 if motor['axis'] == 'X' or motor['axis'] == 'Y': motor['search-velocity'] = 1.688 motor['max-velocity'] = 10 - motor['max-jerk'] = 15000 + motor['max-jerk'] = 1000 motor['zero-backoff'] = 1.5 if motor['axis'] == 'Z': motor['search-velocity'] = 0.675 diff --git a/src/py/bbctrl/Log.py b/src/py/bbctrl/Log.py index 0436375..6e1226f 100644 --- a/src/py/bbctrl/Log.py +++ b/src/py/bbctrl/Log.py @@ -170,7 +170,7 @@ class Log(object): if self.path is None: return if self.f is not None: self.f.close() self._rotate(self.path) - self.f = open(self.path, 'w') + self.f = open(self.path, 'a') self.bytes_written = 0 diff --git a/src/resources/onefinity_machinist_defaults.json b/src/resources/onefinity_machinist_defaults.json index 544e478..1fc9a26 100644 --- a/src/resources/onefinity_machinist_defaults.json +++ b/src/resources/onefinity_machinist_defaults.json @@ -38,9 +38,9 @@ "max-velocity": 10, "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-min", "reverse": false, @@ -48,7 +48,7 @@ "min-soft-limit": 0, "max-switch": "disabled", "step-angle": 1.8, - "stall-current": 1.0, + "stall-current": 1, "stall-sample-time": 200, "microsteps": 16, "stall-volts": 2, @@ -64,9 +64,9 @@ "max-velocity": 10, "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-min", "reverse": false, @@ -86,29 +86,29 @@ }, { "latch-velocity": 0.1, - "max-accel": 10, - "max-velocity": 17, - "search-velocity": 0.5, + "max-accel": 750, + "max-velocity": 10, + "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, "latch-backoff": 5, "enabled": true, - "homing-mode": "manual", + "homing-mode": "stall-min", "reverse": false, "stall-microstep": 8, "min-soft-limit": 0, "max-switch": "disabled", "step-angle": 1.8, - "stall-current": 1.5, - "stall-sample-time": 50, + "stall-current": 1, + "stall-sample-time": 200, "microsteps": 16, - "stall-volts": 6, + "stall-volts": 2, "axis": "Y", "min-switch": "disabled", - "max-jerk": 50, - "max-soft-limit": 752, - "zero-backoff": 1 + "max-jerk": 1000, + "max-soft-limit": 410, + "zero-backoff": 1.5 }, { "latch-velocity": 0.1, @@ -116,9 +116,9 @@ "max-velocity": 3, "search-velocity": 0.675, "travel-per-rev": 4, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-max", "reverse": true, diff --git a/src/resources/onefinity_woodworker_defaults.json b/src/resources/onefinity_woodworker_defaults.json index 9eec222..c6de435 100644 --- a/src/resources/onefinity_woodworker_defaults.json +++ b/src/resources/onefinity_woodworker_defaults.json @@ -38,9 +38,9 @@ "max-velocity": 10, "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-min", "reverse": false, @@ -64,9 +64,9 @@ "max-velocity": 10, "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-min", "reverse": false, @@ -86,29 +86,29 @@ }, { "latch-velocity": 0.1, - "max-accel": 10, - "max-velocity": 17, - "search-velocity": 0.5, + "max-accel": 750, + "max-velocity": 10, + "search-velocity": 1.688, "travel-per-rev": 10, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, "latch-backoff": 5, "enabled": true, - "homing-mode": "manual", + "homing-mode": "stall-min", "reverse": false, "stall-microstep": 8, "min-soft-limit": 0, "max-switch": "disabled", "step-angle": 1.8, - "stall-current": 1.5, - "stall-sample-time": 50, + "stall-current": 1, + "stall-sample-time": 200, "microsteps": 16, - "stall-volts": 6, + "stall-volts": 2, "axis": "Y", "min-switch": "disabled", - "max-jerk": 50, - "max-soft-limit": 752, - "zero-backoff": 1 + "max-jerk": 1000, + "max-soft-limit": 816, + "zero-backoff": 1.5 }, { "latch-velocity": 0.1, @@ -116,9 +116,9 @@ "max-velocity": 3, "search-velocity": 0.675, "travel-per-rev": 4, - "idle-current": 0.5, + "idle-current": 1, "drive-current": 2.8, - "latch-backoff": 5.001, + "latch-backoff": 5, "enabled": true, "homing-mode": "stall-max", "reverse": true,