From e1f6a027447a9e5614c39766364da835d2a8c8d7 Mon Sep 17 00:00:00 2001 From: Kostya Bats Date: Sat, 9 Dec 2023 17:04:11 +0300 Subject: [PATCH] Fix locator positions --- .../molecules/info/ContestantViewCorner.jsx | 2 +- .../components/organisms/widgets/Locator.jsx | 15 ++++---- .../main/kotlin/org/icpclive/sniper/Admin.kt | 8 ++++- .../org/icpclive/sniper/SniperColibrator.kt | 35 ++++++++++--------- .../kotlin/org/icpclive/sniper/SniperMover.kt | 6 ++-- .../main/kotlin/org/icpclive/sniper/Util.kt | 29 ++++++++++----- 6 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/frontend/overlay/src/components/molecules/info/ContestantViewCorner.jsx b/src/frontend/overlay/src/components/molecules/info/ContestantViewCorner.jsx index ebfd4d25a..38d29b7bb 100644 --- a/src/frontend/overlay/src/components/molecules/info/ContestantViewCorner.jsx +++ b/src/frontend/overlay/src/components/molecules/info/ContestantViewCorner.jsx @@ -25,7 +25,7 @@ const TaskRow = styled.div` grid-column-end: 3; `; -const CornerContestantInfo = styled(ContestantInfo)` +export const CornerContestantInfo = styled(ContestantInfo)` grid-column-start: 1; grid-column-end: 3; `; diff --git a/src/frontend/overlay/src/components/organisms/widgets/Locator.jsx b/src/frontend/overlay/src/components/organisms/widgets/Locator.jsx index eee15655f..755e802c3 100644 --- a/src/frontend/overlay/src/components/organisms/widgets/Locator.jsx +++ b/src/frontend/overlay/src/components/organisms/widgets/Locator.jsx @@ -1,6 +1,6 @@ import React from "react"; import styled, { keyframes } from "styled-components"; -import { ContestantViewCorner } from "../../molecules/info/ContestantViewCorner"; +import { ContestantViewCorner, CornerContestantInfo } from "../../molecules/info/ContestantViewCorner"; const slideIn = keyframes` from { @@ -66,7 +66,7 @@ export const Locator = ({ widgetData, transitionState }) => { {circles.map((circle, index) => { - let left = circle.x - 540 / 2; + let left = circle.x - 343 / 2; let top; if (circle.y - circle.radius - 50 > 10) { top = circle.y - circle.radius - 50; @@ -75,10 +75,10 @@ export const Locator = ({ widgetData, transitionState }) => { } if (left < 0) { left = 0; - } else if (left + 540 > 1920) { - left = 1920 - 540; + } else if (left + 343 > 1920) { + left = 1920 - 343; } - let len = Math.sqrt((left + 540 / 2 - circle.x) * (left + 540 / 2 - circle.x) + + let len = Math.sqrt((left + 343 / 2 - circle.x) * (left + 343 / 2 - circle.x) + (top + 10 - circle.y) * (top + 10 - circle.y)); return
@@ -88,7 +88,8 @@ export const Locator = ({ widgetData, transitionState }) => { animation={transitionState === "exiting" ? slideOut : slideIn} animationStyle={transitionState === "exiting" ? "ease-in" : "ease-out"} duration={(index + 1) * 1500}> - + + {/**/} @@ -97,7 +98,7 @@ export const Locator = ({ widgetData, transitionState }) => { duration={(index + 1) * 1500 - 500}> + d={`M ${circle.x + (left + 343 / 2 - circle.x) / len * circle.radius} ${circle.y + (top + 10 - circle.y) / len * circle.radius} L ${left + 343 / 2} ${top + 10}`}/>
; diff --git a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Admin.kt b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Admin.kt index baa865871..472894586 100644 --- a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Admin.kt +++ b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Admin.kt @@ -11,10 +11,12 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.serializer +import org.icpclive.util.getLogger fun Route.setupRouting() { post("/move") { call.adminApiAction { + logger.info("hello!!!") val request = call.receive() SniperMover.moveToTeam(request.sniperId, request.teamId) Unit @@ -25,7 +27,7 @@ fun Route.setupRouting() { call.adminApiAction { val request = call.receive() val locatorSettings = LocatorController.getLocatorWidgetConfig(request.sniperId, setOf(request.teamId)) - println("request: " + "${config.overlayURL}api/admin/teamLocator/show_with_settings") + println("request: " + "${config.overlayURL}/api/admin/teamLocator/show_with_settings") val showRequest = Util.httpClient.post("${config.overlayURL}/api/admin/teamLocator/show_with_settings") { setBody(Json.encodeToString(locatorSettings)) contentType(ContentType.Application.Json) @@ -78,5 +80,9 @@ suspend inline fun ApplicationCall.adminApiAction( ) } } catch (e: Exception) { + logger.info("Failed to run admin call $e") + println("Failed to run admin call ${e.message}") respond(HttpStatusCode.BadRequest, mapOf("status" to "error", "message" to e.message)) } + +val logger = getLogger(ApplicationCall::class) diff --git a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperColibrator.kt b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperColibrator.kt index d200f622a..0256cb622 100644 --- a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperColibrator.kt +++ b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperColibrator.kt @@ -17,12 +17,14 @@ import javax.swing.ImageIcon import javax.swing.JFrame import javax.swing.JLabel import javax.swing.WindowConstants +import kotlin.io.path.bufferedReader import kotlin.math.abs import kotlin.math.sign import kotlin.math.sqrt import kotlin.system.exitProcess -class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, KeyListener { +class SniperCalibrator(private val url: String, private val configPath: Path) : MJpegViewer, MouseListener, + KeyListener { private var image: Image? = null var pan = 0.0 var tilt = 0.0 @@ -30,7 +32,7 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke private val points: MutableList = ArrayList() var frame: JFrame? = null var label: JLabel? = null - var currentTeam = -1 + var currentTeam = "" var currentTeamMonitor = Object() private fun run() { try { @@ -39,14 +41,14 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke synchronized(currentTeamMonitor) { while (true) { println("Input team id:") - currentTeam = `in`.nextInt() - if (currentTeam == -1) { + currentTeam = `in`.next() + if (currentTeam == "") { points.clear() locations.clear() continue } println("Now locate team $currentTeam") - while (currentTeam != -1) { + while (currentTeam != "") { currentTeamMonitor.wait() } } @@ -151,15 +153,15 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke } class Position { - var id: Int + var id: String var p: LocatorPoint - constructor(id: Int, x: Int, y: Int) { + constructor(id: String, x: Int, y: Int) { this.id = id p = LocatorPoint(x.toDouble(), y.toDouble(), 0.0) } - constructor(id: Int, p: LocatorPoint) { + constructor(id: String, p: LocatorPoint) { this.id = id this.p = p } @@ -170,14 +172,14 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke @Throws(IOException::class) fun readInput() { - val reader = BufferedReader(FileReader("config/icpc-nef/2022-2023/input.txt")) + val reader = configPath.resolve("input.txt").bufferedReader() var x = 0 while (true) { val s = reader.readLine() ?: break val ss = s.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() for (y in ss.indices) { try { - val id = ss[y].toInt() + val id = ss[y] input.add(Position(id, x, y)) } catch (ignored: NumberFormatException) { } @@ -190,7 +192,7 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke if (locations.size < 4) return val from: MutableList = ArrayList() val to: MutableList = ArrayList() - val mp: MutableMap = HashMap() + val mp: MutableMap = HashMap() for (position in input) { mp[position.id] = position } @@ -265,7 +267,7 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke } points.clear() try { - val out = PrintWriter("output.txt") + val out = PrintWriter(configPath.resolve("output.txt").toFile()) out.println(input.size) for (i in input.indices) { val xc = input[i].p.x @@ -284,7 +286,7 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke fun click(x: Int, y: Int) { synchronized(currentTeamMonitor) { - if (currentTeam == -1) return + if (currentTeam == "") return val p = LocatorPoint(x.toDouble(), y.toDouble(), WIDTH / angle) .move(LocatorPoint((-WIDTH / 2).toDouble(), (-HEIGHT / 2).toDouble(), 0.0)) .multiply(angle / WIDTH) @@ -294,7 +296,7 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke } points.add(p) locations.add(Position(currentTeam, p)) - currentTeam = -1 + currentTeam = "" recalculate() val g = image!!.graphics as Graphics2D draw(g) @@ -320,10 +322,11 @@ class SniperCalibrator(private val url: String) : MJpegViewer, MouseListener, Ke @Throws(FileNotFoundException::class) @JvmStatic fun main(args: Array) { - Util.initForCalibrator("config/icpc-nef/2022-2023/snipers.txt", Path.of("config/icpc-nef/2022-2023")) + val configPath = Path.of("config/sniper-test") + Util.initForCalibrator(configPath.resolve("snipers.txt").toString(), configPath) println("Select sniper (1-" + Util.snipers.size + ")") val sniper = `in`.nextInt() - SniperCalibrator(Util.snipers[sniper - 1].hostName).run() + SniperCalibrator(Util.snipers[sniper - 1].hostName, configPath).run() } } } diff --git a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperMover.kt b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperMover.kt index 99759e034..a9ffc912a 100644 --- a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperMover.kt +++ b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/SniperMover.kt @@ -27,6 +27,7 @@ object SniperMover { private const val DEFAULT_SPEED = "0.52" suspend fun moveToTeam(sniperNumber: Int, teamId: String): LocatorPoint? { + println("moveToTeam $sniperNumber $teamId") val point = getLocationPointByTeam(sniperNumber, teamId) ?: return null if (point.y > 0) { @@ -48,7 +49,8 @@ object SniperMover { } private fun getLocationPointByTeam(sniperNumber: Int, teamId: String): LocatorPoint? { - return Util.loadLocatorPoints(sniperNumber).find { it.id == teamId } + val x = Util.loadLocatorPoints(sniperNumber).find { it.id == teamId } + return x } @Throws(Exception::class) @@ -72,5 +74,5 @@ object SniperMover { logger.info("Set sniper $sniper speed: $setSpeedResponse") } - private val logger = getLogger(this::class) + private val logger = getLogger(SniperMover::class) } diff --git a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Util.kt b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Util.kt index 9bb57d5aa..3d8bd4447 100644 --- a/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Util.kt +++ b/src/sniper-locator-controller/src/main/kotlin/org/icpclive/sniper/Util.kt @@ -12,6 +12,7 @@ import java.io.File import java.nio.file.Path import java.text.SimpleDateFormat import java.util.* +import kotlin.io.path.readText object Util { val httpClient = HttpClient(CIO) { @@ -73,24 +74,34 @@ object Util { return LocatorConfig(newPan, newTilt, newAngle) } - fun loadLocatorPoints(sniperNumber: Int): List { - val scanner = Scanner(Config.configDirectory.resolve("coordinates-$sniperNumber.txt").toFile()) + fun loadLocatorPoints(sniperNumber: Int): List { + val x = config.configDirectory.resolve("coordinates-$sniperNumber.txt") + println(x.readText()) + val scanner = Scanner(x) val n = scanner.nextInt() val allPoints = mutableListOf() for (i in 1..n) { - val point = LocatorPoint( - scanner.next(), - scanner.nextDouble(), - scanner.nextDouble(), - scanner.nextDouble() - ) - allPoints.add(point) + try { + val point = LocatorPoint( + scanner.next(), + scanner.nextDouble(), + scanner.nextDouble(), + scanner.nextDouble() + ) + println("$point") + allPoints.add(point) + + } catch (e: Throwable) { + println("sooo bad $e") + } + } return allPoints } private fun init(snipersPath: String, configDir: Path) { + Locale.setDefault(Locale.US) val inp = Scanner(File(snipersPath)) val m = inp.nextInt() val urls = Array(m) { inp.next() }