diff --git a/exercises/static/exercises/marker_visual_loc/python_template/ros2_humble/HAL.py b/exercises/static/exercises/marker_visual_loc/python_template/ros2_humble/HAL.py index 2ec725fdd..a8a5c455e 100644 --- a/exercises/static/exercises/marker_visual_loc/python_template/ros2_humble/HAL.py +++ b/exercises/static/exercises/marker_visual_loc/python_template/ros2_humble/HAL.py @@ -24,12 +24,14 @@ def __auto_spin() -> None: motor_node = MotorsNode("/turtlebot3/cmd_vel", 4, 0.3) camera_node = CameraNode("/turtlebot3/camera/image_raw") odometry_node = OdometryNode("/turtlebot3/odom") +laser_node = LaserNode("/turtlebot3/laser/scan") noisy_odometry_node = NoisyOdometryNode("/turtlebot3/odom") # Spin nodes so that subscription callbacks load topic data executor = rclpy.executors.MultiThreadedExecutor() executor.add_node(camera_node) executor.add_node(odometry_node) +executor.add_node(laser_node) executor.add_node(noisy_odometry_node) executor_thread = threading.Thread(target=__auto_spin, daemon=True) @@ -59,6 +61,12 @@ def getImage(): image = camera_node.getImage() return image.data +# Laser +def getLaserData(): + laser_data = laser_node.getLaserData() + while len(laser_data.values) == 0: + laser_data = laser_node.getLaserData() + return laser_data ### SETTERS ### diff --git a/exercises/static/exercises/marker_visual_loc/react-components/SpecificVisualLoc.js b/exercises/static/exercises/marker_visual_loc/react-components/SpecificVisualLoc.js index 6e5578031..22f6e6da6 100644 --- a/exercises/static/exercises/marker_visual_loc/react-components/SpecificVisualLoc.js +++ b/exercises/static/exercises/marker_visual_loc/react-components/SpecificVisualLoc.js @@ -7,7 +7,7 @@ import RobotBlue from "../resources/images/robot_blue.svg"; import house from "../resources/images/map.png"; -import "./css/GUICanvas.css" +import "./css/GUICanvas.css"; function SpecificVisualLoc(props) { const [realPose, setRealPose] = React.useState(null) const [noisyPose, setNoisyPose] = React.useState(null) @@ -15,6 +15,7 @@ function SpecificVisualLoc(props) { const [realPath, setRealPath] = React.useState("") const [noisyPath, setNoisyPath] = React.useState("") const [userPath, setUserPath] = React.useState("") + const [resizedBeacons, setResizedBeacons] = React.useState({}) var realTrail = []; var noisyTrail = []; var userTrail = []; @@ -25,12 +26,30 @@ function SpecificVisualLoc(props) { const timeout = 40; + const beacons = [ + { id: "tag_0", x: 518.75, y: 270.325, type: "hor" }, + { id: "tag_1", x: 481.4, y: 810.775, type: "hor" }, + { id: "tag_2", x: 196.395, y: 339.15, type: "vert" }, + { id: "tag_3", x: 400.89, y: 79.9, type: "hor" }, + { id: "tag_4", x: 844.94, y: 712.3, type: "vert" }, + { id: "tag_5", x: 295.03, y: 499.8, type: "vert" }, + { id: "tag_6", x: 730.4, y: 350.55, type: "hor" }, + { id: "tag_7", x: 499.66, y: 140.25, type: "vert" }, + ]; + const resizeObserver = new ResizeObserver((entries) => { var img = entries[0].target; //or however you get a handle to the IMG var width = (img.clientWidth / 1012); var height = (img.clientHeight / 1012); + setResizedBeacons(beacons.map(beacon => ({ + id: beacon.id, + x: beacon.x * width, + y: beacon.y * height, + type: beacon.type, + }))) + updatePath(realTrail, setRealPath, height, width); updatePath(noisyTrail, setNoisyPath, height, width); updatePath(userTrail, setUserPath, height, width); @@ -135,6 +154,17 @@ function SpecificVisualLoc(props) { realTrail=[] noisyTrail=[] userTrail=[] + + var img = document.getElementById('gui-canvas'); + //or however you get a handle to the IMG + var width = (img.clientWidth / 1012); + var height = (img.clientHeight / 1012); + setResizedBeacons(beacons.map(beacon => ({ + id: beacon.id, + x: beacon.x * width, + y: beacon.y * height, + type: beacon.type, + }))) } catch (error) { } } @@ -195,12 +225,26 @@ function SpecificVisualLoc(props) { /> } + {Object.values(resizedBeacons).map((beacon) => { + return( +
+ )})}
); } -SpecificVisualLoc.propTypes = { - circuit: PropTypes.string, -}; - export default SpecificVisualLoc; \ No newline at end of file diff --git a/exercises/static/exercises/marker_visual_loc/react-components/css/GUICanvas.css b/exercises/static/exercises/marker_visual_loc/react-components/css/GUICanvas.css index 738e7a401..a69d8378c 100644 --- a/exercises/static/exercises/marker_visual_loc/react-components/css/GUICanvas.css +++ b/exercises/static/exercises/marker_visual_loc/react-components/css/GUICanvas.css @@ -38,4 +38,23 @@ height: 20px; border-radius: 10px; transition: left 0.1s ease-out, top 0.1s ease-out +} + +.beacon { + position: absolute; + border: 2px solid rgb(255, 255, 255); + cursor: pointer; + z-index: 5; +} + +.beacon-vert { + width: 0px; + height: 20px; + translate: 0 -10px; +} + +.beacon-hor { + width: 20px; + height: 0px; + translate: -10px; } \ No newline at end of file