diff --git a/install_mirte.sh b/install_mirte.sh index 798a0f8..06c0919 100755 --- a/install_mirte.sh +++ b/install_mirte.sh @@ -122,6 +122,13 @@ sudo systemctl disable --now unattended-upgrades.service || true # either no net # update time in /etc/fake-hwclock.data sudo fake-hwclock save +# mark some apt packages as hold to not break when upgrading +# when using overlay, we don't want to update the kernel, as it will break some things +# updates are in the overlay, while kernel is started from underlay. + +# wildcards and non-existing packages are ignored, so this is safe to run on all images. +sudo apt-mark hold "linux-dtb-*" "linux-image-*" "linux-u-boot-*" "linux-headers-*" "armbian-plymouth-theme" "armbian-firmware" + # remove force ipv4 sudo rm /etc/apt/apt.conf.d/99force-ipv4 || true sudo rm /etc/resolv.conf || true # remove resolv.conf to use the one from the network. diff --git a/install_mirte_master.sh b/install_mirte_master.sh index 6ebf0ff..d999481 100755 --- a/install_mirte_master.sh +++ b/install_mirte_master.sh @@ -18,17 +18,25 @@ mkdir build cd build cmake .. make -j -sudo ln -s $MIRTE_SRC_DIR/mirte-install-scripts/services/mirte-usb-switch.service /lib/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl stop mirte-usb-switch.service || /bin/true -sudo systemctl start mirte-usb-switch.service -sudo systemctl enable mirte-usb-switch.service - -sudo ln -s $MIRTE_SRC_DIR/mirte-install-scripts/services/mirte-shutdown.service /lib/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl stop mirte-shutdown.service || /bin/true -sudo systemctl start mirte-shutdown.service -sudo systemctl enable mirte-shutdown.service + +function add_service() { + service_name=$1 + # check if service file exists in install scripts, if not, exit with error + if [[ ! -f $MIRTE_SRC_DIR/mirte-install-scripts/services/$service_name ]]; then + echo "Service file $service_name does not exist in $MIRTE_SRC_DIR/mirte-install-scripts/services/" + exit 1 + fi + sudo rm -f /lib/systemd/system/$service_name + sudo ln -s $MIRTE_SRC_DIR/mirte-install-scripts/services/$service_name /lib/systemd/system/ + sudo systemctl daemon-reload + sudo systemctl stop $service_name || /bin/true + sudo systemctl start $service_name + sudo systemctl enable $service_name +} + +add_service mirte-battery-watcher.service # check that battery is not empty and shutdown if it is +add_service mirte-shutdown.service # show a message on the screen when shutting down and trigger a shutdown of the robot +add_service mirte-usb-switch.service # turn on/off depth cam usb port. # create a gpio group and add mirte to it. This is needed to access the gpio ports, otherwise only sudo is allowed. sudo groupadd gpiod @@ -41,19 +49,6 @@ pip install gpiod==1.5.4 # python3.8 version pip install gtts playsound openai==0.28.0 sounddevice scipy SpeechRecognition soundfile transformers datasets pyyaml pydub Elevenlabs || true # some strange package versions pip install numpy==1.23.1 # python3.8 fix -# mkdir ~/uboot_fix/ -# cd ~/uboot_fix/ -# # audio fix uboot for orange pi 3b -# if [[ ${type:=""} == "mirte_orangepi3b" ]]; then -# wget https://mirte.arend-jan.com/files/fixes/uboot/linux-u-boot-orangepi3b-edge_24.2.1_arm64__2023.10-S095b-P0000-H264e-V49ed-B11a8-R448a.deb -# sudo apt install ./linux-u-boot-orangepi3b-edge_24.2.1_arm64__2023.10-S095b-P0000-H264e-V49ed-B11a8-R448a.deb -# rm linux-u-boot-orangepi3b-edge_24.2.1_arm64__2023.10-S095b-P0000-H264e-V49ed-B11a8-R448a.deb -# cd ../ -# rm -rf uboot_fix/ -# fi - -# cd ~/mirte_ws/src -# git clone --recurse-submodules https://github.com/arendjan/mirte-telemetrix-cpp.git cd ~/mirte_ws source /opt/ros/humble/setup.bash rosdep install -y --from-paths src/ --ignore-src --rosdistro humble diff --git a/install_web.sh b/install_web.sh index 2b68c20..d8aa937 100755 --- a/install_web.sh +++ b/install_web.sh @@ -9,17 +9,17 @@ sudo apt update || true sudo apt install -y python3-pip python3-setuptools python3-wheel sudo -H pip install nodeenv -# Install backend (node 18.0) -nodeenv --node=18.0.0 $MIRTE_SRC_DIR/mirte-web-interface/node_env +# TODO: around april 2027, update node versions. +# Newer nodeenv (1.11?) will have option for --node=22 instead of exact version +nodeenv --node=22.12.0 $MIRTE_SRC_DIR/mirte-web-interface/node_env . $MIRTE_SRC_DIR/mirte-web-interface/node_env/bin/activate + +# Install backend packages cd $MIRTE_SRC_DIR/mirte-web-interface/nodejs-backend || exit 1 npm install . -deactivate_node -# Install frontend (node 22.12) +# Build front-end cd $MIRTE_SRC_DIR/mirte-web-interface/vue-frontend || exit 1 -nodeenv --node=22.12.0 $MIRTE_SRC_DIR/mirte-web-interface/vue-frontend/node_env -. $MIRTE_SRC_DIR/mirte-web-interface/vue-frontend/node_env/bin/activate npm install NUXT_APP_BASE_URL=/ npm run generate rm -rf node_modules || true diff --git a/services/mirte-battery-watcher.service b/services/mirte-battery-watcher.service new file mode 100644 index 0000000..feb5292 --- /dev/null +++ b/services/mirte-battery-watcher.service @@ -0,0 +1,13 @@ +[Unit] +Description=Mirte-shutdown +After=mirte-ros.service + +[Service] +User=mirte +Type=oneshot +RemainAfterExit=true +ExecStart=/usr/local/src/mirte/mirte-install-scripts/services/mirte_battery_watcher.sh +TimeoutSec=30 +[Install] +WantedBy=multi-user.target +WantedBy=mirte-ros.service diff --git a/services/mirte-shutdown.service b/services/mirte-shutdown.service old mode 100755 new mode 100644 index fa425d8..7859acd --- a/services/mirte-shutdown.service +++ b/services/mirte-shutdown.service @@ -6,7 +6,6 @@ After=mirte-ros.service User=mirte Type=oneshot RemainAfterExit=true -ExecStart=/usr/local/src/mirte/mirte-install-scripts/services/mirte_boot.sh ExecStop=/usr/local/src/mirte/mirte-install-scripts/services/mirte_shutdown.sh TimeoutSec=30 [Install] diff --git a/services/mirte-usb-switch.service b/services/mirte-usb-switch.service old mode 100755 new mode 100644 diff --git a/services/mirte_battery_watcher.sh b/services/mirte_battery_watcher.sh new file mode 100755 index 0000000..e1cbd45 --- /dev/null +++ b/services/mirte_battery_watcher.sh @@ -0,0 +1,89 @@ +#!/bin/bash +set -x +. /home/mirte/.mirte_settings.sh +. /opt/ros/humble/setup.bash +. /home/mirte/mirte_ws/install/setup.bash +SECONDS=0 +LAST_SECONDS=0 +WARN_LVL=0 + +# if battery <= 10%, shutdown in 2 min. +# otherwise if longer than 15 min no message, shutdown. + +mirte_space=$(cat /etc/hostname | tr '[:upper:]' '[:lower:]' | tr '-' '_') +BATTERY_FILE=/tmp/batteryState +STOP=false +trap 'echo "Stopping mirte_master_check"; kill $ECHO_PID; STOP=true' SIGTERM SIGINT +# ros2 topic echo restarts when the topic appears again, so we can just echo always +# on every check, it will read the file, take the last reading and then clear the file +# if the sensor is off, then the file will be empty and will trigger shutdown after some time. +topic=/io/power/power_watcher +if [ "$MIRTE_USE_MULTIROBOT" = "true" ]; then + topic=/$mirte_space/io/power/power_watcher +fi +ros2 topic echo $topic sensor_msgs/msg/BatteryState --field percentage >$BATTERY_FILE & +ECHO_PID=$! +while ! systemctl list-jobs | grep -q -E 'shutdown.target.*start' && ! $STOP; do + OK=false + # echo "topics" + percentage=$( + tail -2 $BATTERY_FILE | head -1 + ) || true + echo $percentage + true >$BATTERY_FILE + # percentage=$(echo "$percentage" | tail -1) + # echo $percentage + # echo $( echo $percentage | wc -c) + if [ "$(echo $percentage | wc -c)" -gt 1 ]; then + # echo "percentage" + percentage=$(echo "$percentage" | awk '{print $NF}') + # echo $percentage + if (($(echo "$percentage > 0.1" | bc -l))); then + OK=true + elif (($(echo "$percentage <= 0.1" | bc -l))); then + wall "Battery is low, shutting down in 2min" + date >>/home/mirte/.shutdown_battery + sudo shutdown +2 + STOP=true + fi + fi + + if $OK; then + # echo "latest percentage: " + # echo $percentage + SECONDS=0 # update time since last ok + LAST_SECONDS=0 + WARN_LVL=0 + fi + # if there is a time jump and seconds is more than last_seconds+2, reset seconds + # time jumps happen when the time is updated (on connecting to wifi) + next_second=$((LAST_SECONDS + 20)) + if [ $SECONDS -gt $next_second ]; then + echo "time jump" + SECONDS=0 + LAST_SECONDS=0 + WARN_LVL=0 + fi + LAST_SECONDS=$SECONDS + + if [ $SECONDS -gt 300 ] && [ $WARN_LVL -eq 0 ]; then + wall "No ROS for longer than 5min" + WARN_LVL=1 + fi + if [ $SECONDS -gt 600 ] && [ $WARN_LVL -eq 1 ]; then + wall "No ROS for longer than 10min, shutting down in 5min" + WARN_LVL=2 + fi + if [ $SECONDS -gt 900 ] && [ $WARN_LVL -eq 2 ]; then + wall "shutting down" + WARN_LVL=3 + date >>/home/mirte/.shutdown_power + sudo shutdown now + STOP=true + fi + sleep 10 +done + +kill $ECHO_PID || true +jobs -p +ros2 daemon stop || true # deamon is sometimes started by ros2 topic echo, otherwise the shutdown will get stuck and wait for 30+ seconds diff --git a/services/mirte_boot.sh b/services/mirte_boot.sh deleted file mode 100755 index 44bf74c..0000000 --- a/services/mirte_boot.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -xe -# check if file /home/mirte/shutdown exists -if [ -f /home/mirte/.shutdown ]; then - # check if file /home/mirte/shutdown_done exists - echo "correct shutdown" - rm /home/mirte/.shutdown -else - echo "incorrect shutdown" - touch /home/mirte/.shutdown_incorrect - # append date to shutdown_incorrect file - date >>/home/mirte/.shutdown_incorrect -fi -"$(dirname "$0")/mirte_master_check.sh" &