Francesco Ganci - 4143910 - 2021/2022
Compatible With:
- ROS1 noetic
Previous version of this project:
- programmatoroSeduto/rt2_assignment1 on GitHub branch action
- CarmineD8/rt2_assignment1 on GitHub the very first version
Yet another "upgrade" of the project from: programmatoroSeduto/rt2_assignment1 on GitHub; see the branch action. The main drawback of that lies in the complete lack of a user interface allowing to make the user aware of the status of the robot, as well as to drive the robot.
This is exactly the purpose of this update: here a user interface is provided, using Jupyter and MatPlotLib. The most of the work has been done on the Jupyter notebooks, with some small changes on the nodes of the original architecture. See the Jupyter Notebook jupyter_interface_V2 for further informations.
In order to support the implementation on Jupyter, some things have been changed. Here is a brief summary of this work:
-
no changes in
position_service.cpp
-
created a new message type,
JupyterTargetInfo.msg
, containing a large set of informations about the status of the nodestate_machine.cpp
-
the node
state_machine.cpp
now publishes a message of typeJupyterTargetInfo
almost regularly, properly setting the fields depending on the state of the node. The message is employed by the graphical interface for the visuals. -
the node
go_to_point.py
now publishes the command twist on two topics:/cmd_vel
as before, and/current_cmd_vel
read by the Jupyter notebook. This topic is needed for visualizing the commanc currently given to the robot in a graph. -
the old node
user_interface.py
has been replaced by the new implementationjupyter_user_interface.py
providing a service for switching on/off the random behaviour.
This repository contains a package that can be installed directly in whatever ROS1 workspace you like. Here is the main elements in the package:
/rt2_assignment_2
├── JupyterNotebooks
│  └── jupyter_interface_V2.ipynb <> the user interface
│
├── launch
│  └── sim_jupyter.launch <> launcher for Jupyter notebooks
│
├── msg
│  └── JupyterTargetInfo.msg <> infos for the graphical interface
│
├── scripts
│  ├── go_to_point.py <> motion planning algorithm (modified)
│  ├── jupyter_user_interface.py <> an updated version able to communicate with Jupyter
│  └── user_interface.py <> the old version
│
├── src
│  ├── position_service.cpp <> random position generator
│  └── state_machine.cpp <> implementation of the random behaviour
│
└── urdf
└── my_robot.urdf <> Gazebo robot description
Here are the instructions for installing and running the project in your ROS1 environment.
Before installing the project, make sure your system satisfies these requirements:
-
a working installation of ROS1 (the project is compatible with ROS1 Noetic).
I suggest to use the Docker image here: carms84/noetic_ros2 Docker image forwarding also the port 8888 in order to have Juyter on Windows.
-
A workspace is needed for the installation of the package.
Here's a script for quickly creating a workspace:
#! /bin/bash cd /root mkdir test_ws cd test_ws mkdir src catkin_make cd src
No external dependencies are required to run the project.
The simulation uses Gazebo and the URDF model here: CarmineD8/pioneer_ctrl on GitHub. Downloading the model is not necessary to run the project: the model is already integrated with this package.
Installing Jupyter Notebook is needed for running the user interface along with the ROS1 package. Here are the script to install it. Don't ignore the errors: I did put here some notes about the most common errors; in case you ignore the errors during the installation, the program won't work.
# before starting, make sure everything is updated/upgraded
# see troubleshooting if you're using the Docker image
# sudo apt update -y
# sudo apt upgrade -y
# you need pip!
# sudo apt-get install pip
pip3 --help
pip3 --version
# pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
# Jupyter is a web app, so a browser is needed
# sudo apt-get install firefox
firefox --version
# Mozilla Firefox 99.0
# suggested (not necessary)
pip3 install jinja2==3.1.1
# Successfully installed MarkupSafe-2.1.1 jinja2-3.1.1
pip3 install numpy --upgrade
# Successfully installed numpy-1.22.3
# Install Jupyter py modules
pip3 install traitlets
# check traitlets version >= 5.1.1
# OUTPUT: Successfully installed traitlets-5.1.1
pip3 install pygments==2.4.1
# the Docker image contains the version 2.3.1, which is lower than the one required by Jupyter
# to successfully install the latest pygments, you have to specify the version
# otherwise Pip will find a older version (why?)
pip3 install pyyaml
# check version 5.3.1
pip3 install bqplot
# bqplot-0.12.33 (latest, see https://github.com/bqplot/bqplot/releases/)
pip3 install ipywidgets==8.0.0rc0
# latest is 8.0.0rc0, see https://ipywidgets.readthedocs.io/en/latest/
# install Jupyter Notebook
pip3 install jupyter
The project also requires some extensions, so Jupyter should be enabled for using them. What you need now is nbextensions
, a ... extension that enables to install other extensions (wooooooooooooooooooooooooow...):
pip3 install jupyter_contrib_nbextensions
# jupyter-contrib-nbextensions-0.5.1
pip3 install jupyter_nbextensions_configurator
# version 0.4.1
jupyter contrib nbextension install
# the output from this command should be very long and "colorful", but with no errors or warnings
Here are some extensions you should enable for running the project. Mainly two extensions. The frist one is widgetsnbextension
:
jupyter nbextension enable --py widgetsnbextension
# the expected output is:
# $$ jupyter nbextension enable --py widgetsnbextension
# Enabling notebook extension jupyter-js-widgets/extension...
# - Validating: OK
Another required extension for this project is jupyros
which contains many functionalities useful for making Jupyter able to interact with ROS. Here's the installation script:
source /opt/ros/noetic/setup.bash
# install jupyros
pip3 install jupyros
# Successfully installed jupyros-0.3.0
# add Jupyros to Jupyter Notebook
jupyter nbextension enable --py --sys-prefix jupyros
# expected output from the last command:
# $$ jupyter nbextension enable --py --sys-prefix jupyros
# Enabling notebook extension jupyter-ros/extension...
# - Validating: OK
Below is a script for launching Jupyter, to run from inside the root folder of the package. It is dentical to the one in the repository (root folder of the pacakge). Notice that the script als launches the ROS1 master before launching Jupyter.
#! /bin/bash
set -e
source /opt/ros/noetic/setup.bash
source ../../devel/setup.bash
roscore &
cd /
# see https://github.com/Jupyter-contrib/jupyter_nbextensions_configurator/issues/72
jupyter nbextensions_configurator enable --user
jupyter nbextension enable --py --sys-prefix jupyros
jupyter notebook --allow-root --ip 0.0.0.0
Here are the instructions to install the project.
Let's suppose the workspace you're using to install the project is test_ws
; here you don't need a specific path: the workspace can be everywhere you want.
Follow these steps:
-
go inside the
/src
folder of your workspace -
clone the repo:
git clone https://github.com/programmatoroSeduto/rt2_assignment_2.git -b main ./rt2_assignment_2
-
build the workspace with
catkin_make
.
As usual, two ways for running this architecture: the quick one, and the other one node by node.
Let's start both the simulation and the Jupyter Notebook containing the interface. Follow the steps below:
-
open a bash and run the ROS1 master:
roscore &
. Remember to source your workspace!.Notice that, if you use the script for running Jupyter inside the package, running the ROS master is not needed because the script itself launches the ROS1 master before starting Jupyter.
-
go inside the folder of the package and run Jupyter:
roscd rt2_assignment_2 # chmod +x ./run_jupyter.sh ./run_jupyter.sh
The script shall run from inside the script folder; avoid nested folders in your
src
folder.If you're opening Jupyter for the first time, the best is to set an acces method with password, so the next time it will be easier to log in.
-
in another console (even directly in Jupyter Notebook) launch the project with the launch file
sim_jupyter.launch
.# SOURCE YOUR WORKSPACE BEFORE! roslaunch rt2_assignment_2 sim_jupyter.launch
-
Now everything should be running. Open the notebook you find inside the package, named
jupyter_interface_V2.ipynb
(see the folder JupyterNotebooks).I often use to start all the blocks of the notebook with Kernel -> Restart & Run All.
Please refer to the infos inside the notebook. Have fun!
The way to launch the project is quite similar to the one shown in the readme of the previous verson of the project (link here: programmatoroSeduto/rt2_assignment1 on GitHub) but launching the node jupyter_user_interface.py
instead of user_interface.py
.
The project also wants to test two documentation systems:
- Doxygen easy to use, stable, quick to use, with a handy GUI, but quite unflexible and generating a too much old style HTML documentation (welcome back to 90s!)
- Sphinx enables to produce a nice documentation, flexible and extendable with not so much effort, but really painful to use, not stable, it has not a GUI, and uses the horrible reStructured format. Here is an interesting article about Sphinx.
As always, in particular if you're using the Docker image carms84/noetic_ros2, either Docker or Sphinx aren't installed. Luckily, both the frameworks are quite easy to install: just copy and paste some commands to the console.
Open a console and paste this command: (the command -y
says to cautomatically confirm the installation)
# the engine
sudo apt-get install -y doxygen
# check your installation with the command
doxygen -v
# 1.8.17
# and the GUI
sudo apt-get install -y doxygen-gui
# install check: this should make an alert window appear
doxywizard --help
That's all for the Doxygen setup. You can run the GUI using typing the command doxywizard
in the shell.
THE EXTENSION 'BREATHE' OF SPHINX REQUIRES DOXYGEN: install it before proceed.
Installing Sphinx s quite easy (don't trust it!):
# the engine
# the following gives an issue (the repo is not up to date...)
# sudo apt-get install -y python3-sphinx
# use this instead:
pip3 install sphinx==4.5.0
# check the installation
sphinx-quickstart --version
# if it appears a Python exception like this:
# ImportError: cannot import name 'contextfunction' from 'jinja2' (/usr/local/lib/python3.8/dist-packages/jinja2/__init__.py)
# SEE THE TROUBLESHOOTING section
Let's install also some useful extensions for Sphinx:
# breathe allows Sphinx to read the Doxygen XML documentation
pip3 install breathe
# see https://github.com/michaeljones/breathe/releases
# latest is 4.33.1
# this is a nice theme which recalls ReadTheDocs (a little bit worse than the orininal one)
pip3 install sphinx-rtd-theme
# this extension lets Sphinx to read the MD format
pip3 install myst-parser
# see https://myst-parser.readthedocs.io/en/latest/
# latest is 0.17.2
Very simple, because the configuration file is already in the package and ready to use. Follow these steps:
-
go inside the package, folder
/docs
. Here's a file labeledDoxyfile
that is the configuration file. It is set to generate both the HTML documentation and the XML documentation inside the folder of the package/docs/build/html
. -
I suggest to use
doxywizard
, open from there the configuration file and generate the documentation. Otherwise, you can simply call this from the shell:doxygen Doxyfile # firefox ./build/html/index.html &
To see the documentation, go inside the package, sub folder /docs/build/html
, and open index.html
in a browser.
As before, the package contains everything you need in order to build the documentation with Sphinx. Here is the steps for generating the docs:
-
go inside the folder
/docs
of the package -
launch this command in a shell:
./build_sphinx.sh # firefox ./_build/html/index.html &
The command makes the documentation; ignore the warnings there. Note that the command also builds the Doxygen documentation.
-
in the folder
/docs
of the package I launchedsphinx-quickstart
Here's the output:sphinx-quickstart Welcome to the Sphinx 4.5.0 quickstart utility. Please enter values for the following settings (just press Enter to accept a default value, if one is given in brackets). Selected root path: . You have two options for placing the build directory for Sphinx output. Either, you use a directory "_build" within the root path, or you separate "source" and "build" directories within the root path. > Separate source and build directories (y/n) [n]: n The project name will occur in several places in the built documentation. > Project name: RT2 Assignment 2 > Author name(s): Francesco Ganci (S4143910) > Project release []: 1.0.0 If the documents are to be written in a language other than English, you can select a language here by its language code. Sphinx will then translate text that it generates into that language. For a list of supported codes, see https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language. > Project language [en]: en Creating file /root/test_ws/src/rt2_assignment_2/docs/conf.py. Creating file /root/test_ws/src/rt2_assignment_2/docs/index.rst. Creating file /root/test_ws/src/rt2_assignment_2/docs/Makefile. Creating file /root/test_ws/src/rt2_assignment_2/docs/make.bat. Finished: An initial directory structure has been created. You should now populate your master file /root/test_ws/src/rt2_assignment_2/docs/index.rst and create other documentation source files. Use the Makefile to build the docs, like so: make builder where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
Please note that now there are
build
and_build
inside thedocs
folder. The first one will contain the Doxygen XML documentation, whereras_build
is going to host the Sphinx verison of the documentation. -
Before starting to add the pages, I configured the builder through the config file
config.py
. -
created a folder
/docs/sphinx
which is going to collect the reST pages. -
Time to write some documentation! I started from the index page, which includes the README inside.
-
As you can see in the folder
/docs/sphinx
, the documentation is divided into two main parts: the one referred to ROScpp nodes, and the other one referring to the Python scripts inside the project. Each of them have its index. The first step is to make clear the structure of the documentation, creating the reST pages. -
documentation of PY nodes with simple reST and autodoc
See the pages inside
.../rts_2assignment_2/docs/sphinx/rospy-nodes
. Here the directive.. automodule ::
imports and generates the documentation from the Python scripts. Notice the instructionsys.path.insert( 0, os.path.abspath('./../scripts') )
inside the fileconf.py
: the extension Autodoc wouldn't find the py files withut that. -
documentation of C++ nodes with simple reST and breathe
See the pages inside
.../rts_2assignment_2/docs/sphinx/roscpp-nodes
. The pages have a very simple structure: the directive.. doxyfile ::
reads the documentation attached to the C++ code through the XML documentation from Doxygen. -
build the documentation with a script.
Notice that, since Sphinx runs from
.../rt2_assignment_2/docs
and not in the root folder of the package, due to a bug or something similar Sphinx can't see the README.md file there. The scripts applies a workaround: the readme is copied inside the folder/docs
, included in the documentation, and then deleted. Unfortunately Sphinx has some problems in catching the relative locations right now: this is a well known issue, with so many posts everywhere on the web, but no satisfying solution.Here's the code inside the script for building the documentation with Sphinx:
#! /bin/bash source ../../../devel/setup.bash cp ../README.md ./readme.md make clean make html rm readme.md # firefox ./_build/html/index.html &
Here are some well-known problems that can occur trying to run the project.
Especially when you use the Docker image carms84/noetic_ros2, the first time you launch the command sudo apt-get update
, an error message is print; the output is similar to this one:
$$ sudo apt-get update
sudo: setrlimit(RLIMIT_CORE): Operation not permitted
Get:1 http://dl.google.com/linux/chrome/deb stable InRelease [1,811 B]
Get:2 http://mirrors.ubuntu.com/mirrors.txt Mirrorlist [142 B]
Get:3 http://giano.com.dist.unige.it/ubuntu focal InRelease [265 kB]
Get:6 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages [1,090 B]
Get:5 http://ubuntu.mirror.garr.it/ubuntu focal-backports InRelease [108 kB]
Get:7 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Get:4 http://giano.com.dist.unige.it/ubuntu focal-updates InRelease [114 kB]
Get:9 http://ubuntu.mirror.garr.it/ubuntu focal-updates/main amd64 Packages [2,185 kB]
Ign:8 http://ubuntu.connesi.it/ubuntu focal-updates/restricted amd64 Packages
Ign:8 http://giano.com.dist.unige.it/ubuntu focal-updates/restricted amd64 Packages
Ign:11 http://ubuntu.connesi.it/ubuntu focal-updates/multiverse amd64 Packages
Ign:12 http://giano.com.dist.unige.it/ubuntu focal-backports/universe amd64 Packages
Get:13 http://ubuntu.mirror.garr.it/ubuntu focal-backports/main amd64 Packages [51.2 kB]
Get:14 http://packages.ros.org/ros/ubuntu focal InRelease [4,676 B]
Get:11 http://ubuntu.mirror.garr.it/ubuntu focal-updates/multiverse amd64 Packages [30.3 kB]
Err:14 http://packages.ros.org/ros/ubuntu focal InRelease
The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
Get:10 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [1,153 kB]
Get:15 http://packages.ros.org/ros2/ubuntu focal InRelease [4,679 B]
Get:16 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [1,139 kB]
Err:15 http://packages.ros.org/ros2/ubuntu focal InRelease
The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
Get:17 http://security.ubuntu.com/ubuntu focal-security/multiverse amd64 Packages [25.8 kB]
Get:18 http://security.ubuntu.com/ubuntu focal-security/main amd64 Packages [1,771 kB]
Get:8 http://archive.ubuntu.com/ubuntu focal-updates/restricted amd64 Packages [1,214 kB]
Get:12 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 Packages [26.0 kB]
Get:19 http://security.ubuntu.com/ubuntu focal-security/universe amd64 Packages [870 kB]
Fetched 9,079 kB in 7s (1,331 kB/s)
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://packages.ros.org/ros/ubuntu focal InRelease: The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://packages.ros.org/ros2/ubuntu focal InRelease: The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
W: Failed to fetch http://packages.ros.org/ros/ubuntu/dists/focal/InRelease The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
W: Failed to fetch http://packages.ros.org/ros2/ubuntu/dists/focal/InRelease The following signatures were invalid: EXPKEYSIG F42ED6FBAB17C654 Open Robotics <info@osrfoundation.org>
W: Some index files failed to download. They have been ignored, or old ones used instead.
This happens because there are still some old addresses in the list of the repositories. To solve this, here are the commands:
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
# now, update/upgrade
sudo apt-get update -y
sudo apt-get upgrade -y
If you're interested, here is the official post explaining this fact: ROS GPG Key Expiration Incident on ROS Discourse. Another useful post: apt update: signatures were invalid: F42ED6FBAB17C654 - ROS Answers: Open Source Q&A Forum
The command generating the error:
pip3 install pyyaml
it could happen that this kind of error is print:
ERROR: pandas 1.4.2 has requirement numpy>=1.18.5; platform_machine != "aarch64" and platform_machine != "arm64" and python_version < "3.10", but you'll have numpy 1.17.4 which is incompatible.
ERROR: nbconvert 6.5.0 has requirement jinja2>=3.0, but you'll have jinja2 2.10.3 which is incompatible.
This should solve the problem:
pip3 install numpy --upgrade
# check that the version is >=1.22.3
pip3 uninstall jinja2
pip3 install jinja2
# check that the version is >=3.1.1
# try again
pip3 install pyyaml
There could be an error when also Anaconda is installed in the same system. The error procudes this output on the screen:
-- Found PythonInterp: /root/anaconda3/bin/python3 (found suitable version "3.9.7", minimum required is "3")
-- Using PYTHON_EXECUTABLE: /root/anaconda3/bin/python3
-- Using Debian Python package layout
-- Could NOT find PY_em (missing: PY_EM)
CMake Error at /opt/ros/noetic/share/catkin/cmake/empy.cmake:30 (message):
Unable to find either executable 'empy' or Python module 'em'... try
installing the package 'python3-empy'
Call Stack (most recent call first):
/opt/ros/noetic/share/catkin/cmake/all.cmake:164 (include)
/opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:20 (include)
CMakeLists.txt:58 (find_package)
-- Configuring incomplete, errors occurred!
See also "/root/test_ws/build/CMakeFiles/CMakeOutput.log".
Invoking "cmake" failed
As workaround, you can call catkin_make
as follows:
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
See this post.
Sometimes there are some errors with pip3
during the installation of the packages for Jupyter Notebook. The error could be this for example:
ERROR: ipython 8.2.0 has requirement pygments>=2.4.0, but you'll have pygments 2.3.1 which is incompatible.
ERROR: nbconvert 6.5.0 has requirement jinja2>=3.0, but you'll have jinja2 2.10.3 which is incompatible.
ERROR: nbconvert 6.5.0 has requirement pygments>=2.4.1, but you'll have pygments 2.3.1 which is incompatible.
ERROR: pandas 1.4.2 has requirement numpy>=1.18.5; platform_machine != "aarch64" and platform_machine != "arm64" and python_version < "3.10", but you'll have numpy 1.17.4 which is incompatible.
The error is solved in this post on StackOverflow.
# try this
pip3 install jupyter bqplot pyyaml ipywidgets
# if something goes wrong,
pip3 install traitlets==5.1.1
pip3 install pygments==2.4.1
pip3 install jupyter bqplot pyyaml ipywidgets
# the error should disappear.
The packahe Jinja typically gives some problem; unfortunately it is required during the installation og Jupyter notebook, otherwise, as you try to run jupyter contrib nbextension install
, it wll appear a very unintellegible Python error.
In order to avoid this boring error, uninstall and install again this component:
pip3 uninstall Jinja2
pip3 install Jinja2
See this post, not directly related with this situation: ContextualVersionConflict when starting 0-robot #139 on HitHub
That's because you forgot to source the workspace, or maybe you didn't run catkin_make
on it. So, catkin_make
and source
it before using roscd
.
The message appears in the Jupyter Notebook, and resembles this:
The rospy package is not found in your $PYTHONPATH. Subscribe and publish are not going to work.
Do you need to activate your ROS environment?
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Input In [2], in <cell line: 16>()
13 import numpy as np
15 # ROS libraries
---> 16 import rospy
17 from std_srvs.srv import SetBool, SetBoolRequest, SetBoolResponse
18 from geometry_msgs.msg import Twist, Pose, Vector3
ModuleNotFoundError: No module named 'rospy'
Remember to source your ROS1 environment and to launch te ROS1 master before executing the Jupyter notebook!
Unfortunately, this error could happen when you try to launch the command sphinx-quickstart
, whereas pshinx-build --help
works fine. Here's the "arabic" error:
$$ sphinx-quickstart
Traceback (most recent call last):
File "/usr/bin/sphinx-quickstart", line 11, in <module>
load_entry_point('Sphinx==1.8.5', 'console_scripts', 'sphinx-quickstart')()
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 490, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2854, in load_entry_point
return ep.load()
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2445, in load
return self.resolve()
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2451, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "/usr/lib/python3/dist-packages/sphinx/cmd/quickstart.py", line 49, in <module>
from sphinx.util.template import SphinxRenderer
File "/usr/lib/python3/dist-packages/sphinx/util/template.py", line 17, in <module>
from sphinx.jinja2glue import SphinxFileSystemLoader
File "/usr/lib/python3/dist-packages/sphinx/jinja2glue.py", line 16, in <module>
from jinja2 import FileSystemLoader, BaseLoader, TemplateNotFound, \
ImportError: cannot import name 'contextfunction' from 'jinja2' (/usr/local/lib/python3.8/dist-packages/jinja2/__init__.py)
As said in this post sometimes happens that pat-get
catches a old version of Sphinx build, uncompatible with the latest version of Jinja2 (currently the latest release is 3.1.1, see the official page of Jinja2).
To solve the problem, you can easily upgrade Sphinx through pip3
as follows: (see this page)
pip3 install --upgrade sphinx
It should fix that. After, check the installation: it should appear on the screen the version when you try to run sphinx-quickstart
. This:
$$ sphinx-quickstart --version
sphinx-quickstart 1.8.5
A project by Francesco Ganci, S4143910, upon a code by CarmineD8.
- Email : s4143910@studenti.unige.it