Description
Next, we need to set up auto-start for the relevant programs and dependencies, so we don't have to manually run the relevant programs every time we start up.
Create Startup Script
bash
cd ~/RoboTamerSdk4Qmini/bin && vim boot.sh1
Write the following content:
Special Attention
- The
Wireless Controllerin the script is the Bluetooth controller's device name. If your controller has a different name, please modify it to the actual device name. - Every time the script runs, it generates a new log file in the
/home/lckfb/robot-logs/directory. The file name includes the current date and time to ensure logs are not overwritten. - The script automatically checks log file size and performs rotation when it exceeds the specified size, while retaining a certain number of historical log files to avoid excessive disk space usage.
shell
#!/bin/bash
# ============================================================
# Qmini Robot Startup Script - With Log Rotation Management
# ============================================================
set -e
# Configuration parameters
LOG_DIR="/home/lckfb/robot-logs"
MAX_LOG_SIZE_MB=50 # Maximum single log file size (MB)
MAX_LOG_FILES=50 # Maximum number of log files to retain
LOG_ROTATE_INTERVAL=3600 # Log rotation check interval (seconds)
# Very important! Very important! Very important!
# Set XDG_RUNTIME_DIR environment variable
# Otherwise DDS communication will be abnormal
export XDG_RUNTIME_DIR=/run/user/$(id -u)
# Create log directory
mkdir -p "$LOG_DIR"
# Log rotation function
rotate_log_if_needed() {
local log_file="$1"
if [ ! -f "$log_file" ]; then
return 0
fi
local size_mb=$(du -m "$log_file" 2>/dev/null | cut -f1)
if [ "$size_mb" -ge "$MAX_LOG_SIZE_MB" ]; then
local timestamp=$(date +%Y%m%d_%H%M%S)
local rotated_file="${log_file%.log}_${timestamp}.log"
mv "$log_file" "$rotated_file"
gzip "$rotated_file" 2>/dev/null || true
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Log rotated: $rotated_file.gz"
fi
}
# Cleanup old logs function
cleanup_old_logs() {
local file_count=$(find "$LOG_DIR" -name "*.log" -o -name "*.log.gz" 2>/dev/null | wc -l)
if [ "$file_count" -gt "$MAX_LOG_FILES" ]; then
local delete_count=$((file_count - MAX_LOG_FILES))
find "$LOG_DIR" -name "*.log" -o -name "*.log.gz" 2>/dev/null | \
sort | head -n "$delete_count" | xargs rm -f 2>/dev/null || true
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Cleaned up $delete_count old log files"
fi
}
# Background log rotation daemon
start_log_daemon() {
local log_file="$1"
local pid_file="$LOG_DIR/.log_daemon.pid"
# If a daemon is already running, stop it first
if [ -f "$pid_file" ]; then
local old_pid=$(cat "$pid_file")
if kill -0 "$old_pid" 2>/dev/null; then
kill "$old_pid" 2>/dev/null || true
fi
rm -f "$pid_file"
fi
# Start new daemon
(
while true; do
sleep "$LOG_ROTATE_INTERVAL"
rotate_log_if_needed "$log_file"
cleanup_old_logs
done
) &
echo $! > "$pid_file"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Log daemon started (PID: $(cat $pid_file))"
}
# Wait for PS4 controller
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Waiting for PS4 controller..."
while ! grep -ql "Wireless Controller" /sys/class/input/event*/device/name 2>/dev/null; do
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Controller not found, retrying in 5s..."
sleep 5
done
echo "[$(date '+%Y-%m-%d %H:%M:%S')] PS4 controller connected!"
# Generate log file name
LOG_TIME=$(date +%Y_%m_%d-%H)
LOG_FILE="$LOG_DIR/run_interface_$(date +%Y%m%d_%H%M%S).log"
cd /home/lckfb/RoboTamerSdk4Qmini/bin/
# Print startup information
echo "============================================================"
echo "Qmini Robot Control System"
echo "Start Time: $(date '+%Y-%m-%d %H:%M:%S')"
echo "Log File: $LOG_FILE"
echo "Max Log Size: ${MAX_LOG_SIZE_MB}MB"
echo "Max Log Files: $MAX_LOG_FILES"
echo "============================================================"
# Start log rotation daemon
start_log_daemon "$LOG_FILE"
# Cleanup old logs
cleanup_old_logs
# Run main program
exec stdbuf -oL -eL /home/lckfb/RoboTamerSdk4Qmini/bin/run_interface 2>&1 | tee "$LOG_FILE"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Add executable permission:
bash
chmod +x ~/RoboTamerSdk4Qmini/bin/boot.sh1
Create Qmini System Service
bash
sudo vim /etc/systemd/system/qmini.service1
Write the following content:
bash
[Unit]
Description=Qmini Interface Service
After=bluetooth.target
Before=shutdown.target
[Service]
ExecStart=/home/lckfb/RoboTamerSdk4Qmini/bin/boot.sh
ExecStop=/bin/true
Restart=on-failure
User=lckfb
WorkingDirectory=/home/lckfb/RoboTamerSdk4Qmini/bin
[Install]
WantedBy=multi-user.target1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Start the service:
bash
sudo systemctl daemon-reload
sudo systemctl enable qmini.service
sudo systemctl start qmini.service1
2
3
2
3
Check if the service is running normally:
bash
sudo systemctl status qmini.service1
Create Independent Root Service to Handle lo Multicast
Description
Since the multicast option on the lo interface requires root permission to modify, we need to create an independent system service to handle this issue, ensuring that the multicast function of lo is enabled before the Qmini service starts.
bash
sudo vim /etc/systemd/system/lo-multicast.service1
Write the following content:
bash
[Unit]
Description=Enable multicast on loopback
After=network.target
Before=qmini.service
[Service]
Type=oneshot
ExecStart=/sbin/ip link set lo multicast on
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Start the service:
bash
sudo systemctl daemon-reload
sudo systemctl enable lo-multicast.service
sudo systemctl start lo-multicast.service1
2
3
2
3
Check if the service is running normally:
bash
systemctl status lo-multicast.service1