diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..69385c02 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,78 @@ +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 && \ + 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 && \ + make install && \ + ldconfig + + +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 \ + xvfb \ + x11vnc \ + x11-utils \ + && 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..d897186c --- /dev/null +++ b/docker-entry.sh @@ -0,0 +1,60 @@ +#!/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 "$HOME/.vnc" + x11vnc -storepasswd "${VNC_PASSWORD}" "$HOME/.vnc/passwd" + + export DISPLAY=:99 + + 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 "$DISPLAY" -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