From 42ab654838a423823c29612f491a2f7d5816ba6e Mon Sep 17 00:00:00 2001 From: Thassio Silva Date: Tue, 23 Dec 2025 16:28:07 -0300 Subject: [PATCH 1/2] fix(config): make robot ini lookup work after install When installed to /usr/local/bin, applicationDirPath changes and ../config is not valid. Add fallback search paths (e.g., /usr/local/share/grsim/config) to prevent default robot geometry. --- Dockerfile | 74 +++++++++++++ docker-entry.sh | 45 ++++++++ firasim.xml | 258 +++++++++++++++++++++++++++++++++++++++++++ src/configwidget.cpp | 61 +++++++--- 4 files changed, 421 insertions(+), 17 deletions(-) create mode 100644 Dockerfile create mode 100755 docker-entry.sh create mode 100644 firasim.xml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..8936ba5b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,74 @@ +FROM ubuntu:20.04 AS build +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + git \ + ca-certificates \ + build-essential \ + cmake \ + pkg-config \ + qt5-default \ + libqt5opengl5-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libprotobuf-dev \ + protobuf-compiler \ + libode-dev \ + libboost-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /vartypes +RUN git clone https://github.com/jpfeltracco/vartypes.git . && \ + git checkout 2d16e81b7995f25c5ba5e4bc31bf9a514ee4bc42 && \ + mkdir -p build && \ + cd build && \ + cmake .. && \ + make -j"$(nproc)" && \ + make install && \ + ldconfig + +WORKDIR /firasim +COPY cmake /firasim/cmake +COPY config /firasim/config +COPY include /firasim/include +COPY resources /firasim/resources +COPY formation /firasim/formation +COPY msg /firasim/msg +COPY src /firasim/src +COPY CMakeLists.txt README.md LICENSE.md INSTALL.md AUTHORS.md CHANGELOG.md /firasim/ + +RUN mkdir -p /usr/local/share/firasim +COPY firasim.xml /usr/local/share/firasim/grsim.xml + +RUN mkdir -p /usr/local/share/grsim/config +COPY config/*.ini /usr/local/share/grsim/config/ + +RUN mkdir -p build && \ + cd build && \ + cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && \ + make -j"$(nproc)" && \ + make install + +FROM ubuntu:20.04 +ENV DEBIAN_FRONTEND=noninteractive \ + LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib + +RUN apt-get update && apt-get install -y --no-install-recommends \ + tini \ + qt5-default \ + libqt5opengl5 \ + libode8 \ + libprotobuf17 \ + x11vnc xvfb \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build /usr/local /usr/local + +RUN useradd -ms /bin/bash default +COPY docker-entry.sh /docker-entry.sh +RUN chmod 775 /docker-entry.sh + +EXPOSE 20011 30011 30012 10300 10301 10302 5900 +USER default +WORKDIR /home/default +ENTRYPOINT ["tini", "--", "/docker-entry.sh"] diff --git a/docker-entry.sh b/docker-entry.sh new file mode 100755 index 00000000..f402b4fd --- /dev/null +++ b/docker-entry.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -e + +export QT_AUTO_SCREEN_SCALE_FACTOR=0 +export QT_ENABLE_HIGHDPI_SCALING=0 +export QT_SCALE_FACTOR=1 +export QT_SCREEN_SCALE_FACTORS=1 +export QT_FONT_DPI=96 +export XFT_DPI=96 + +export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp/runtime-default}" +mkdir -p "$XDG_RUNTIME_DIR" || true +chmod 700 "$XDG_RUNTIME_DIR" || true + +export HOME="${HOME:-/home/default}" +if [[ ! -f "$HOME/.grsim.xml" ]]; then + cp /usr/local/share/firasim/grsim.xml "$HOME/.grsim.xml" + chmod 644 "$HOME/.grsim.xml" || true +fi + +if [[ "$1" == "vnc" ]]; then + shift + echo "Launch in VNC mode" + + : "${VNC_PASSWORD:=vncpassword}" + : "${VNC_GEOMETRY:=1280x1024}" + + mkdir -p ~/.vnc + x11vnc -storepasswd "${VNC_PASSWORD}" ~/.vnc/passwd + + export DISPLAY=:99 + Xvfb :99 -screen 0 "${VNC_GEOMETRY}x24" -dpi 96 -ac +extension GLX +render -noreset & + + /usr/local/bin/FIRASim "$@" & + + exec x11vnc -forever -shared -usepw -display :99 -rfbport 5900 -noxdamage + +elif [[ -n "$DISPLAY" ]]; then + echo "Launch with host X11 display: $DISPLAY" + exec /usr/local/bin/FIRASim "$@" + +else + echo "Launch in offscreen mode (no DISPLAY)" + exec /usr/local/bin/FIRASim -platform offscreen "$@" +fi diff --git a/firasim.xml b/firasim.xml new file mode 100644 index 00000000..5919573d --- /dev/null +++ b/firasim.xml @@ -0,0 +1,258 @@ + + + + + + Division B + + Division A + + + Division B + + + + 3 + + + + + + 0.003000 + + + 2.200000 + + + 1.800000 + + + 0.250000 + + + 0.250000 + + + 0.500000 + + + 0.150000 + + + 0.375000 + + + 0.300000 + + + 0.400000 + + + 0.025000 + + + 0.025000 + + + 0.150000 + + + 0.400000 + + + 0.050000 + + + + + 0.003000 + + + 1.500000 + + + 1.300000 + + + 0.200000 + + + 0.200000 + + + 0.700000 + + + 0.150000 + + + 0.375000 + + + 0.300000 + + + 0.400000 + + + 0.025000 + + + 0.025000 + + + 0.100000 + + + 0.400000 + + + 0.050000 + + + + + + 0.021500 + + + + Parsian + + Parsian + + + ParsianNew + + + RoboIME2012 + + + Parsian + + + ParsianNew + + + RoboIME2012 + + + + Parsian + + Parsian + + + ParsianNew + + + RoboIME2012 + + + Parsian + + + ParsianNew + + + RoboIME2012 + + + + + + + 60.000000 + + + false + + + false + + + 0.016000 + + + 9.800000 + + + true + + + + + 0.043000 + + + 0.060000 + + + 0.090000 + + + 0.500000 + + + 0.010000 + + + 0.004000 + + + 0.004000 + + + + + + 224.0.0.1 + + + 10002 + + + 20011 + + + 30011 + + + 30012 + + + 0 + + + 120 + + + + false + + + 3.000000 + + + 3.000000 + + + 2.000000 + + + false + + + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + diff --git a/src/configwidget.cpp b/src/configwidget.cpp index fdf40db3..aad341b8 100644 --- a/src/configwidget.cpp +++ b/src/configwidget.cpp @@ -216,22 +216,49 @@ void ConfigWidget::loadRobotsSettings() void ConfigWidget::loadRobotSettings(const QString&& team) { - QString ss = qApp->applicationDirPath()+QString("/../config/")+QString("%1.ini").arg(team); + const QString iniName = QString("%1.ini").arg(team); + QStringList candidates; + + candidates << (qApp->applicationDirPath() + "/../config/" + iniName); + candidates << (qApp->applicationDirPath() + "/../share/grsim/config/" + iniName); + candidates << (QString("/usr/local/share/grsim/config/") + iniName); + candidates << (QString("/usr/local/config/") + iniName); + candidates << (qApp->applicationDirPath() + "/config/" + iniName); + candidates << (QDir::homePath() + "/.grsim/config/" + iniName); + + QString ss; + for (const auto& p : candidates) { + if (QFileInfo::exists(p)) { + ss = QDir::cleanPath(p); + break; + } + } + + if (ss.isEmpty()) { + ss = qApp->applicationDirPath() + "/../config/" + iniName; + qWarning() << "[FIRASim] Could not find robot ini for team" << team + << "Tried:" << candidates; + } else { + qDebug() << "[FIRASim] Using robot ini:" << ss; + } + + delete robot_settings; robot_settings = new QSettings(ss, QSettings::IniFormat); + robotSettings.RobotCenterFromKicker = robot_settings->value("Geometery/CenterFromKicker", 0.073).toDouble(); - robotSettings.RobotRadius = robot_settings->value("Geometery/Radius", 0.09).toDouble(); - robotSettings.RobotHeight = robot_settings->value("Geometery/Height", 0.13).toDouble(); - robotSettings.BottomHeight = robot_settings->value("Geometery/RobotBottomZValue", 0.02).toDouble(); - robotSettings.WheelRadius = robot_settings->value("Geometery/WheelRadius", 0.0325).toDouble(); - robotSettings.WheelThickness = robot_settings->value("Geometery/WheelThickness", 0.005).toDouble(); - robotSettings.Wheel1Angle = robot_settings->value("Geometery/Wheel1Angle", 60).toDouble(); - robotSettings.Wheel2Angle = robot_settings->value("Geometery/Wheel2Angle", 135).toDouble(); - robotSettings.BallRadius = robot_settings->value("Geometery/BallRadius", 0.002).toDouble(); - robotSettings.BallMass = robot_settings->value("Geometery/BallMass", 0.001).toDouble(); - - robotSettings.BodyMass = robot_settings->value("Physics/BodyMass", 2).toDouble(); - robotSettings.WheelMass = robot_settings->value("Physics/WheelMass", 0.2).toDouble(); - robotSettings.WheelTangentFriction = robot_settings->value("Physics/WheelTangentFriction", 0.8f).toDouble(); - robotSettings.WheelPerpendicularFriction = robot_settings->value("Physics/WheelPerpendicularFriction", 0.05f).toDouble(); - robotSettings.Wheel_Motor_FMax = robot_settings->value("Physics/WheelMotorMaximumApplyingTorque", 0.2f).toDouble(); -} + robotSettings.RobotRadius = robot_settings->value("Geometery/Radius", 0.09).toDouble(); + robotSettings.RobotHeight = robot_settings->value("Geometery/Height", 0.13).toDouble(); + robotSettings.BottomHeight = robot_settings->value("Geometery/RobotBottomZValue", 0.02).toDouble(); + robotSettings.WheelRadius = robot_settings->value("Geometery/WheelRadius", 0.0325).toDouble(); + robotSettings.WheelThickness = robot_settings->value("Geometery/WheelThickness", 0.005).toDouble(); + robotSettings.Wheel1Angle = robot_settings->value("Geometery/Wheel1Angle", 60).toDouble(); + robotSettings.Wheel2Angle = robot_settings->value("Geometery/Wheel2Angle", 135).toDouble(); + robotSettings.BallRadius = robot_settings->value("Geometery/BallRadius", 0.002).toDouble(); + robotSettings.BallMass = robot_settings->value("Geometery/BallMass", 0.001).toDouble(); + + robotSettings.BodyMass = robot_settings->value("Physics/BodyMass", 2).toDouble(); + robotSettings.WheelMass = robot_settings->value("Physics/WheelMass", 0.2).toDouble(); + robotSettings.WheelTangentFriction = robot_settings->value("Physics/WheelTangentFriction", 0.8).toDouble(); + robotSettings.WheelPerpendicularFriction = robot_settings->value("Physics/WheelPerpendicularFriction", 0.05).toDouble(); + robotSettings.Wheel_Motor_FMax = robot_settings->value("Physics/WheelMotorMaximumApplyingTorque", 0.2).toDouble(); +} \ No newline at end of file From 5e25371b3a5ffdcaa55a64b8cc94d02df6b0169c Mon Sep 17 00:00:00 2001 From: Thassio Silva Date: Tue, 23 Dec 2025 16:43:59 -0300 Subject: [PATCH 2/2] fix: load robot/team configs correctly in Docker installs Ship team .ini files to /usr/local/share/grsim/config and ensure ~/.grsim.xml is created from template. Prevents fallback to default robot geometry (giant robots) inside containers. --- Dockerfile | 12 ++++++++---- docker-entry.sh | 27 +++++++++++++++++++++------ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8936ba5b..69385c02 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN git clone https://github.com/jpfeltracco/vartypes.git . && \ mkdir -p build && \ cd build && \ cmake .. && \ - make -j"$(nproc)" && \ + make && \ make install && \ ldconfig @@ -46,8 +46,10 @@ COPY config/*.ini /usr/local/share/grsim/config/ RUN mkdir -p build && \ cd build && \ cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && \ - make -j"$(nproc)" && \ - make install + make && \ + make install && \ + ldconfig + FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive \ @@ -59,7 +61,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libqt5opengl5 \ libode8 \ libprotobuf17 \ - x11vnc xvfb \ + xvfb \ + x11vnc \ + x11-utils \ && rm -rf /var/lib/apt/lists/* COPY --from=build /usr/local /usr/local diff --git a/docker-entry.sh b/docker-entry.sh index f402b4fd..d897186c 100755 --- a/docker-entry.sh +++ b/docker-entry.sh @@ -18,24 +18,39 @@ if [[ ! -f "$HOME/.grsim.xml" ]]; then chmod 644 "$HOME/.grsim.xml" || true fi -if [[ "$1" == "vnc" ]]; then +if [[ "${1:-}" == "vnc" ]]; then shift echo "Launch in VNC mode" : "${VNC_PASSWORD:=vncpassword}" : "${VNC_GEOMETRY:=1280x1024}" - mkdir -p ~/.vnc - x11vnc -storepasswd "${VNC_PASSWORD}" ~/.vnc/passwd + mkdir -p "$HOME/.vnc" + x11vnc -storepasswd "${VNC_PASSWORD}" "$HOME/.vnc/passwd" export DISPLAY=:99 - Xvfb :99 -screen 0 "${VNC_GEOMETRY}x24" -dpi 96 -ac +extension GLX +render -noreset & + + Xvfb "$DISPLAY" -screen 0 "${VNC_GEOMETRY}x24" -dpi 96 -ac +extension GLX +render -noreset & + XVFB_PID=$! + + for i in $(seq 1 80); do + if xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then + break + fi + sleep 0.1 + done + + if ! xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then + echo "ERROR: Xvfb did not start on $DISPLAY" + ps aux | grep -E 'Xvfb|x11vnc|FIRASim' || true + exit 1 + fi /usr/local/bin/FIRASim "$@" & - exec x11vnc -forever -shared -usepw -display :99 -rfbport 5900 -noxdamage + exec x11vnc -forever -shared -usepw -display "$DISPLAY" -rfbport 5900 -noxdamage -elif [[ -n "$DISPLAY" ]]; then +elif [[ -n "${DISPLAY:-}" ]]; then echo "Launch with host X11 display: $DISPLAY" exec /usr/local/bin/FIRASim "$@"