Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
12a9106
Mac Fixes
dgerblick Sep 16, 2022
44d3a85
added in car.py changes for sim
Abuynits Oct 2, 2022
1b00386
fixed get_ball_velocity
Abuynits Oct 8, 2022
735353f
fixed get_ball_pose
Abuynits Oct 8, 2022
5c13d0e
added function for configuring spawn bounds and field setup
Abuynits Oct 8, 2022
8817a79
brokne
Abuynits Oct 8, 2022
fb425af
broken
Abuynits Oct 9, 2022
96970bb
no bugs?
Abuynits Oct 9, 2022
ebeb747
added function for reseting the car cmd
Abuynits Oct 9, 2022
70dcd02
cleaned up code
Abuynits Oct 9, 2022
590f995
added control gui
Abuynits Oct 11, 2022
a6adcca
removed broken callback functions and debug print statements
Abuynits Oct 16, 2022
03acfc4
add method descriptions and formated code
Abuynits Oct 16, 2022
a257646
tested car randomization
Abuynits Oct 21, 2022
3c525a7
Merge pull request #1 from purdue-arc/modular_training
jcrm1 Oct 23, 2022
f37aa8b
Remove broken/unnecessary imports
jcrm1 Oct 23, 2022
382311c
added friction to sim ball
Abuynits Oct 30, 2022
9edd8fe
Merge branch 'sim-old-config-dev' of https://github.com/Abuynits/rock…
Abuynits Oct 30, 2022
4ebf912
Add direction change reward
jcrm1 Nov 3, 2022
eef062a
Add initial direction_change reward
jcrm1 Nov 3, 2022
7d07301
Stop divide by zero
jcrm1 Nov 3, 2022
4faa79a
Typo
jcrm1 Nov 3, 2022
e41d049
Test print statements
jcrm1 Nov 3, 2022
3d611a7
Remove test print statements
jcrm1 Nov 4, 2022
d446019
Update sign check
jcrm1 Nov 5, 2022
6e0470d
Add previous model loading
jcrm1 Nov 6, 2022
b74e0a4
Update rocket_league.yaml
jcrm1 Nov 6, 2022
cbf2f50
Merge pull request #157 from purdue-arc/add_dir_change_reward
halcdev Nov 6, 2022
2608d86
Fix broken link
jcrm1 Jan 28, 2023
d0d089b
Merge branch 'Abuynits:sim-old-config-dev' into sim-old-config-dev
jcrm1 Jan 28, 2023
1e1b94f
Merge pull request #2 from purdue-arc/modular_training
jcrm1 Jan 28, 2023
154567f
Merge pull request #3 from purdue-arc/modular_training
jcrm1 Feb 1, 2023
5826970
Fix broken image URL
jcrm1 Feb 4, 2023
1299d6d
Merge pull request #160 from purdue-arc/jcrm1-fix-broken-link
dgerblick Feb 4, 2023
aed1600
rktl_perception style consistency
dgerblick Feb 4, 2023
94f1846
Update Copyright Year
dgerblick Feb 4, 2023
ee0a2cf
Make copyright disclaimer consistent
dgerblick Feb 5, 2023
1a9b9ae
undo removal of camera node from camera launch file
dgerblick Feb 7, 2023
9c5ef9a
Merge pull request #162 from purdue-arc/perception-cleanup
rtjord Feb 7, 2023
b406338
Remove unneeded double quotes
jcrm1 Feb 21, 2023
f0b9c45
Merge branch 'main' into mac-docker-fixes
dgerblick Feb 21, 2023
197e4cb
Merge remote-tracking branch 'refs/remotes/origin/mac-docker-fixes' i…
dgerblick Feb 21, 2023
ab0bd69
Merge pull request #163 from purdue-arc/mac-docker-fixes
jcrm1 Feb 21, 2023
bd2e6b6
Update hardware_interface.ino
jcrm1 Feb 22, 2023
5982d4e
Add websocket_node.py
jcrm1 Feb 25, 2023
4ffa5d6
Added websockets to dockerfile
dgerblick Feb 25, 2023
d8947ef
Update websocket_node.py
jcrm1 Feb 28, 2023
383899a
websocket_node.py: fix quitting, spinning
jcrm1 Feb 28, 2023
d04e4c0
Update websocket_node.py
jcrm1 Feb 28, 2023
673cb60
Update hardware_interface.ino
jcrm1 Feb 28, 2023
b47d267
changed float to float32
zakolano Feb 28, 2023
aba228f
Merge pull request #165 from purdue-arc/testcase-fix
dgerblick Mar 4, 2023
777206e
Merge branch 'main' into abuynits-jcrm1-sim-refactoring
dgerblick Mar 8, 2023
7a1ce74
Disabled field and car randomization to fix error
dgerblick Mar 8, 2023
09c281c
Minor Docker changes, started RTD conversion
dgerblick Mar 28, 2023
0a1a256
rktl_autonomy documentation
dgerblick Mar 28, 2023
6527712
Fix array index bug in rewards
jcrm1 Apr 1, 2023
6e93c83
Continue fixing array index bug in rewards
jcrm1 Apr 1, 2023
0dbe07b
More fixing reward type bug
jcrm1 Apr 1, 2023
b71af0f
Update rocket_league_sim.launch
jcrm1 Apr 4, 2023
1464944
Documented `rktl_game`
dgerblick Apr 9, 2023
04b2fd0
Restructuring READMEs
dgerblick Apr 10, 2023
877e131
Added templates, nodes/launch files for `rktl_game` and `rktl_launch`
dgerblick Apr 10, 2023
d7eaacd
Docker Changes to build docs
dgerblick Apr 11, 2023
bf69b41
Revert "Docker Changes to build docs"
dgerblick Apr 13, 2023
75ba586
Documentation for `rktl_planner`
dgerblick Apr 14, 2023
01dba89
Started doc-ing `rktl_sim`
dgerblick Apr 15, 2023
8c767cf
Finished writing readmes for `rktl_sim`
dgerblick Apr 15, 2023
927fa3a
rktl_autonomy node documentation
dgerblick Apr 15, 2023
6c64449
Automatic msg/srv documentation
dgerblick Apr 16, 2023
cb5cb3d
`rktl_control` documentation
dgerblick Apr 22, 2023
b6e2a53
launch files
dgerblick Apr 22, 2023
dd15505
Create docs.yml
jcrm1 Apr 22, 2023
781e739
Update docs.yml
jcrm1 Apr 22, 2023
b6f9c4e
Update docs.yml
jcrm1 Apr 22, 2023
b11f599
Update top-push.yml
jcrm1 Apr 22, 2023
3bb5c09
Merge pull request #169 from purdue-arc/new-docs
dgerblick Apr 22, 2023
2f80b96
Update top-push.yml
dgerblick Apr 22, 2023
df90268
Update README.md
dgerblick Apr 22, 2023
5a666e3
Create CNAME
dgerblick Apr 22, 2023
41e91be
Update docs.yml
dgerblick Apr 22, 2023
b51aa0e
Delete CNAME
dgerblick Apr 22, 2023
a895239
Update docs.yml
dgerblick Apr 22, 2023
c0e0cb4
Update docs.yml
dgerblick Apr 22, 2023
eec50d1
Update docs.yml
dgerblick Apr 22, 2023
60fd9f1
`rktl_perception` documentation
dgerblick Apr 23, 2023
a5f9775
Merge branch 'new-docs' of github.com:purdue-arc/rocket_league into n…
dgerblick Apr 23, 2023
e41a907
README style consistency
dgerblick Apr 23, 2023
215bda3
favicon
dgerblick Apr 23, 2023
2bc90cd
Fixed auto-generated contents on pages
dgerblick Apr 23, 2023
7a72132
Merge pull request #170 from purdue-arc/new-docs
dgerblick Apr 23, 2023
494a002
Merge branch 'main' into abuynits-jcrm1-sim-refactoring
jcrm1 Aug 26, 2023
7cf219a
Merge pull request #168 from purdue-arc/abuynits-jcrm1-sim-refactoring
jcrm1 Aug 26, 2023
4f2cad7
Merge pull request #164 from purdue-arc/car-pico-control
jcrm1 Aug 26, 2023
4b7615c
Update README.md
jcrm1 Nov 6, 2023
3e5922b
Merge pull request #174 from purdue-arc/jcrm1-patch-1
jcrm1 Nov 6, 2023
5f0545d
Update docker-run.sh
jcrm1 Nov 6, 2023
1036bd2
Merge pull request #175 from purdue-arc/jcrm1-patch-1
jcrm1 Nov 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Docs
on:
workflow_call:
inputs:
tag:
default: "latest"
required: false
type: string
permissions:
contents: write
jobs:
docs:
runs-on: ubuntu-latest
env:
DOCKER_CMD: >-
. /opt/ros/noetic/setup.zsh &&
cd catkin_ws &&
catkin build --no-status --force-color &&
. devel/setup.zsh &&
cd src/rocket_league/docs &&
pip install -r requirements.txt &&
make html -j4
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: src/rocket_league
- name: Build the local Docker image
run: ./src/rocket_league/docker/docker-build.sh --build-arg TAG=${{ inputs.tag }}
- name: Build docs
run: ./src/rocket_league/docker/docker-run.sh
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.event_name == 'push' }}
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: src/rocket_league/docs/_build/html
cname: rktl.purduearc.com
force_orphan: true
5 changes: 5 additions & 0 deletions .github/workflows/top-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ jobs:
needs: docker
if: always()
uses: purdue-arc/rocket_league/.github/workflows/catkin-build-test.yml@main
docs:
name: Build and deploy documentation
needs: docker
if: always()
uses: purdue-arc/rocket_league/.github/workflows/docs.yml@main
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ instance/

# Sphinx documentation
docs/_build/
docs/html/
docs/autoapi
docs/rosdoc/
docs/rktl_*/
~!docs/rktl_*/index.md

# PyBuilder
target/
Expand Down Expand Up @@ -145,3 +150,7 @@ dmypy.json

# macOS
.DS_Store

# docker files
/docker/.vscode-server
/docker/.zsh_history
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2020, Purdue ARC
Copyright (c) 2023, Autonomous Robotics Club of Purdue (Purdue ARC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# Rocket League
This repo contains all the files necessary for the [Rocket League project](https://wiki.purduearc.com/wiki/rocket-league/overview).
This repo contains all the files necessary for the [Rocket League project](https://www.purduearc.com/wiki/active-projects/rocket-league/).
This project aims to recreate the video game of the same name via a team of
autonomously controlled RC cars competing against human controlled ones.

The repo is broken down into several ROS packages, closely matching the system outline:

![System outline](https://wiki.purduearc.com/wiki/rocket-league/assets/images/system-overview.png)
The repo is broken down into several ROS packages.

### rktl_autonomy
This package contains all code for the "High Level Planner" section. It provides
Expand Down
5 changes: 3 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ RUN apt update && \
ros-$ROS_DISTRO-camera-calibration \
ros-$ROS_DISTRO-joy \
ros-$ROS_DISTRO-rosserial-arduino \
ros-$ROS_DISTRO-rosbridge-server && \
ros-$ROS_DISTRO-rosbridge-server \
ros-$ROS_DISTRO-rosdoc-lite && \
# pip
pip3 install pybullet gym[box2d] stable-baselines3 pfilter optuna && \
pip3 install pybullet gym[box2d] stable-baselines3 pfilter optuna websockets && \
# clean up
rm -rf /var/lib/apt/lists/* /root/.cache/pip/

Expand Down
2 changes: 2 additions & 0 deletions docker/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ RUN usermod -l $USER -u $UID -aG video,dialout -md /home/$USER $BASE_USER && \
echo "$USER:$PW" | chpasswd

USER $USER
ENV PATH="${PATH}:/home/$USER/.local/bin"

WORKDIR /home/$USER
6 changes: 6 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Docker Development Image Setup Guide

## You have to read this

- Run `docker-build.sh` to build the development image.
- Run `docker-run.sh` to start the container.
- Run `docker-server-run.sh` to start the container when running on a remote computer connected via `ssh -Y`.
Expand All @@ -12,6 +13,7 @@
## You don't have to read this

### Remote Image

`Dockerfile` is used to build `purduearc/rocket-league:latest`.
[DockerHub](https://hub.docker.com/repository/docker/purduearc/rocket-league/)
is set up to automatically build this image when changes are made to the `main`
Expand All @@ -23,12 +25,14 @@ include any code from this repository or install any ROS dependencies other than
those found in the standard `ros-melodic-desktop-full` install.

### Local Image

`Dockerfile.local` is used to build `purduearc/rocket-league:local`. DockerHub
will not automatically build this image, you have to do that yourself by running
`docker-build.sh`. Running this will add your user so files can be accessed and
modified from both the container and your bare-metal computer.

### Running the image

Run `docker-run.sh` to start the image (`purduearc/rocket-league:local`) and
mount your local catkin workspace. You can pass in additional arguments directly
to the `docker run` command. For example, if you have an Nvidia GPU and have
Expand All @@ -49,6 +53,7 @@ For example:
peripherals

### Server Xauth voodoo explanation

- Remove the old temporary xauth folder
- Create the temporary xauth folder
- Copy the current Xauthority file to temp directory to not pollute the main Xauthority file
Expand All @@ -58,6 +63,7 @@ For example:
- Set the display variable for inside the container to use the new display location

### Other things

You can also run `docker-join.sh` to attach a shell to the container. You can
pass in arbitrary arguments similar to `docker-run.sh`.

Expand Down
2 changes: 1 addition & 1 deletion docker/docker-build-base.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
DOCKER_DIR=$(realpath $(dirname $0))
REPO_NAME="purduearc/rocket-league"

docker buildx build \
docker build \
--tag $REPO_NAME \
--cache-from=type=registry,ref=${REPO_NAME}:cache \
$@ \
Expand Down
2 changes: 2 additions & 0 deletions docker/docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

DOCKER_DIR=$(realpath $(dirname $0))
REPO_NAME="purduearc/rocket-league"
M1_ARGS=$([ $(uname -p) == 'arm' ] && echo "--platform linux/arm64/v8")

docker build --build-arg USER=$USER \
--build-arg PW="robot" \
--build-arg UID=$(id -u) \
--build-arg GID=$(id -g) \
--build-arg ROS_DEPS="$ROS_DEPS" \
$M1_ARGS \
-t $REPO_NAME:local-$USER \
-f $DOCKER_DIR/Dockerfile.local \
$@ \
Expand Down
30 changes: 24 additions & 6 deletions docker/docker-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,41 @@
WS_DIR=$(realpath $(dirname $0)/../../../)
REPO_NAME="purduearc/rocket-league"
CONTAINER_NAME="${CONTAINER_NAME:-$USER-arc-rocket-league-dev}"
MY_DISPLAY=$([ $(uname -s) == 'Darwin' ] && echo "host.docker.internal:0" || echo "$DISPLAY")
XAUTHORITY="$HOME/.Xauthority"
echo "Using display $MY_DISPLAY"
echo "Using $XAUTHORITY as Xauthority"
echo "mounting host directory $WS_DIR as container directory /home/$USER/catkin_ws"

# tty-specific options
if [ -t 0 -a -t 1 ]
then
TTY_OPTS="-it"
if [ -t 0 -a -t 1 ]; then
XTRA_OPTS="-it"
fi

# gitconfig
if [[ -f "$HOME/.gitconfig" ]]; then
XTRA_OPTS="$XTRA_OPTS -v $HOME/.gitconfig:/home/$USER/.gitconfig:ro"
fi

# Create histroy file and vscode-server files if they don't exist
if [[ ! -f "$WS_DIR/.zsh_history" ]]; then
touch "$WS_DIR/.zsh_history"
fi

if [[ ! -d "$WS_DIR/.vscode-server" ]]; then
mkdir "$WS_DIR/.vscode-server"
fi

docker run --rm \
$TTY_OPTS \
$XTRA_OPTS \
-e USER \
-e DISPLAY \
-e DISPLAY=$MY_DISPLAY \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-v $XAUTHORITY:/home/$USER/.Xauthority:ro \
-v $WS_DIR:/home/$USER/catkin_ws \
-v /tmp/.X11-unix:/tmp/.X11-unix \
`[ -f ~/.gitconfig ] && echo "-v $HOME/.gitconfig:/home/$USER/.gitconfig:ro"` \
-v $WS_DIR/.zsh_history:/home/$USER/.zsh_history \
-v $WS_DIR/.vscode-server:/home/$USER/.vscode-server \
-v ~/.ssh:/home/$USER/.ssh:ro \
--name $CONTAINER_NAME \
$@ \
Expand Down
53 changes: 53 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= ~/.local/bin/sphinx-build
SOURCEDIR := .
BUILDDIR := _build

# All Local Rocket League Packages
RKTLPKGS := $(wildcard ../rktl_*/)

# Gather all READMES from the project
READMES := $(foreach readme,$(shell find $(RKTLPKGS) -name 'README.md'),$(subst ../,,$(readme)))

# rosdoc output folder
ROSDOC_DIR := rosdoc
ROSDOC_PACKS := $(shell rospack list-names)
ROSDOC_OUT := $(foreach pack,$(ROSDOC_PACKS),$(ROSDOC_DIR)/$(pack))
ROSDOC_LOCAL := $(filter $(ROSDOC_DIR)/rktl_%,$(ROSDOC_OUT))
ROSDOC_HTML_DIRS := action msg srv

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(SPHINXOPTS)

.PHONY: help clean readmes rosdoc Makefile $(READMES) $(ROSDOC_LOCAL)

clean:
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(SPHINXOPTS)
@rm -rf autoapi $(foreach readme,$(READMES),$(dir $(readme))) $(ROSDOC_OUT)

$(READMES):
@mkdir -p $(dir $@)
@cp ../$@ $@

readmes: $(READMES)

$(ROSDOC_OUT):
@mkdir -p $@
rosdoc_lite -o $@ $(shell rospack find $(notdir $@)) > /dev/null 2>&1
@# Clean up big unnecessary files
@rm $@/html/index.html
@rm $@/html/*.png
@rm $@/html/*.js

rosdoc: $(ROSDOC_OUT)

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile readmes rosdoc
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(SPHINXOPTS)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/favicons/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/favicons/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/favicons/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/favicons/favicon.ico
Binary file not shown.
105 changes: 105 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.

import os
import sys
import shutil
sys.path.insert(0, os.path.abspath(".."))


# -- Project information -----------------------------------------------------

project = "Purdue ARC—Rocket League IRL"
copyright = "2023, Autonomous Robotics Club of Purdue (Purdue ARC)"
author = "Autonomous Robotics Club of Purdue (Purdue ARC)"

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.

extensions = [
"sphinx.ext.duration",
"sphinx.ext.doctest",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"autoapi.extension",
"myst_parser",
"sphinx_favicon",
]

myst_enable_extensions = [
"dollarmath",
"amsmath",
"smartquotes",
]

autoapi_dirs = [
"../rktl_autonomy/src",
"../rktl_perception/src",
"../rktl_planner/src",
"../rktl_sim/src",
]
autoapi_keep_files = True
# autoapi_file_patterns = ["*.py", "*"]
# autoapi_ignore = ["*.pyc", "*.cpp"]

intersphinx_mapping = {
"rtd": ("https://docs.readthedocs.io/en/stable/", None),
"python": ("https://docs.python.org/3/", None),
"sphinx": ("https://www.sphinx-doc.org/en/master/", None),
}
intersphinx_disabled_domains = ["std"]

templates_path = ["_templates"]

# -- Options for EPUB output
epub_show_urls = "footnote"

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_extra_path = ["rosdoc"]
html_logo = "images/arc_logo.svg"

favicons = [
{"href": "favicons/favicon.ico"},
{"href": "favicons/favicon-16x16.png"},
{"href": "favicons/favicon-32x32.png"},
{
"rel": "apple-touch-icon",
"href": "favicons/apple-touch-icon.png",
},
{
"rel": "android-chrome",
"href": "favicons/android-chrome-192x192.png",
},
{
"rel": "android-chrome",
"href": "favicons/android-chrome-512-512.png",
},
]
Loading