├── pyicub
├── core
│ ├── __init__.py
│ └── rpc.py
├── modules
│ ├── __init__.py
│ ├── face.py
│ ├── faceLandmarks.py
│ ├── camera.py
│ ├── llm.py
│ └── emotions.py
├── controllers
│ └── __init__.py
├── proc
│ ├── icubapi.py
│ ├── fsmizer.py
│ └── actionizer.py
├── __init__.py
└── utils.py
├── examples
├── PositionController
│ ├── __init__.py
│ ├── move_head.py
│ ├── move_part.py
│ └── move_head_timeout.py
├── 5_Templates
│ └── 1.hello
│ │ ├── json
│ │ ├── msg1.json
│ │ └── hello.json
│ │ ├── 3.run_welcome.py
│ │ ├── 2.create_params.py
│ │ └── 1.create_template.py
├── 6_REST
│ ├── 4.templates
│ │ ├── template
│ │ │ ├── params
│ │ │ │ ├── msg1.json
│ │ │ │ ├── msg2.json
│ │ │ │ └── msg.py
│ │ │ ├── welcome.json
│ │ │ └── welcome.py
│ │ └── 1.hello_world.py
│ ├── 5.restfulclient
│ │ ├── template
│ │ │ ├── params
│ │ │ │ ├── msg1.json
│ │ │ │ ├── msg2.json
│ │ │ │ └── msg.py
│ │ │ ├── welcome.json
│ │ │ └── welcome.py
│ │ ├── 2.client.py
│ │ └── 1.server.py
│ ├── 3.actions
│ │ ├── actions
│ │ │ └── LookAtAction.json
│ │ └── app.py
│ ├── 6.topics
│ │ ├── 2.subscriber.py
│ │ └── 1.publisher.py
│ ├── 2.input_args
│ │ └── app.py
│ └── 1.client_server
│ │ ├── 2.client.py
│ │ └── 1.server.py
├── 7_FSM
│ ├── 1.semaphore
│ │ ├── diagram.png
│ │ ├── fsm.json
│ │ └── app.py
│ ├── 3.icub_rest
│ │ ├── diagram.png
│ │ ├── actions
│ │ │ └── LookAtAction.json
│ │ └── app.py
│ ├── 4.icub_multiple
│ │ ├── FSM_A.png
│ │ ├── FSM_B.png
│ │ ├── actions
│ │ │ └── LookAtAction.json
│ │ ├── FSM_A.json
│ │ └── app.py
│ ├── 5.icub_subs
│ │ ├── diagram.png
│ │ ├── 2.sub.py
│ │ ├── 1.pub.py
│ │ └── fsm.json
│ ├── 6.icub_rest_import
│ │ ├── app.py
│ │ └── fsm.json
│ └── 2.semaphore_subs
│ │ ├── 3.cmd.py
│ │ ├── 2.sub.py
│ │ └── 1.pub.py
├── 9_LLM
│ ├── REST
│ │ ├── client.py
│ │ └── server.py
│ └── igpt.py
├── 0_YARP
│ ├── 1.callback.py
│ └── 2.logger.py
├── 4_Actions
│ ├── json
│ │ ├── CustomAction.json
│ │ └── LookAtAction.json
│ ├── 3.imported_action.py
│ ├── 9.from_repository.py
│ ├── 5.custom_actions.py
│ ├── 2.lookat_actions.py
│ ├── 1.moving_head.py
│ ├── 6.custom_waitmotiondone.py
│ ├── 8.async_action.py
│ ├── 7.custom_action_speech.py
│ ├── 10.inner_actions.py
│ └── 4.complete_action.py
├── 8_Attention
│ ├── REST
│ │ ├── server.py
│ │ └── client.py
│ └── observe.py
├── 3_Modules
│ ├── 3.runtimemodule.py
│ └── 2.face_landmarks.py
└── GazeController
│ ├── lookat.py
│ ├── lookat_events.py
│ └── lookat_timeout.py
├── docker
├── build.sh
├── run.sh
├── pyicub.env
├── .env
├── Dockerfile.pyicub-frontend
├── Dockerfile.pyicub
├── setup.sh
└── compose.yaml
├── requirements.txt
├── icub-apps
├── applications
│ ├── cluster-config.xml
│ └── icubSim
│ │ └── icub-gazebo.xml
└── gazebo
│ └── icub-world.sdf
├── pytest.ini
├── scripts
├── tests.sh
├── setup.sh
├── start.sh
└── common.sh
├── .github
└── workflows
│ ├── run_tests.yml
│ └── readTheDocs.yml
├── README.md
├── LICENSE
├── .gitignore
├── tests
└── test_core.py
└── setup.py
/pyicub/core/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pyicub/modules/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pyicub/controllers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/PositionController/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docker/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | docker compose build
4 |
--------------------------------------------------------------------------------
/examples/5_Templates/1.hello/json/msg1.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome_msg": "hello world"
3 | }
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/template/params/msg1.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome_msg": "hello world"
3 | }
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/template/params/msg2.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome_msg": "welcome world"
3 | }
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/template/params/msg1.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome_msg": "hello world"
3 | }
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/template/params/msg2.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome_msg": "welcome world"
3 | }
--------------------------------------------------------------------------------
/examples/7_FSM/1.semaphore/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s4hri/pyicub/HEAD/examples/7_FSM/1.semaphore/diagram.png
--------------------------------------------------------------------------------
/examples/7_FSM/3.icub_rest/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s4hri/pyicub/HEAD/examples/7_FSM/3.icub_rest/diagram.png
--------------------------------------------------------------------------------
/examples/7_FSM/4.icub_multiple/FSM_A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s4hri/pyicub/HEAD/examples/7_FSM/4.icub_multiple/FSM_A.png
--------------------------------------------------------------------------------
/examples/7_FSM/4.icub_multiple/FSM_B.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s4hri/pyicub/HEAD/examples/7_FSM/4.icub_multiple/FSM_B.png
--------------------------------------------------------------------------------
/examples/7_FSM/5.icub_subs/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s4hri/pyicub/HEAD/examples/7_FSM/5.icub_subs/diagram.png
--------------------------------------------------------------------------------
/docker/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | source "$(dirname "$0")/setup.sh"
6 |
7 | docker compose up
8 |
9 | docker compose down --remove-orphans
--------------------------------------------------------------------------------
/pyicub/proc/icubapi.py:
--------------------------------------------------------------------------------
1 | from pyicub.rest import iCubRESTApp
2 | from pyicub.utils import getPublicMethods
3 | import time
4 | import inspect
5 |
6 | app = iCubRESTApp()
7 | app.rest_manager.run_forever()
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | PyYAML==6.0.1
2 | Flask==3.0.2
3 | Flask-Cors==6.0.0
4 | transitions==0.9.2
5 | graphviz==0.20.3
6 | requests==2.32.4
7 | pygraphviz==1.11
8 | numpy==2.2.4
9 | pytest==8.3.5
10 | pytest-html==4.1.1
--------------------------------------------------------------------------------
/icub-apps/applications/cluster-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | pyicub-node
5 | icub-node
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docker/pyicub.env:
--------------------------------------------------------------------------------
1 | ICUB_SIMULATION=true
2 | ICUB_APPS=${WORKDIR}/pyicub/icub-apps
3 | ICUB_HOST=icub-head
4 | ICUB_NODE=icub-node
5 | PYICUB_HOST=localhost
6 | PYICUB_NODE=${PYICUB_NODE}
7 | YARP_FORWARD_LOG_ENABLE=0
8 | YARP_QUIET=1
9 | YARP_COLORED_OUTPUT=1
10 | YARP_DEBUG_ENABLE=0
11 | PYICUB_LOGGING=false
12 | PYICUB_LOGGING_PATH=${WORKDIR}/pyicub
13 | PYICUB_API=true
14 | PYICUB_API_FRONTEND_PORT=9000
15 | PYICUB_API_RESTMANAGER_HOST=${PYICUB_HOST}
16 | PYICUB_API_RESTMANAGER_PORT=9001
17 | PYICUB_API_PROXY_HOST=${PYICUB_HOST}
18 | PYICUB_API_PROXY_PORT=9001
19 | PYICUB_API_PROXY_SCHEME=http
20 | PYTEST_OUTPUT_DIR=/shared/pytest
--------------------------------------------------------------------------------
/docker/.env:
--------------------------------------------------------------------------------
1 | PYICUB_VERSION=8.3.4
2 | PYICUB_APPS_VERSION=master
3 | PYICUB_FRONTEND_VERSION=v8.8-ng
4 |
5 | RELEASE_DATE=2025.10
6 |
7 | ROBOTOLOGY_SUPERBUILD_VERSION=v2024.08.0
8 | VERSION=${PYICUB_VERSION}_ubuntu22.04_robotology_${ROBOTOLOGY_SUPERBUILD_VERSION}-${RELEASE_DATE}
9 | ROBOTOLOGY_IMAGE_NAME=iitschri/robotology-superbuild-docker:${ROBOTOLOGY_SUPERBUILD_VERSION}-ubuntu22.04_2025.10
10 | PYICUB_IMAGE_NAME=iitschri/pyicub-docker:${VERSION}
11 | PYICUB_FRONTEND_IMAGE_NAME=iitschri/pyicub-frontend-docker:${PYICUB_FRONTEND_VERSION}
12 | COMPOSE_PROFILES=backend,frontend
13 | WORKDIR=/usr/local/src/robot
14 | PYICUB_NODE=pyicub-node
15 |
16 |
--------------------------------------------------------------------------------
/docker/Dockerfile.pyicub-frontend:
--------------------------------------------------------------------------------
1 | FROM node:23
2 |
3 | ARG PYICUB_FRONTEND_URL=https://github.com/s4hri/pyicub-frontend
4 | ARG PYICUB_FRONTEND_VERSION=master
5 | ARG PYICUB_API_FRONTEND_PORT=9000
6 | ARG ROBOT_CODE=/usr/local/src/robot
7 |
8 | ENV PYICUB_API_FRONTEND_PORT=${PYICUB_API_FRONTEND_PORT}
9 | ENV ROBOT_CODE=${ROBOT_CODE}
10 |
11 | RUN mkdir -p $ROBOT_CODE
12 |
13 | RUN cd $ROBOT_CODE && \
14 | git clone ${PYICUB_FRONTEND_URL} pyicub-frontend && \
15 | cd pyicub-frontend && \
16 | git checkout ${PYICUB_FRONTEND_VERSION}
17 |
18 | WORKDIR $ROBOT_CODE/pyicub-frontend
19 |
20 | RUN npm install
21 |
22 | CMD ["sh", "-c", "npm run production -- --port $PYICUB_API_FRONTEND_PORT"]
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | # pytest.ini
2 | [pytest]
3 | testpaths = tests
4 | python_files = test_*.py *_test.py
5 | python_classes = Test*
6 | python_functions = test_*
7 |
8 | markers =
9 | smoke: basic smoke tests to verify execution of core functionality
10 | slow: marks tests that take a long time to run
11 | integration: marks tests as integration tests
12 |
13 | addopts =
14 | -ra
15 | --strict-markers
16 | --tb=short
17 | --doctest-modules
18 | --durations=10
19 |
20 | minversion = 7.0
21 |
22 | log_cli = true
23 | log_cli_level = INFO
24 | log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
25 | log_cli_date_format = %Y-%m-%d %H:%M:%S
26 |
--------------------------------------------------------------------------------
/scripts/tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source "$(dirname "$0")/common.sh"
4 |
5 | export DISPLAY=:99
6 | sudo Xvfb :99 -screen 0 1024x768x24 &
7 | sleep 1 # Give it time to start
8 |
9 | initialize_environment
10 | start_yarpserver_detached >/dev/null 2>&1
11 | start_local_yarprun >/dev/null 2>&1
12 |
13 | echo "Starting Gazebo simulation..."
14 | gzserver ${ICUB_APPS}/gazebo/icub-world.sdf >/dev/null 2>&1 &
15 | sleep 5
16 |
17 | echo "Starting robot interface..."
18 | yarprobotinterface --context gazeboCartesianControl --config no_legs.xml --portprefix /icubSim >/dev/null 2>&1 &
19 | sleep 5
20 |
21 | echo "Running pytest..."
22 | cd $ROBOT_CODE/pyicub || exit 1
23 |
24 | pytest --html=$PYTEST_OUTPUT_DIR/pytest_report.html
25 |
--------------------------------------------------------------------------------
/.github/workflows/run_tests.yml:
--------------------------------------------------------------------------------
1 | name: Run Tests
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | test:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v3
15 |
16 | - name: Run tests with Docker Compose
17 | working-directory: docker
18 | run: |
19 | echo "Building and running services for testing..."
20 | COMPOSE_PROFILES=backend,test docker compose build
21 | COMPOSE_PROFILES=test docker compose up
22 |
23 | - name: Clean up docker
24 | working-directory: docker
25 | run: |
26 | echo "Cleaning up..."
27 | docker compose down --volumes --remove-orphans
28 |
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/template/welcome.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Welcome",
3 | "params": {
4 | "welcome_msg": "$welcome_msg"
5 | },
6 | "steps": [
7 | {
8 | "welcome_msg": "$welcome_msg",
9 | "name": "Step",
10 | "limb_motions": {},
11 | "gaze_motion": null,
12 | "custom_calls": [
13 | {
14 | "target": "speech.say",
15 | "args": [
16 | "$welcome_msg"
17 | ]
18 | }
19 | ],
20 | "offset_ms": null
21 | }
22 | ],
23 | "wait_for_steps": [
24 | true
25 | ],
26 | "description": "empty",
27 | "offset_ms": null
28 | }
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/template/welcome.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TemplateAction",
3 | "params": {
4 | "welcome_msg": "$welcome_msg"
5 | },
6 | "steps": [
7 | {
8 | "welcome_msg": "$welcome_msg",
9 | "name": "Step",
10 | "limb_motions": {},
11 | "gaze_motion": null,
12 | "custom_calls": [
13 | {
14 | "target": "speech.say",
15 | "args": [
16 | "$welcome_msg"
17 | ]
18 | }
19 | ],
20 | "offset_ms": null
21 | }
22 | ],
23 | "wait_for_steps": [
24 | true
25 | ],
26 | "description": "empty",
27 | "offset_ms": null
28 | }
--------------------------------------------------------------------------------
/examples/5_Templates/1.hello/json/hello.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TemplateAction",
3 | "params": {
4 | "step_bodymotion": "$step_bodymotion",
5 | "welcome_msg": "$welcome_msg"
6 | },
7 | "steps": [
8 | "$step_bodymotion",
9 | {
10 | "welcome_msg": "$welcome_msg",
11 | "name": "Step",
12 | "limb_motions": {},
13 | "gaze_motion": null,
14 | "custom_calls": [
15 | {
16 | "target": "speech.say",
17 | "args": [
18 | "$welcome_msg"
19 | ]
20 | }
21 | ],
22 | "offset_ms": null
23 | }
24 | ],
25 | "wait_for_steps": [
26 | true,
27 | true
28 | ],
29 | "description": "empty",
30 | "offset_ms": null
31 | }
--------------------------------------------------------------------------------
/examples/9_LLM/REST/client.py:
--------------------------------------------------------------------------------
1 |
2 | from pyicub.rest import PyiCubRESTfulClient
3 |
4 | robot_name = 'icubSim'
5 | app_name = 'helper'
6 |
7 | client = PyiCubRESTfulClient(host='localhost', port=9001)
8 |
9 | res = client.run_target(robot_name, app_name, target_name='gpt.query', text='Tell me a fun fact about space.')
10 | print("Set prompt result:", res)
11 |
12 | res = client.run_target(robot_name, app_name, target_name='gpt.set_system_prompt',
13 | prompt='You are a concise assistant who answers very briefly.')
14 | print("Set prompt result:", res)
15 |
16 | res = client.run_target(robot_name, app_name, target_name='gpt.create_session', session_id='rest-session')
17 | print("Create session result:", res)
18 |
19 | res = client.run_target(robot_name, app_name, target_name='gpt.switch_session', session_id='rest-session')
20 | print("Switch session result:", res)
21 |
22 | res = client.run_target(robot_name, app_name, target_name='gpt.query', text='Who is Alan Turing?')
23 | print("Query result:", res)
24 |
--------------------------------------------------------------------------------
/examples/7_FSM/1.semaphore/fsm.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Semaphore",
3 | "states": [
4 | {
5 | "name": "RED",
6 | "description": null
7 | },
8 | {
9 | "name": "YELLOW",
10 | "description": null
11 | },
12 | {
13 | "name": "GREEN",
14 | "description": null
15 | }
16 | ],
17 | "transitions": [
18 | {
19 | "trigger": "init>RED",
20 | "source": "init",
21 | "dest": "RED"
22 | },
23 | {
24 | "trigger": "RED>GREEN",
25 | "source": "RED",
26 | "dest": "GREEN"
27 | },
28 | {
29 | "trigger": "GREEN>YELLOW",
30 | "source": "GREEN",
31 | "dest": "YELLOW"
32 | },
33 | {
34 | "trigger": "YELLOW>init",
35 | "source": "YELLOW",
36 | "dest": "init"
37 | }
38 | ],
39 | "initial_state": "init",
40 | "session_id": 0,
41 | "session_count": 3
42 | }
--------------------------------------------------------------------------------
/docker/Dockerfile.pyicub:
--------------------------------------------------------------------------------
1 | ARG DOCKER_SRC=ubuntu:latest
2 | FROM $DOCKER_SRC
3 |
4 | ARG WORKDIR="/usr/local/src/robot"
5 | ARG PYICUB_URL=https://github.com/s4hri/pyicub
6 | ARG PYICUB_VERSION=master
7 | ARG PYICUB_APPS_URL=https://github.com/s4hri/pyicub-apps
8 | ARG PYICUB_APPS_VERSION=master
9 |
10 | ENV WORKDIR=$WORKDIR
11 | ENV PYICUB_URL=$PYICUB_URL
12 | ENV PYICUB_VERSION=$PYICUB_VERSION
13 | ENV PYICUB_APPS_URL=$PYICUB_APPS_URL
14 | ENV PYICUB_APPS_VERSION=$PYICUB_APPS_VERSION
15 | ENV DEBIAN_FRONTEND=noninteractive
16 | ENV XDG_RUNTIME_DIR=/tmp/runtime-root
17 |
18 | WORKDIR ${WORKDIR}
19 |
20 | ENV PATH=$PATH:/root/.local/bin
21 |
22 | RUN mkdir -p /tmp/runtime-root && \
23 | chmod 700 /tmp/runtime-root
24 |
25 | COPY .. $WORKDIR/pyicub
26 |
27 | RUN cd $WORKDIR/pyicub && \
28 | pip3 install -r requirements.txt
29 |
30 | ENV PYTHONPATH=$WORKDIR/pyicub
31 |
32 | RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh \
33 | && touch /root/.ssh/config && chmod 600 /root/.ssh/config \
34 | && ssh-keyscan -H github.com >> /root/.ssh/known_hosts 2>/dev/null || true
35 |
36 | ENV GIT_SSH_COMMAND="ssh -F /dev/null"
37 |
38 | RUN git clone https://github.com/s4hri/docker-tests.git
39 |
40 | USER root
41 |
42 | CMD ["bash"]
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PyiCub
2 | ====
3 |
4 | Introduction
5 | -------------
6 | [PYICUB](https://github.com/s4hri/pyicub) is a framework for developing iCub applications using Python.
7 |
8 |
9 | Documentation
10 | --------------
11 | The official documentation is available at [PyiCub Documentation](https://pyicub-doc.readthedocs.io/en/latest/).
12 |
13 |
14 | Requirements
15 | -------------
16 | - [YARP](https://github.com/robotology/yarp) (compiled with Python wrappers)
17 | - [icub-main](https://github.com/robotology/icub-main)
18 |
19 |
20 | How to install the Python package
21 | -------------
22 | ```
23 | git clone git@github.com:s4hri/pyicub.git
24 | cd pyicub
25 | pip3 install .
26 | ```
27 |
28 | How to start (using Docker)
29 | -------------
30 | In order to simplify the installation procedure, we have containerized the essential requirements in a Docker image.
31 |
32 | ```
33 | git clone git@github.com:s4hri/pyicub.git
34 | cd pyicub/docker
35 | bash build.sh
36 | bash run.sh
37 | ```
38 |
39 | How to test pyicub
40 | -------------
41 |
42 | To run the tests you can run this command from your host machine, levearing docker containers.
43 |
44 | ```
45 | cd pyicub/docker
46 | COMPOSE_PROFILES=test ./run.sh
47 | ```
48 |
--------------------------------------------------------------------------------
/scripts/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | echo "Running container startup configuration..."
5 |
6 | # ALSA sound card detection
7 | echo "Checking ALSA sound cards..."
8 | CARD_LINE=$(aplay -l 2>/dev/null | grep -E "card [0-9]+:" | grep -i -E "analog|pch|alc|intel|realtek" | head -n 1)
9 |
10 | if [ -z "$CARD_LINE" ]; then
11 | echo "🟡 No analog ALSA card found. Falling back to card 0, device 0"
12 | CARD_NUM=0
13 | DEVICE_NUM=0
14 | else
15 | CARD_NUM=$(echo "$CARD_LINE" | awk '{print $2}' | tr -d ':')
16 | DEVICE_NUM=$(echo "$CARD_LINE" | awk -F'device ' '{print $2}' | awk '{print $1}' | tr -d ':')
17 | echo "🟢 Using ALSA card $CARD_NUM, device $DEVICE_NUM"
18 | fi
19 |
20 | # Check X11 socket(s)
21 | if compgen -G "/tmp/.X11-unix/X*" > /dev/null; then
22 | echo "🟢 X11 socket(s) found:"
23 | ls -1 /tmp/.X11-unix/X* | xargs -n1 echo " "
24 | else
25 | echo "🟡 No X11 sockets found. GUI apps may fail."
26 | fi
27 |
28 | # Check PulseAudio socket
29 | if [[ ! -S ${XDG_RUNTIME_DIR}/pulse/native ]]; then
30 | echo "🟡 PulseAudio socket missing. Audio via Pulse may fail."
31 | else
32 | echo "🟢 PulseAudio socket is ready."
33 | fi
34 |
35 | echo "Container initialization complete. All systems checked."
36 |
--------------------------------------------------------------------------------
/examples/0_YARP/1.callback.py:
--------------------------------------------------------------------------------
1 | import yarp
2 | from pyicub.core.ports import BufferedReadPort, BufferedPort
3 | from pyicub.core.logger import YarpLogger
4 | from threading import Thread
5 | from random import randint
6 |
7 |
8 | class Reader:
9 | def __init__(self):
10 | self.port = BufferedReadPort("/reader:i", "/writer:o", callback=self.detectMsg)
11 | self.log = YarpLogger.getLogger()
12 |
13 | def detectMsg(self, bot):
14 | self.log.debug("READER receiving : " + bot.toString())
15 | return True
16 |
17 |
18 | class Writer:
19 | def __init__(self):
20 | self.port = BufferedPort()
21 | self.port.open("/writer:o")
22 |
23 | def sendMsg (self, top):
24 | for i in range (1, top):
25 | msg = "item " + str(i)
26 | self.port.write(msg)
27 | yarp.delay(randint(1,5))
28 |
29 |
30 |
31 | if __name__ == '__main__':
32 |
33 | yarp.Network.init()
34 | log = YarpLogger.getLogger()
35 |
36 | writer = Writer()
37 | log.debug("init WRITER")
38 | reader = Reader()
39 | log.debug("init READER")
40 |
41 | log.debug("start writing")
42 | writing = Thread(target=writer.sendMsg(3))
43 | writing.start()
44 | writing.join()
45 | log.debug("end writing")
46 |
47 | yarp.Network.fini()
--------------------------------------------------------------------------------
/examples/4_Actions/json/CustomAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "steps": [
3 | {
4 | "name": "Step1",
5 | "limb_motions": {},
6 | "gaze_motion": null,
7 | "custom_calls": [
8 | {
9 | "target": "gaze.lookAtAbsAngles",
10 | "args": [
11 | 0.0,
12 | 15.0,
13 | 0.0
14 | ]
15 | },
16 | {
17 | "target": "emo.neutral",
18 | "args": []
19 | }
20 | ],
21 | "offset_ms": null
22 | },
23 | {
24 | "name": "Step2",
25 | "limb_motions": {},
26 | "gaze_motion": null,
27 | "custom_calls": [
28 | {
29 | "target": "gaze.lookAtAbsAngles",
30 | "args": [
31 | 0.0,
32 | 0.0,
33 | 0.0
34 | ]
35 | },
36 | {
37 | "target": "emo.smile",
38 | "args": []
39 | }
40 | ],
41 | "offset_ms": null
42 | }
43 | ],
44 | "wait_for_steps": [
45 | true,
46 | true
47 | ],
48 | "name": "CustomAction",
49 | "description": "empty",
50 | "offset_ms": null
51 | }
--------------------------------------------------------------------------------
/scripts/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source "$(dirname "$0")/common.sh"
4 |
5 | initialize_environment
6 | source "$(dirname "$0")/setup.sh"
7 |
8 | PYICUB_ENV_FILE="$HOME/.pyicub_env"
9 | BASHRC_FILE="$HOME/.bashrc"
10 |
11 | check_existing_yarpserver
12 |
13 | start_local_yarprun
14 |
15 | if [[ "${ICUB_SIMULATION}" == "false" ]]; then
16 | if wait_for_icub_host 5; then
17 | ensure_ssh_key_installed
18 | start_icub_yarprun
19 | export ICUB_NAME=icub
20 | else
21 | exit 1;
22 | fi
23 | else
24 | export ICUB_NAME=icubSim
25 | fi
26 |
27 |
28 | # Save environment variables
29 | echo "Writing environment variables to $PYICUB_ENV_FILE"
30 | {
31 | echo "export ICUB_SIMULATION=$ICUB_SIMULATION"
32 | echo "export ICUB_NAME=$ICUB_NAME"
33 | echo "export ICUB_APPS=${ICUB_APPS}"
34 | } > "$PYICUB_ENV_FILE"
35 |
36 | # Inject into .bashrc if not already present
37 | if ! grep -q 'source ~/.pyicub_env' "$BASHRC_FILE"; then
38 | echo -e "\n# Load PyiCub environment automatically" >> "$BASHRC_FILE"
39 | echo "source ~/.pyicub_env" >> "$BASHRC_FILE"
40 | echo "Added environment loader to $BASHRC_FILE"
41 | else
42 | echo "Environment loader already present in $BASHRC_FILE"
43 | fi
44 |
45 | terminator 2>/dev/null &
46 |
47 | echo "Launching yarpmanager..."
48 | yarpmanager --apppath "${ICUB_APPS}/applications" --from "${ICUB_APPS}/applications/cluster-config.xml"
49 |
50 | if [[ "${ICUB_SIMULATION}" == "false" ]]; then
51 | cleanup_remote_processes
52 | fi
53 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | Istituto Italiano di Tecnologia, Genova
5 |
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 |
11 | 1. Redistributions of source code must retain the above copyright notice, this
12 | list of conditions and the following disclaimer.
13 |
14 | 2. Redistributions in binary form must reproduce the above copyright notice,
15 | this list of conditions and the following disclaimer in the documentation
16 | and/or other materials provided with the distribution.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/examples/0_YARP/2.logger.py:
--------------------------------------------------------------------------------
1 | import yarp
2 | from pyicub.core.ports import BufferedReadPort, BufferedPort
3 | from pyicub.core.logger import PyicubLogger, YarpLogger
4 | from threading import Thread
5 | from random import randint
6 |
7 | class Reader:
8 | def __init__(self, logger):
9 | self.log = logger
10 | self.port = BufferedReadPort("/reader:i", "/writer:o", callback=self.detectMsg)
11 |
12 | def detectMsg(self, bot):
13 | self.log.debug("READER receiving : " + bot.toString())
14 | return True
15 |
16 |
17 | class Writer:
18 | def __init__(self, logger):
19 | self.log = logger
20 | self.port = BufferedPort()
21 | self.port.open("/writer:o")
22 |
23 | def sendMsg (self, top):
24 | for i in range (1, top):
25 | msg = "item " + str(i)
26 | self.port.write(msg)
27 | self.log.debug("WRITER sending %s " % msg)
28 | yarp.delay(randint(1,5))
29 |
30 |
31 |
32 | if __name__ == '__main__':
33 |
34 | yarp.Network.init()
35 | mylog = YarpLogger.getLogger()
36 | #mylog = PyicubLogger.getLogger()
37 |
38 | writer = Writer(logger=mylog)
39 | mylog.info("init WRITER")
40 | reader = Reader(logger=mylog)
41 | mylog.info("init READER")
42 |
43 | mylog.info("start writing")
44 | writing1 = Thread(target=writer.sendMsg(5))
45 | writing1.start()
46 | writing2 = Thread(target=writer.sendMsg(10))
47 | writing2.start()
48 | writing1.join()
49 | writing2.join()
50 |
51 | mylog.info("end writing")
52 |
53 | yarp.Network.fini()
--------------------------------------------------------------------------------
/examples/6_REST/3.actions/actions/LookAtAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "steps": [
3 | {
4 | "name": "Step1",
5 | "limb_motions": {},
6 | "gaze_motion": {
7 | "checkpoints": [
8 | [
9 | -1.0,
10 | -0.5,
11 | 1.0
12 | ],
13 | [
14 | -1.0,
15 | -0.2,
16 | 0.5
17 | ],
18 | [
19 | -1.0,
20 | 0.2,
21 | 0.1
22 | ]
23 | ],
24 | "lookat_method": "lookAtFixationPoint"
25 | },
26 | "custom_calls": [],
27 | "offset_ms": null
28 | },
29 | {
30 | "name": "Step2",
31 | "limb_motions": {},
32 | "gaze_motion": {
33 | "checkpoints": [
34 | [
35 | 0.0,
36 | 0.0,
37 | 0.0,
38 | true,
39 | 1.5
40 | ]
41 | ],
42 | "lookat_method": "lookAtAbsAngles"
43 | },
44 | "custom_calls": [],
45 | "offset_ms": null
46 | }
47 | ],
48 | "wait_for_steps": [
49 | true,
50 | true
51 | ],
52 | "name": "LookAtAction",
53 | "description": null,
54 | "offset_ms": null
55 | }
--------------------------------------------------------------------------------
/examples/7_FSM/3.icub_rest/actions/LookAtAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "steps": [
3 | {
4 | "name": "Step1",
5 | "limb_motions": {},
6 | "gaze_motion": {
7 | "checkpoints": [
8 | [
9 | -1.0,
10 | -0.5,
11 | 1.0
12 | ],
13 | [
14 | -1.0,
15 | -0.2,
16 | 0.5
17 | ],
18 | [
19 | -1.0,
20 | 0.2,
21 | 0.1
22 | ]
23 | ],
24 | "lookat_method": "lookAtFixationPoint"
25 | },
26 | "custom_calls": [],
27 | "offset_ms": null
28 | },
29 | {
30 | "name": "Step2",
31 | "limb_motions": {},
32 | "gaze_motion": {
33 | "checkpoints": [
34 | [
35 | 0.0,
36 | 0.0,
37 | 0.0,
38 | true,
39 | 1.5
40 | ]
41 | ],
42 | "lookat_method": "lookAtAbsAngles"
43 | },
44 | "custom_calls": [],
45 | "offset_ms": null
46 | }
47 | ],
48 | "wait_for_steps": [
49 | true,
50 | true
51 | ],
52 | "name": "LookAtAction",
53 | "description": null,
54 | "offset_ms": null
55 | }
--------------------------------------------------------------------------------
/examples/7_FSM/4.icub_multiple/actions/LookAtAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "steps": [
3 | {
4 | "name": "Step1",
5 | "limb_motions": {},
6 | "gaze_motion": {
7 | "checkpoints": [
8 | [
9 | -1.0,
10 | -0.5,
11 | 1.0
12 | ],
13 | [
14 | -1.0,
15 | -0.2,
16 | 0.5
17 | ],
18 | [
19 | -1.0,
20 | 0.2,
21 | 0.1
22 | ]
23 | ],
24 | "lookat_method": "lookAtFixationPoint"
25 | },
26 | "custom_calls": [],
27 | "offset_ms": null
28 | },
29 | {
30 | "name": "Step2",
31 | "limb_motions": {},
32 | "gaze_motion": {
33 | "checkpoints": [
34 | [
35 | 0.0,
36 | 0.0,
37 | 0.0,
38 | true,
39 | 1.5
40 | ]
41 | ],
42 | "lookat_method": "lookAtAbsAngles"
43 | },
44 | "custom_calls": [],
45 | "offset_ms": null
46 | }
47 | ],
48 | "wait_for_steps": [
49 | true,
50 | true
51 | ],
52 | "name": "LookAtAction",
53 | "description": null,
54 | "offset_ms": null
55 | }
--------------------------------------------------------------------------------
/examples/9_LLM/REST/server.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp
30 |
31 | app = iCubRESTApp()
32 | app.rest_manager.run_forever()
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/examples/8_Attention/REST/server.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp
30 | import os
31 |
32 | app = iCubRESTApp()
33 | app.rest_manager.run_forever()
34 |
35 |
--------------------------------------------------------------------------------
/icub-apps/gazebo/icub-world.sdf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 100
6 |
7 |
8 |
9 | model://sun
10 |
11 |
12 |
13 | 0.197302 -0.215077 1 0 -0 0
14 | 0.5 0.5 0.5 1
15 | 0.1 0.1 0.1 1
16 |
17 | 20
18 | 0.5
19 | 0.01
20 | 0.001
21 |
22 | 0
23 | 0 0 -1
24 |
25 |
26 |
27 |
28 |
29 | 0 0 10 0 -0 3.14
30 |
31 |
32 |
33 | 0.197302 -0.215077 1 0 -0 0
34 |
35 |
36 |
37 |
38 | model://ground_plane
39 |
40 |
41 |
42 |
43 | model://iCubGazeboV2_5_visuomanip
44 | 0.0 0.0 0.63 0.0 0.0 0.0
45 |
46 |
47 |
48 |
49 |
50 | -1.73754 2.13332 1.77051 0 0.463643 -1.0638
51 | orbit
52 | perspective
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/examples/4_Actions/3.imported_action.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub
30 |
31 | icub = iCub()
32 | action_id = icub.importAction("json/LookAtAction.json")
33 | icub.playAction(action_id)
34 |
--------------------------------------------------------------------------------
/examples/4_Actions/9.from_repository.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub
30 |
31 |
32 | icub = iCub(action_repository_path='./json')
33 |
34 | icub.playAction("LookAtAction")
35 | icub.playAction("HeadAction")
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .venv
86 | env/
87 | venv/
88 | ENV/
89 | env.bak/
90 | venv.bak/
91 |
92 | # Spyder project settings
93 | .spyderproject
94 | .spyproject
95 |
96 | # Rope project settings
97 | .ropeproject
98 |
99 | # mkdocs documentation
100 | /site
101 |
102 | # mypy
103 | .mypy_cache/
104 |
--------------------------------------------------------------------------------
/examples/6_REST/3.actions/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp
30 | import os
31 |
32 | app = iCubRESTApp(action_repository_path=os.path.join(os.getcwd(), 'actions'))
33 | app.rest_manager.run_forever()
34 |
35 |
--------------------------------------------------------------------------------
/tests/test_core.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import pytest
30 |
31 | @pytest.mark.smoke
32 | def test_import_pyicub():
33 | try:
34 | import pyicub
35 | except ImportError as e:
36 | pytest.fail(f"Failed to import pyicub: {e}")
37 |
--------------------------------------------------------------------------------
/examples/4_Actions/json/LookAtAction.json:
--------------------------------------------------------------------------------
1 | {
2 | "steps": [
3 | {
4 | "name": "Step1",
5 | "limb_motions": {},
6 | "gaze_motion": {
7 | "checkpoints": [
8 | [
9 | -1.0,
10 | -0.5,
11 | 1.0,
12 | true,
13 | 2.0
14 | ],
15 | [
16 | -1.0,
17 | -0.2,
18 | 0.5,
19 | true,
20 | 2.0
21 | ],
22 | [
23 | -1.0,
24 | 0.2,
25 | 0.1,
26 | true,
27 | 2.0
28 | ]
29 | ],
30 | "lookat_method": "lookAtFixationPoint"
31 | },
32 | "custom_calls": [],
33 | "offset_ms": null
34 | },
35 | {
36 | "name": "Step2",
37 | "limb_motions": {},
38 | "gaze_motion": {
39 | "checkpoints": [
40 | [
41 | 0.0,
42 | 0.0,
43 | 0.0,
44 | true,
45 | 1.5
46 | ]
47 | ],
48 | "lookat_method": "lookAtAbsAngles"
49 | },
50 | "custom_calls": [],
51 | "offset_ms": null
52 | }
53 | ],
54 | "wait_for_steps": [
55 | true,
56 | true
57 | ],
58 | "name": "LookAtAction",
59 | "description": null,
60 | "offset_ms": null
61 | }
--------------------------------------------------------------------------------
/docker/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | echo "Running host pre-launch configuration..."
5 |
6 | if [[ -n "$GITHUB_ACTIONS" ]]; then
7 | echo "Running on GitHub Actions — skipping host setup."
8 | export DOCKER_RUNTIME=runc
9 | export GPU_DEVICES=none
10 | return 0
11 | fi
12 |
13 | # Ensure PulseAudio is running
14 | if ! pactl info > /dev/null 2>&1; then
15 | echo "🟡 PulseAudio not running. Trying to start it..."
16 | pulseaudio --start || echo "[ERROR] Failed to start PulseAudio."
17 | fi
18 |
19 | # Grant X11 access
20 | if command -v xhost &> /dev/null; then
21 | xhost +local:docker > /dev/null
22 | echo "🟢 X11 access granted to Docker containers."
23 | else
24 | echo "🟡 'xhost' not found. GUI apps may not display correctly."
25 | fi
26 |
27 | # Check Pulse socket
28 | PULSE_SOCKET="$XDG_RUNTIME_DIR/pulse/native"
29 | if [[ ! -S "$PULSE_SOCKET" ]]; then
30 | echo "🟡 PulseAudio socket not found at $PULSE_SOCKET"
31 | else
32 | echo "🟢 PulseAudio socket found: $PULSE_SOCKET"
33 | fi
34 |
35 | # Detect GPU availability
36 | if command -v nvidia-smi &> /dev/null && nvidia-smi -L &> /dev/null; then
37 | echo "🟢 GPU detected — enabling NVIDIA runtime"
38 | export DOCKER_RUNTIME=nvidia
39 | export GPU_DEVICES=all
40 | else
41 | echo "🔵 No GPU found — falling back to CPU mode"
42 | export DOCKER_RUNTIME=runc
43 | export GPU_DEVICES=none
44 | fi
45 |
46 | # SSH Agent detection and sharing
47 | if [[ -S "$SSH_AUTH_SOCK" ]]; then
48 | echo "🟢 SSH agent detected at $SSH_AUTH_SOCK"
49 | export SSH_AUTH_SOCK
50 | else
51 | echo "🟡 SSH agent not running. Please start it and add your keys (ssh-agent / ssh-add)."
52 | echo " Example: eval \$(ssh-agent) && ssh-add ~/.ssh/id_rsa"
53 | fi
54 |
55 | echo "Host setup successful. Ready to launch Docker containers."
56 |
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/template/params/msg.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import TemplateParameter
30 |
31 | w1 = TemplateParameter(name="welcome_msg", value="hello world")
32 | w1.exportJSONFile("msg1.json")
33 |
34 | w2 = TemplateParameter(name="welcome_msg", value="welcome world")
35 | w2.exportJSONFile("msg2.json")
--------------------------------------------------------------------------------
/examples/7_FSM/6.icub_rest_import/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, iCubFSM
30 | from pyicub.actions import iCubFullbodyAction
31 |
32 | import os
33 |
34 | app = iCubRESTApp()
35 |
36 | fsm = iCubFSM()
37 | fsm.importFromJSONFile('fsm.json')
38 |
39 | app.setFSM(fsm)
40 | app.rest_manager.run_forever()
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/template/params/msg.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import TemplateParameter
30 |
31 | w1 = TemplateParameter(name="welcome_msg", value="hello world")
32 | w1.exportJSONFile("msg1.json")
33 |
34 | w2 = TemplateParameter(name="welcome_msg", value="welcome world")
35 | w2.exportJSONFile("msg2.json")
--------------------------------------------------------------------------------
/pyicub/modules/face.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.core.ports import BufferedWritePort
30 |
31 | class facePyCtrl:
32 |
33 | def __init__(self, robot):
34 | self.__faceraw_port__ = BufferedWritePort('/face/raw/out', '/%s/face/raw/in' % robot)
35 |
36 | def sendRaw(self, cmd):
37 | self.__faceraw_port__.write(cmd)
38 |
--------------------------------------------------------------------------------
/examples/3_Modules/3.runtimemodule.py:
--------------------------------------------------------------------------------
1 |
2 | # BSD 2-Clause License
3 | #
4 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
5 | # Istituto Italiano di Tecnologia, Genova
6 | #
7 | # All rights reserved.
8 | #
9 | # Redistribution and use in source and binary forms, with or without
10 | # modification, are permitted provided that the following conditions are met:
11 | #
12 | # 1. Redistributions of source code must retain the above copyright notice, this
13 | # list of conditions and the following disclaimer.
14 | #
15 | # 2. Redistributions in binary form must reproduce the above copyright notice,
16 | # this list of conditions and the following disclaimer in the documentation
17 | # and/or other materials provided with the distribution.
18 | #
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 |
31 | from pyicub.helper import iCub
32 |
33 | class myCustomModule:
34 |
35 | def test(self):
36 | print("test message from my custom module")
37 |
38 | icub = iCub()
39 | icub.addRuntimeModule(name='test_module', module=myCustomModule())
40 |
41 | input("PRESS A KEY TO CONTINUE")
42 | icub.test_module.test()
43 |
44 |
--------------------------------------------------------------------------------
/examples/6_REST/6.topics/2.subscriber.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | from pyicub.rest import iCubRESTSubscriber
31 |
32 | def on_enter_foo(args):
33 | print("on enter ", args)
34 |
35 | def on_exit_foo(args):
36 | print("on exit ", args)
37 |
38 | serv = iCubRESTSubscriber()
39 | serv.subscribe_topic(topic_uri="http://localhost:9001/pyicub/generic/Publisher/Publisher.foo", on_enter=on_enter_foo, on_exit=on_exit_foo)
40 | serv.run_forever()
41 |
--------------------------------------------------------------------------------
/pyicub/__init__.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | __name__ = 'PyiCub'
31 | __authors__ = 'Davide De Tommaso, Adam Lukomski, Nicola Russi, Enrico Piacenti, Gioele Migno, Mohammad Gharb'
32 | __emails__ = 'davide.detommaso@iit.it, adam.lukomski@iit.it, nicola.russi@iit.it, enrico.piacenti@iit.it, gioele.migno@iit.it, mohammad.gharb@iit.it'
33 | __license__ = 'BSD-2'
34 | __version__ = '8.3.5'
35 | __description__ = 'Developing iCub applications using Python'
36 |
--------------------------------------------------------------------------------
/examples/6_REST/2.input_args/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, rest_service
30 |
31 | class myRESTApp(iCubRESTApp):
32 |
33 | @rest_service
34 | def process(self):
35 | return "I am processing my arguments ... " + str(self.getArgs())
36 |
37 | app = myRESTApp(arg1="your-arg1-value", arg2=[1,2,3,4], arg3=["option1", "option2"], arg4={"key1": 1, "key2": [1,2]})
38 | app.rest_manager.run_forever()
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from setuptools import setup
30 | import setuptools
31 |
32 | import pyicub
33 |
34 | setup(name='pyicub',
35 | version=pyicub.__version__,
36 | description=pyicub.__description__,
37 | url='http://github.com/s4hri/pyicub',
38 | author=pyicub.__authors__,
39 | author_email=pyicub.__emails__,
40 | license=pyicub.__license__,
41 | packages=setuptools.find_packages(),
42 | zip_safe=False)
43 |
--------------------------------------------------------------------------------
/examples/5_Templates/1.hello/3.run_welcome.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, iCubActionTemplate
30 | from pyicub.utils import importFromJSONFile
31 |
32 |
33 | icub = iCub()
34 |
35 | template = icub.importTemplate(JSON_file="json/hello.json")
36 | template.setParam(JSON_file="json/step1.json")
37 | template.setParam(JSON_file="json/msg1.json")
38 | action = template.getAction()
39 | action_id = icub.addAction(action)
40 | icub.playAction(action_id)
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/3_Modules/2.face_landmarks.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub
30 | import time
31 | icub = iCub()
32 |
33 | for j in range(100):
34 | # get number of face detected
35 | faces = icub.facelandmarks.getFaces()
36 | if faces > 0:
37 | for i in range(faces):
38 | # for each face get center eyes
39 | center_eye = icub.facelandmarks.getCenterEyes(i)
40 | print("face %i - [x: %s , y: %s ]" % (i+1, center_eye[0], center_eye[1]))
41 | else:
42 | # no face detected
43 | print("no face detected")
44 |
45 | time.sleep(0.1)
46 |
--------------------------------------------------------------------------------
/examples/6_REST/1.client_server/2.client.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulClient
30 |
31 | robot_name='generic'
32 | app_name='myServer'
33 |
34 | client = PyiCubRESTfulClient(host='localhost', port=9001)
35 |
36 | req_id = client.run_target_async(robot_name, app_name, target_name='myServer.foo')
37 |
38 | res = client.run_target(robot_name, app_name, target_name='myServer.hello_world', name='Johnny')
39 | print(res)
40 |
41 | res = client.run_target(robot_name, app_name, target_name='myServer.date', date_format='%b-%d-%Y')
42 | print(res)
43 |
44 | print(client.wait_until_completed(req_id))
45 | print(client.get_request_info(req_id))
--------------------------------------------------------------------------------
/examples/7_FSM/2.semaphore_subs/3.cmd.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulClient
30 |
31 | import random
32 |
33 | client = PyiCubRESTfulClient(host='localhost', port=9001)
34 |
35 | print("PyiCub ver: ", client.get_version())
36 |
37 | triggers = ["init>RED", "RED>GREEN", "GREEN>YELLOW", "YELLOW>init"]
38 |
39 | while True:
40 | input("Press ENTER to run the FSM (CTRL+C to exit): ")
41 | for trigger in triggers:
42 | msg = input("Type a message and press ENTER to send the trigger %s : " % trigger)
43 | res = client.fsm_runStep(robot_name='generic', app_name='Publisher', trigger=trigger, msg=msg, wait_time=random.randrange(1,2))
44 | print(res)
45 |
--------------------------------------------------------------------------------
/examples/6_REST/1.client_server/1.server.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulServer, rest_service
30 | from datetime import date
31 |
32 | import time
33 |
34 | class myServer(PyiCubRESTfulServer):
35 |
36 | @rest_service
37 | def hello_world(self, name: str='you'):
38 | return "Hello world %s!" % name
39 |
40 | @rest_service
41 | def date(self, date_format: str="%d/%m/%Y"):
42 | today = date.today()
43 | return today.strftime(date_format)
44 |
45 | @rest_service
46 | def foo(self):
47 | time.sleep(5)
48 | return "I've done a lot of stuff!"
49 |
50 | app = myServer()
51 | app.rest_manager.run_forever()
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/examples/6_REST/6.topics/1.publisher.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulServer, rest_service
30 | from datetime import date
31 |
32 | import time
33 |
34 | class Publisher(PyiCubRESTfulServer):
35 |
36 | @rest_service
37 | def hello_world(self, name: str='you'):
38 | return "Hello world %s!" % name
39 |
40 | @rest_service
41 | def date(self, date_format: str="%d/%m/%Y"):
42 | today = date.today()
43 | return today.strftime(date_format)
44 |
45 | @rest_service
46 | def foo(self):
47 | time.sleep(5)
48 | return "I've done a lot of stuff!"
49 |
50 | app = Publisher()
51 | app.rest_manager.run_forever()
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/1.hello_world.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCub, iCubRESTApp
30 |
31 | import os
32 |
33 | from pyicub.helper import iCub, iCubActionTemplate
34 | from pyicub.utils import importFromJSONFile
35 |
36 |
37 | icub = iCub()
38 |
39 | template = icub.importTemplate(JSON_file="template/welcome.json")
40 | template.setParam(JSON_file="template/params/msg1.json")
41 | action1 = template.getAction(action_name="Welcome1")
42 |
43 | template = icub.importTemplate(JSON_file="template/welcome.json")
44 | template.setParam(JSON_file="template/params/msg2.json")
45 | action2 = template.getAction(action_name="Welcome2")
46 |
47 | app = iCubRESTApp()
48 | app.importAction(action1)
49 | app.importAction(action2)
50 | app.rest_manager.run_forever()
51 |
52 |
--------------------------------------------------------------------------------
/examples/7_FSM/3.icub_rest/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, iCubFSM
30 | from pyicub.actions import iCubFullbodyAction
31 | from pyicub.fsm import FSM
32 |
33 | logger = FSM.getLogger()
34 |
35 | app = iCubRESTApp()
36 |
37 | head_action = iCubFullbodyAction(JSON_file="actions/HeadAction.json")
38 | lookat_action = iCubFullbodyAction(JSON_file="actions/LookAtAction.json")
39 |
40 | fsm = iCubFSM()
41 | head_state = fsm.addAction(head_action)
42 | lookat_state = fsm.addAction(lookat_action)
43 |
44 | fsm.addTransition(iCubFSM.INIT_STATE, head_state)
45 | fsm.addTransition(head_state, lookat_state)
46 | fsm.addTransition(lookat_state, head_state)
47 | fsm.addTransition(lookat_state, iCubFSM.INIT_STATE)
48 |
49 | fsm.draw('diagram.png')
50 | fsm.exportJSONFile('fsm.json')
51 |
52 | app.setFSM(fsm)
53 | app.rest_manager.run_forever()
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/template/welcome.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCubActionTemplate, iCubFullbodyStep
30 |
31 | class Step(iCubFullbodyStep):
32 |
33 | def __init__(self, welcome_msg, offset_ms=None, name=None, JSON_dict=None, JSON_file=None):
34 | self.welcome_msg = welcome_msg
35 | super().__init__(offset_ms, name, JSON_dict, JSON_file)
36 |
37 | def prepare(self):
38 | self.createCustomCall(target="speech.say", args=(self.welcome_msg,))
39 |
40 |
41 | class TemplateAction(iCubActionTemplate):
42 |
43 | def prepare_params(self):
44 | self.createParam(name="welcome_msg")
45 |
46 | def prepare(self):
47 | welcome_msg = self.getParam("welcome_msg")
48 | self.addStep(Step(welcome_msg))
49 |
50 | template = TemplateAction()
51 | template.exportJSONFile("welcome.json")
52 |
--------------------------------------------------------------------------------
/examples/6_REST/4.templates/template/welcome.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCubActionTemplate, iCubFullbodyStep
30 |
31 | class Step(iCubFullbodyStep):
32 |
33 | def __init__(self, welcome_msg, offset_ms=None, name=None, JSON_dict=None, JSON_file=None):
34 | self.welcome_msg = welcome_msg
35 | super().__init__(offset_ms, name, JSON_dict, JSON_file)
36 |
37 | def prepare(self):
38 | self.createCustomCall(target="speech.say", args=(self.welcome_msg,))
39 |
40 |
41 | class TemplateAction(iCubActionTemplate):
42 |
43 | def prepare_params(self):
44 | self.createParam(name="welcome_msg")
45 |
46 | def prepare(self):
47 | welcome_msg = self.getParam("welcome_msg")
48 | self.addStep(Step(welcome_msg))
49 |
50 | template = TemplateAction("Welcome")
51 | template.exportJSONFile("welcome.json")
52 |
--------------------------------------------------------------------------------
/examples/7_FSM/4.icub_multiple/FSM_A.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "FSM_A",
3 | "states": [
4 | {
5 | "name": "LookAtAction",
6 | "description": null
7 | }
8 | ],
9 | "transitions": [
10 | {
11 | "trigger": "init>LookAtAction",
12 | "source": "init",
13 | "dest": "LookAtAction"
14 | }
15 | ],
16 | "initial_state": "init",
17 | "actions": {
18 | "LookAtAction": {
19 | "steps": [
20 | {
21 | "name": "Step1",
22 | "limb_motions": {},
23 | "gaze_motion": {
24 | "checkpoints": [
25 | [
26 | -1.0,
27 | -0.5,
28 | 1.0
29 | ],
30 | [
31 | -1.0,
32 | -0.2,
33 | 0.5
34 | ],
35 | [
36 | -1.0,
37 | 0.2,
38 | 0.1
39 | ]
40 | ],
41 | "lookat_method": "lookAtFixationPoint"
42 | },
43 | "custom_calls": [],
44 | "offset_ms": null
45 | },
46 | {
47 | "name": "Step2",
48 | "limb_motions": {},
49 | "gaze_motion": {
50 | "checkpoints": [
51 | [
52 | 0.0,
53 | 0.0,
54 | 0.0,
55 | true,
56 | 1.5
57 | ]
58 | ],
59 | "lookat_method": "lookAtAbsAngles"
60 | },
61 | "custom_calls": [],
62 | "offset_ms": null
63 | }
64 | ],
65 | "wait_for_steps": [
66 | true,
67 | true
68 | ],
69 | "name": "LookAtAction",
70 | "description": null,
71 | "offset_ms": null
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/examples/4_Actions/5.custom_actions.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, iCubFullbodyAction, iCubFullbodyStep
30 |
31 | import os
32 |
33 | class Step1(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 | self.createCustomCall(target="gaze.lookAtAbsAngles", args=(0.0, 15.0, 0.0,))
37 | self.createCustomCall(target="emo.neutral")
38 |
39 | class Step2(iCubFullbodyStep):
40 |
41 | def prepare(self):
42 | self.createCustomCall(target="gaze.lookAtAbsAngles", args=(0.0, 0.0, 0.0,))
43 | self.createCustomCall(target="emo.smile")
44 |
45 | class CustomAction(iCubFullbodyAction):
46 |
47 | def prepare(self):
48 | self.addStep(Step1())
49 | self.addStep(Step2())
50 |
51 |
52 | action = CustomAction()
53 | icub = iCub()
54 | action_id = icub.addAction(action)
55 | icub.playAction(action_id)
56 | icub.exportAction(action_id=action_id, path=os.path.join(os.getcwd(), 'json'))
57 |
--------------------------------------------------------------------------------
/examples/7_FSM/5.icub_subs/2.sub.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | from pyicub.rest import RESTSubscriberFSM
31 |
32 | class Subscriber(RESTSubscriberFSM):
33 |
34 | def on_enter_state(self, fsm_name, session_id, session_count, state_name, state_count):
35 | print("on enter state: ", fsm_name, session_id, session_count, state_name, state_count)
36 |
37 | def on_exit_state(self, fsm_name, session_id, session_count, state_name, state_count):
38 | print("on exit state: ", fsm_name, session_id, session_count, state_name, state_count)
39 |
40 | def on_enter_fsm(self, fsm_name, session_id, session_count):
41 | print("on enter fsm: ", fsm_name, session_id, session_count)
42 |
43 | def on_exit_fsm(self, fsm_name, session_id, session_count):
44 | print("on exit fsm: ", fsm_name, session_id, session_count)
45 |
46 | app = Subscriber(server_host="localhost", server_port=9001, robot_name="icubSim", app_name="Publisher")
47 | app.rest_manager.run_forever()
48 |
--------------------------------------------------------------------------------
/examples/7_FSM/2.semaphore_subs/2.sub.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | from pyicub.rest import RESTSubscriberFSM
31 |
32 | class Subscriber(RESTSubscriberFSM):
33 |
34 | def on_enter_state(self, fsm_name, session_id, session_count, state_name, state_count):
35 | print("on enter state: ", fsm_name, session_id, session_count, state_name, state_count)
36 |
37 | def on_exit_state(self, fsm_name, session_id, session_count, state_name, state_count):
38 | print("on exit state: ", fsm_name, session_id, session_count, state_name, state_count)
39 |
40 | def on_enter_fsm(self, fsm_name, session_id, session_count):
41 | print("on enter fsm: ", fsm_name, session_id, session_count)
42 |
43 | def on_exit_fsm(self, fsm_name, session_id, session_count):
44 | print("on exit fsm: ", fsm_name, session_id, session_count)
45 |
46 | app = Subscriber(server_host="localhost", server_port=9001, robot_name="generic", app_name="Publisher")
47 | app.rest_manager.run_forever()
48 |
--------------------------------------------------------------------------------
/examples/4_Actions/2.lookat_actions.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, iCubFullbodyStep, iCubFullbodyAction
30 |
31 | import os
32 |
33 | class Step1(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 | g1 = self.createGazeMotion("lookAtFixationPoint")
37 | g1.addCheckpoint([-1.0, -0.5, 1.0, True, 2.0])
38 | g1.addCheckpoint([-1.0, -0.2, 0.5, True, 2.0])
39 | g1.addCheckpoint([-1.0, 0.2, 0.1, True, 2.0])
40 |
41 | class Step2(iCubFullbodyStep):
42 |
43 | def prepare(self):
44 | g2 = self.createGazeMotion("lookAtAbsAngles")
45 | g2.addCheckpoint([0.0, 0.0, 0.0, True, 1.5])
46 |
47 | class LookAtAction(iCubFullbodyAction):
48 |
49 | def prepare(self):
50 | self.addStep(Step1())
51 | self.addStep(Step2())
52 |
53 |
54 | action = LookAtAction()
55 | icub = iCub()
56 | action_id = icub.addAction(action)
57 | icub.playAction(action_id)
58 | icub.exportAction(action_id=action_id, path=os.path.join(os.getcwd(), 'json'))
59 |
--------------------------------------------------------------------------------
/examples/5_Templates/1.hello/2.create_params.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import JointsTrajectoryCheckpoint, LimbMotion, JointPose, ICUB_HEAD, iCubFullbodyStep, TemplateParameter
30 | from pyicub.utils import exportJSONFile
31 |
32 | class Step(iCubFullbodyStep):
33 |
34 | def prepare(self):
35 | pose_up = JointPose(target_joints=[20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
36 | pose_down = JointPose(target_joints=[-20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
37 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
38 | motion = self.createLimbMotion(ICUB_HEAD)
39 | motion.createJointsTrajectory(pose_up, duration=3.0)
40 | motion.createJointsTrajectory(pose_down, duration=3.0)
41 | motion.createJointsTrajectory(pose_home, duration=3.0)
42 |
43 | param1 = TemplateParameter(name="step_bodymotion", value=Step())
44 | param1.exportJSONFile("json/step1.json")
45 |
46 | param2 = TemplateParameter(name="welcome_msg", value="hello world")
47 | param2.exportJSONFile("json/msg1.json")
--------------------------------------------------------------------------------
/examples/5_Templates/1.hello/1.create_template.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCubActionTemplate, iCubFullbodyStep
30 |
31 | class Step(iCubFullbodyStep):
32 |
33 | def __init__(self, welcome_msg, offset_ms=None, name=None, JSON_dict=None, JSON_file=None):
34 | self.welcome_msg = welcome_msg
35 | super().__init__(offset_ms, name, JSON_dict, JSON_file)
36 |
37 | def prepare(self):
38 | self.createCustomCall(target="speech.say", args=(self.welcome_msg,))
39 |
40 |
41 | class TemplateAction(iCubActionTemplate):
42 |
43 | def prepare_params(self):
44 | self.createParam(name="step_bodymotion")
45 | self.createParam(name="welcome_msg")
46 |
47 | def prepare(self):
48 | step_bodymotion = self.getParam("step_bodymotion")
49 | welcome_msg = self.getParam("welcome_msg")
50 | self.addStep(step_bodymotion)
51 | self.addStep(Step(welcome_msg))
52 |
53 |
54 | template = TemplateAction()
55 | template.exportJSONFile("json/hello.json")
56 |
--------------------------------------------------------------------------------
/examples/4_Actions/1.moving_head.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, JointPose, ICUB_HEAD, iCubFullbodyAction, iCubFullbodyStep
30 |
31 | import os
32 |
33 | class Step(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 |
37 | pose_up = JointPose(target_joints=[20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
38 | pose_down = JointPose(target_joints=[-20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
39 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
40 |
41 | motion = self.createLimbMotion(ICUB_HEAD)
42 | motion.createJointsTrajectory(pose_up, duration=3.0)
43 | motion.createJointsTrajectory(pose_down, duration=3.0)
44 | motion.createJointsTrajectory(pose_home, duration=3.0)
45 |
46 | class HeadAction(iCubFullbodyAction):
47 |
48 | def prepare(self):
49 | step = Step()
50 | self.addStep(step)
51 |
52 | action = HeadAction()
53 | icub = iCub()
54 | action_id = icub.addAction(action)
55 | icub.playAction(action_id)
56 | icub.exportAction(action_id=action_id, path=os.path.join(os.getcwd(), 'json'))
57 |
--------------------------------------------------------------------------------
/examples/4_Actions/6.custom_waitmotiondone.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | from pyicub.helper import iCub, JointPose, iCubFullbodyAction, iCubFullbodyStep, ICUB_HEAD
31 |
32 | class Step(iCubFullbodyStep):
33 |
34 | def prepare(self):
35 | pose_up = JointPose(target_joints=[30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
36 | pose_down = JointPose(target_joints=[-30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
37 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
38 |
39 | lm = self.createLimbMotion(ICUB_HEAD)
40 | lm.createJointsTrajectory(pose_up, duration=2.0)
41 | lm.createJointsTrajectory(pose_down, duration=2.0, timeout=1.0)
42 | lm.createJointsTrajectory(pose_home, duration=2.0)
43 |
44 | class GenericPoses(iCubFullbodyAction):
45 |
46 | def prepare(self):
47 | self.addStep(Step())
48 |
49 |
50 | action = GenericPoses()
51 | icub = iCub()
52 | action_id = icub.addAction(action)
53 | icub.playAction(action_id)
54 | icub.getPositionController(ICUB_HEAD).setCustomWaitMotionDone(motion_complete_at=0.8)
55 | icub.playAction(action_id)
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/2.client.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulClient
30 |
31 | client = PyiCubRESTfulClient(host='localhost', port=9001)
32 |
33 | print("PyiCub ver: ", client.get_version())
34 |
35 | robots = client.get_robots()
36 |
37 | print("Robots: ")
38 | for robot in robots:
39 | print("name: '%s' url: '%s'" % (robot.name, robot.url))
40 |
41 | applications = client.get_apps(robot.name)
42 |
43 | print("\t Robot Apps: ")
44 | for app in applications:
45 | print("\t -> name: '%s' url: '%s'" % (app.name, app.url))
46 |
47 | services = client.get_services(robot.name, app.name)
48 |
49 | print("\t\t Applications Services: ")
50 | for service in services.values():
51 | print("\t\t name: '%s' url: '%s'" % (service.name, service.url))
52 |
53 | actions = client.get_robot_actions(robot.name)
54 | print("\t Robot Actions: ")
55 | for action_id in actions:
56 | print("\t -> action_id: %s" % action_id)
57 | client.play_action(robot.name, action_id=action_id)
58 |
--------------------------------------------------------------------------------
/examples/9_LLM/igpt.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import yarp
30 | from pyicub.modules.llm import iGPT
31 |
32 | # Initialize YARP network
33 | yarp.Network.init()
34 |
35 | # Create iGPT client
36 | gpt = iGPT()
37 |
38 | # Check connection
39 | if not gpt.isValid():
40 | print("[ERROR] Could not connect to /GPT/rpc:i")
41 | exit(1)
42 |
43 | # Show module status
44 | print("Module status:", gpt.status())
45 |
46 | # Create and switch to a new session
47 | print("Creating session 'test1'")
48 | print(gpt.create_session("test1"))
49 |
50 | print("Switching to session 'test1'")
51 | print(gpt.switch_session("test1"))
52 |
53 | # Set a custom system prompt
54 | prompt = "You are a wise assistant who answers briefly and accurately."
55 | print("Setting system prompt:")
56 | print(gpt.set_system_prompt(prompt))
57 |
58 | # Run a test query
59 | print("Querying: 'What is the capital of Italy?'")
60 | response = gpt.query("What is the capital of Italy?")
61 | print("Response:", response)
62 |
63 | # List current sessions
64 | print("Active sessions:", gpt.list_sessions())
65 |
66 | # Finish YARP
67 | yarp.Network.fini()
68 |
--------------------------------------------------------------------------------
/examples/4_Actions/8.async_action.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, JointPose, JointsTrajectoryCheckpoint, LimbMotion, GazeMotion, iCubFullbodyAction, PyiCubCustomCall, iCubFullbodyStep, ICUB_HEAD
30 |
31 | import time
32 |
33 | class Step(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 | pose_up = JointPose(target_joints=[30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
37 | pose_down = JointPose(target_joints=[-30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
38 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
39 |
40 | lm = self.createLimbMotion(ICUB_HEAD)
41 | lm.createJointsTrajectory(pose_up, duration=3.0)
42 | lm.createJointsTrajectory(pose_down, duration=3.0, timeout=1.0)
43 | lm.createJointsTrajectory(pose_home, duration=3.0)
44 |
45 | class GenericPoses(iCubFullbodyAction):
46 |
47 | def prepare(self):
48 | self.addStep(Step())
49 |
50 | action = GenericPoses()
51 | icub = iCub()
52 | action_id = icub.addAction(action)
53 | req = icub.playAction(action_id, wait_for_completed=False)
54 | print("Doing some stuff in parallel...")
55 | print("...waiting for action completation...")
56 | req.wait_for_completed()
--------------------------------------------------------------------------------
/pyicub/core/rpc.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import yarp
30 | from pyicub.core.logger import YarpLogger
31 |
32 | class RpcClient:
33 |
34 | def __init__(self, rpc_server_name):
35 | self.__logger__ = YarpLogger.getLogger()
36 | self.__rpc_client__ = yarp.RpcClient()
37 | self.__rpc_client_port_name__ = rpc_server_name + "/rpc_client/commands"
38 | self.__rpc_client__.open(self.__rpc_client_port_name__)
39 | self.__logger__.debug("Connecting %s with %s" % (self.__rpc_client_port_name__, rpc_server_name))
40 | self.__connection_result__ = self.__rpc_client__.addOutput(rpc_server_name)
41 | self.__logger__.debug("Result: %s" % self.__connection_result__)
42 |
43 | @property
44 | def connection_result(self):
45 | return self.__connection_result__
46 |
47 | def execute(self, cmd):
48 | ans = yarp.Bottle()
49 | self.__logger__.debug("Executing RPC command %s" % cmd.toString())
50 | self.__rpc_client__.write(cmd, ans)
51 | self.__logger__.debug("Result: %s" % ans.toString())
52 | return ans
53 |
54 | def __del__(self):
55 | self.__rpc_client__.interrupt()
56 | self.__rpc_client__.close()
57 |
--------------------------------------------------------------------------------
/examples/7_FSM/1.semaphore/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.fsm import FSM
30 | import time
31 | import random
32 |
33 | logger = FSM.getLogger()
34 |
35 | def on_RED(data):
36 | logger.info("Stop!")
37 | time.sleep(data)
38 |
39 | def on_YELLOW(data):
40 | logger.info("Slow down!")
41 | time.sleep(data)
42 |
43 | def on_GREEN(data):
44 | logger.info("Go!")
45 | time.sleep(data)
46 |
47 | fsm = FSM("Semaphore")
48 |
49 | fsm.addState(name="RED", on_enter_callback=on_RED)
50 | fsm.addState(name="YELLOW", on_enter_callback=on_YELLOW)
51 | fsm.addState(name="GREEN", on_enter_callback=on_GREEN)
52 |
53 | # The initial state is always "init"
54 | fsm.addTransition(FSM.INIT_STATE, dest="RED")
55 | fsm.addTransition(source="RED", dest="GREEN")
56 | fsm.addTransition(source="GREEN", dest="YELLOW")
57 | fsm.addTransition(source="YELLOW", dest=FSM.INIT_STATE)
58 |
59 | fsm.draw('diagram.png')
60 |
61 | for i in range(3):
62 | for trigger in fsm.triggers:
63 | fsm.runStep(trigger, data=random.randrange(1,2))
64 | logger.info("Session Count: %d" % fsm.getSessionCount())
65 |
66 | print("\nSTATES: ", fsm.getStates())
67 | print("\nTRANSITIONS: ", fsm.getTransitions())
68 | print("\nFSM: ", fsm.toJSON())
69 |
70 | fsm.exportJSONFile("fsm.json")
71 |
72 |
73 |
--------------------------------------------------------------------------------
/examples/6_REST/5.restfulclient/1.server.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, iCub, rest_service
30 | from datetime import date
31 |
32 | import time
33 | import os
34 |
35 | class myRESTApp(iCubRESTApp):
36 |
37 | @rest_service
38 | def hello_world(self, name: str='you'):
39 | return "Hello world %s!" % name
40 |
41 | @rest_service
42 | def date(self, date_format: str="%d/%m/%Y"):
43 | today = date.today()
44 | return today.strftime(date_format)
45 |
46 | @rest_service
47 | def process(self):
48 | return "I am processing my arguments ... " + str(self.getArgs())
49 |
50 | @rest_service
51 | def foo(self):
52 | time.sleep(5)
53 | return "I've done a lot of stuff!"
54 |
55 | icub = iCub()
56 |
57 | template = icub.importTemplate(JSON_file="template/welcome.json")
58 | template.setParam(JSON_file="template/params/msg1.json")
59 | action1 = template.getAction(action_name="Welcome1")
60 |
61 | template = icub.importTemplate(JSON_file="template/welcome.json")
62 | template.setParam(JSON_file="template/params/msg2.json")
63 | action2 = template.getAction(action_name="Welcome2")
64 |
65 | app = iCubRESTApp()
66 | app.importAction(action1)
67 | app.importAction(action2)
68 | app.rest_manager.run_forever()
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/examples/4_Actions/7.custom_action_speech.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, JointPose, JointsTrajectoryCheckpoint, LimbMotion, GazeMotion, iCubFullbodyAction, PyiCubCustomCall, iCubFullbodyStep, ICUB_HEAD
30 |
31 | class Step(iCubFullbodyStep):
32 |
33 | def prepare(self):
34 | hamlet="""
35 | To be, or not to be, that is the question:
36 | Whether 'tis nobler in the mind to suffer
37 | The slings and arrows of outrageous fortune,
38 | ...
39 | """
40 | pose_up = JointPose(target_joints=[30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
41 | pose_down = JointPose(target_joints=[-30.0, 0.0, 0.0, 0.0, 0.0, 5.0])
42 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
43 |
44 | lm = self.createLimbMotion(ICUB_HEAD)
45 | lm.createJointsTrajectory(pose_up, duration=2.0)
46 | lm.createJointsTrajectory(pose_down, duration=2.0, timeout=1.0)
47 | lm.createJointsTrajectory(pose_home, duration=2.0)
48 |
49 | self.createCustomCall(target="speech.say", args=(hamlet,))
50 |
51 | class CustomSpeech(iCubFullbodyAction):
52 |
53 | def prepare(self):
54 | self.addStep(Step())
55 |
56 | action = CustomSpeech()
57 | icub = iCub()
58 | action_id = icub.addAction(action)
59 | icub.playAction(action_id)
--------------------------------------------------------------------------------
/pyicub/modules/faceLandmarks.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.core.ports import BufferedReadPort
30 |
31 | class faceLandmarksPyCtrl:
32 |
33 | def __init__(self):
34 | self.__landmarks__ = []
35 | self.__faces__ = 0
36 | self.__port_landmarks__ = BufferedReadPort("/faceLandmarksPyCtrl/landmarks:i", "/faceLandmarks/landmarks:o", callback=self.onRead)
37 | self.__port_faces__ = BufferedReadPort("/faceLandmarksPyCtrl/faces:i", "/faceLandmarks/faces:o", callback=self.onReadFaces)
38 |
39 | ## LANDMARKS
40 | def onRead(self, bottle):
41 | self.__landmarks__ = []
42 | for i in range(bottle.size()):
43 | self.__landmarks__.append(bottle.get(i).asList())
44 |
45 | def getLandmark(self, landmark_index, face_index = 0):
46 | if self.__landmarks__:
47 | x = self.__landmarks__[face_index].get(landmark_index).asList().get(0).asInt32()
48 | y = self.__landmarks__[face_index].get(landmark_index).asList().get(1).asInt32()
49 | return [x, y]
50 | else:
51 | return [None, None]
52 |
53 | def getCenterEyes(self, face_index = 0):
54 | [x, y] = self.getLandmark(27, face_index)
55 | return [x, y]
56 |
57 | ## FACES
58 | def onReadFaces(self, bottle):
59 | self.__faces__= bottle.get(0).asInt32()
60 |
61 | def getFaces(self):
62 | return self.__faces__
63 |
--------------------------------------------------------------------------------
/pyicub/proc/fsmizer.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import FSMsManager
30 | from pyicub.helper import iCub
31 |
32 | import argparse
33 |
34 | def main():
35 | parser = argparse.ArgumentParser(description="PyiCub FSMizer")
36 |
37 | subparsers = parser.add_subparsers(dest="command", help="Choose 'build' or 'run'.")
38 |
39 | build_parser = subparsers.add_parser("build", help="Build process")
40 | build_parser.add_argument("--module", nargs="+", required=True, help="Module name")
41 | build_parser.add_argument("--target", nargs="+", required=True, help="Target path")
42 |
43 | execute_parser = subparsers.add_parser("run", help="Running process")
44 | execute_parser.add_argument("--fsm", nargs="+", required=True, help="FSM (name) to process")
45 | execute_parser.add_argument("--source", nargs="+", required=True, help="Source path JSON repository")
46 |
47 | args = parser.parse_args()
48 |
49 | if args.command == "build":
50 | mgr = FSMsManager()
51 | mgr.importFSMsFromModule(args.module[0])
52 | mgr.exportFSMs(args.target[0])
53 | elif args.command == "run":
54 | #icub = iCub(action_repository_path=args.source[0])
55 | #for action in args.actions:
56 | # icub.playAction(action)
57 | pass
58 | else:
59 | print("Invalid command. Choose 'build' or 'run'.")
60 |
61 |
62 | if __name__ == "__main__":
63 | main()
--------------------------------------------------------------------------------
/pyicub/proc/actionizer.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.actions import ActionsManager
30 | from pyicub.helper import iCub
31 |
32 | import argparse
33 |
34 | def main():
35 | parser = argparse.ArgumentParser(description="PyiCub Actionizer")
36 |
37 | subparsers = parser.add_subparsers(dest="command", help="Choose 'build' or 'run'.")
38 |
39 | build_parser = subparsers.add_parser("build", help="Build process")
40 | build_parser.add_argument("--module", nargs="+", required=True, help="Module name")
41 | build_parser.add_argument("--target", nargs="+", required=True, help="Target path")
42 |
43 | execute_parser = subparsers.add_parser("run", help="Running process")
44 | execute_parser.add_argument("--actions", nargs="+", required=True, help="List of actions to process (action id)")
45 | execute_parser.add_argument("--source", nargs="+", required=True, help="Source path JSON repository")
46 |
47 | args = parser.parse_args()
48 |
49 | if args.command == "build":
50 | mgr = ActionsManager()
51 | mgr.importActionsFromModule(args.module[0])
52 | mgr.exportActions(args.target[0])
53 | elif args.command == "run":
54 | icub = iCub(action_repository_path=args.source[0])
55 | for action in args.actions:
56 | icub.playAction(action)
57 | else:
58 | print("Invalid command. Choose 'build' or 'run'.")
59 |
60 |
61 | if __name__ == "__main__":
62 | main()
--------------------------------------------------------------------------------
/examples/7_FSM/2.semaphore_subs/1.pub.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulServer
30 | from pyicub.fsm import FSM
31 |
32 | import time
33 |
34 | logger = FSM.getLogger()
35 |
36 | class Semaphore(FSM):
37 |
38 | def __init__(self):
39 | FSM.__init__(self, name="Semaphore")
40 | self.addState(name="RED", on_enter_callback=self.on_RED)
41 | self.addState(name="YELLOW", on_enter_callback=self.on_YELLOW)
42 | self.addState(name="GREEN", on_enter_callback=self.on_GREEN)
43 |
44 | self.addTransition(FSM.INIT_STATE, "RED")
45 | self.addTransition("RED", "GREEN")
46 | self.addTransition("GREEN", "YELLOW")
47 | self.addTransition("YELLOW", FSM.INIT_STATE)
48 |
49 | def on_RED(self, msg='default', wait_time=6):
50 | logger.info("RED STATE: Stop! Received msg: %s" % msg)
51 | time.sleep(wait_time)
52 |
53 | def on_YELLOW(self, msg='default', wait_time=1):
54 | logger.info("YELLOW STATE: Slow down! Received msg: %s" % msg)
55 | time.sleep(wait_time)
56 |
57 | def on_GREEN(self, msg='default', wait_time=1):
58 | logger.info("GREEN STATE: Go! Received msg: %s" % msg)
59 | time.sleep(wait_time)
60 |
61 | class Publisher(PyiCubRESTfulServer):
62 |
63 | def hello_world(self, name: str='you'):
64 | return "Hello world %s!" % name
65 |
66 | app = Publisher()
67 | fsm = Semaphore()
68 | app.setFSM(fsm)
69 |
70 | app.rest_manager.run_forever()
71 |
--------------------------------------------------------------------------------
/scripts/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | initialize_environment() {
6 | echo "Initializing environment..."
7 | source "${ROBOTOLOGY_SUPERBUILD_INSTALL_DIR}/share/robotology-superbuild/setup.sh"
8 | }
9 |
10 | wait_for_icub_host() {
11 | local timeout="${1:-60}"
12 | echo "Waiting for $ICUB_HOST to become reachable (timeout: ${timeout}s)..."
13 | local seconds_waited=0
14 |
15 | while ! ping -c 1 -W 1 "$ICUB_HOST" >/dev/null 2>&1; do
16 | printf "."
17 |
18 | if command -v play >/dev/null 2>&1; then
19 | play -n synth 0.1 sin 440 >/dev/null 2>&1
20 | else
21 | printf "\a"
22 | fi
23 | sleep 1;
24 |
25 |
26 | seconds_waited=$((seconds_waited + 1))
27 |
28 | if [ "$seconds_waited" -ge "$timeout" ]; then
29 | echo -e "\n$ICUB_HOST not reachable within timeout."
30 | return 1
31 | fi
32 | done
33 |
34 | echo -e "\n$ICUB_HOST is reachable."
35 |
36 | if command -v play >/dev/null 2>&1; then
37 | play -n synth 0.5 sin 880 >/dev/null 2>&1
38 | else
39 | printf "\a"
40 | fi
41 |
42 | return 0
43 | }
44 |
45 |
46 |
47 | start_yarpserver() {
48 | echo "Starting yarpserver..."
49 | YARP_FORWARD_LOG_ENABLE=0 yarpserver --write
50 | }
51 |
52 | start_yarpserver_detached() {
53 | echo "Starting yarpserver (detached)..."
54 | YARP_FORWARD_LOG_ENABLE=0 yarpserver --write &
55 | sleep 2
56 | }
57 |
58 | start_local_yarprun() {
59 | echo "Starting local yarprun..."
60 | yarprun --server /"$PYICUB_NODE" --log &
61 | sleep 2
62 | }
63 |
64 | start_icub_yarprun() {
65 | echo -e "\nStarting remote yarprun on $ICUB_HOST..."
66 | ssh icub@"$ICUB_HOST" \
67 | "nohup yarprun --server /$ICUB_NODE --log &" &
68 | sleep 2
69 | }
70 |
71 | cleanup_remote_processes() {
72 | echo "Cleaning up remote processes on $ICUB_HOST..."
73 | ssh icub@"$ICUB_HOST" \
74 | "killall -q -9 yarprun yarpdev || true"
75 | }
76 |
77 | ensure_ssh_key_installed() {
78 | echo "Checking SSH key access to $ICUB_HOST..."
79 |
80 | if ssh -o BatchMode=yes -o ConnectTimeout=5 icub@"$ICUB_HOST" 'exit'; then
81 | echo "SSH key already installed."
82 | return
83 | fi
84 |
85 | echo "SSH key not found. Attempting to copy SSH key to icub@$ICUB_HOST"
86 | if [ ! -f ~/.ssh/id_rsa.pub ]; then
87 | echo "No SSH key found. Generating one..."
88 | ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
89 | fi
90 |
91 | echo "You may be prompted for the icub user's password to copy the key."
92 | ssh-copy-id -o StrictHostKeyChecking=no icub@"$ICUB_HOST"
93 | }
94 |
95 | check_existing_yarpserver() {
96 | for i in {1..5}; do
97 | if yarp detect --write >/dev/null 2>&1; then
98 | echo "Existing yarpserver detected."
99 | return
100 | else
101 | echo "No yarpserver detected. Attempt $i of 5."
102 | sleep 2
103 | fi
104 | done
105 | echo "Error: No yarpserver detected after 5 attempts." >&2
106 | exit 1
107 | }
--------------------------------------------------------------------------------
/examples/7_FSM/4.icub_multiple/app.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2023, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, iCubFSM
30 | from pyicub.actions import iCubFullbodyAction
31 | from pyicub.fsm import FSM
32 | import os
33 |
34 |
35 | head_action = iCubFullbodyAction(JSON_file="actions/HeadAction.json")
36 | lookat_action = iCubFullbodyAction(JSON_file="actions/LookAtAction.json")
37 |
38 | class FSM_A(iCubFSM):
39 |
40 | def __init__(self):
41 | iCubFSM.__init__(self)
42 | lookat_state = self.addAction(lookat_action)
43 | self.addTransition(FSM.INIT_STATE, lookat_state)
44 | self.exportJSONFile("FSM_A.json")
45 | self.draw("FSM_A.png")
46 |
47 |
48 | class FSM_B(iCubFSM):
49 |
50 | def __init__(self):
51 | iCubFSM.__init__(self)
52 | head_state = self.addAction(head_action)
53 | lookat_state = self.addAction(lookat_action)
54 | self.addTransition(FSM.INIT_STATE, head_state)
55 | self.addTransition(head_state, lookat_state)
56 | self.addTransition(lookat_state, FSM.INIT_STATE)
57 | self.exportJSONFile("FSM_B.json")
58 | self.draw("FSM_B.png")
59 |
60 |
61 |
62 | class MultipleFSM(iCubRESTApp):
63 |
64 | def __init__(self, machine_id):
65 | self.FSM_A = FSM_A()
66 | self.FSM_B = FSM_B()
67 | iCubRESTApp.__init__(self, machine_id=machine_id)
68 |
69 | def configure(self, input_args):
70 | machine_id = int(input_args['machine_id'])
71 |
72 | if machine_id == 1:
73 | self.setFSM(self.FSM_A)
74 | elif machine_id == 2:
75 | self.setFSM(self.FSM_B)
76 |
77 | app = MultipleFSM(machine_id=[1,2])
78 | app.rest_manager.run_forever()
--------------------------------------------------------------------------------
/examples/PositionController/move_head.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | """
29 | move_head.py
30 | ============
31 |
32 | This script controls the head movement of the iCub humanoid robot. It demonstrates how to
33 | retrieve the position controller for the head, define joint poses, and execute basic head movements.
34 |
35 | Usage:
36 | ------
37 | Run this script to move the iCub's head to an "up" position and then return it to the "home" position.
38 |
39 |
40 | """
41 |
42 | from pyicub.helper import iCub, JointPose, ICUB_HEAD
43 |
44 |
45 | def move_head():
46 | """
47 | Moves the iCub's head to the "up" position and then back to the "home" position.
48 |
49 | Steps:
50 | ------
51 | 1. Move the head to the `up` position.
52 | 2. Move the head back to the `home` position.
53 |
54 | Example:
55 | --------
56 | >>> move_head()
57 |
58 | Notes:
59 | ------
60 | - The head's movement is managed by a position controller.
61 | - The function uses predefined `JointPose` objects to specify joint configurations.
62 | - This script is useful for verifying that the head position controller is functioning correctly.
63 | """
64 | # Create an instance of the iCub robot
65 | icub = iCub()
66 |
67 | # Retrieve the position controller for the iCub's head
68 | head_ctrl = icub.getPositionController(ICUB_HEAD)
69 |
70 | # Define the "up" pose for the head
71 | up = JointPose(target_joints=[20.0, 0.0, 0.0, 0.0, 0.0, 0.0])
72 |
73 | # Define the "home" pose for the head (neutral position)
74 | home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
75 |
76 | head_ctrl.move(up)
77 | head_ctrl.move(home)
78 |
79 | if __name__ == "__main__":
80 | move_head()
81 |
--------------------------------------------------------------------------------
/examples/4_Actions/10.inner_actions.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, JointPose, ICUB_HEAD, iCubFullbodyAction, iCubFullbodyStep
30 |
31 | import os
32 |
33 | class Step(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 |
37 | pose_up = JointPose(target_joints=[20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
38 | pose_down = JointPose(target_joints=[-20.0, 0.0, 0.0, 0.0, 0.0, 5.0])
39 | pose_home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 5.0])
40 |
41 | motion = self.createLimbMotion(ICUB_HEAD)
42 | motion.createJointsTrajectory(pose_up, duration=3.0)
43 | motion.createJointsTrajectory(pose_down, duration=3.0)
44 | motion.createJointsTrajectory(pose_home, duration=3.0)
45 |
46 | class HeadActionE(iCubFullbodyAction):
47 |
48 | def prepare(self):
49 | step = Step()
50 | self.addStep(step)
51 |
52 | class Step1(iCubFullbodyStep):
53 |
54 | def prepare(self):
55 | self.createCustomCall(target="gaze.lookAtAbsAngles", args=(0.0, 15.0, 0.0,))
56 | self.createCustomCall(target="emo.neutral")
57 |
58 | class Step2(iCubFullbodyStep):
59 |
60 | def prepare(self):
61 | self.createCustomCall(target="gaze.lookAtAbsAngles", args=(0.0, 0.0, 0.0,))
62 | self.createCustomCall(target="emo.smile")
63 |
64 | class CustomAction(iCubFullbodyAction):
65 |
66 | def prepare(self):
67 | self.addStep(Step1())
68 | self.addStep(Step2())
69 |
70 | action = HeadActionE()
71 | custom_action = CustomAction()
72 | action.addAction(custom_action)
73 |
74 | icub = iCub()
75 | action_id = icub.addAction(action)
76 | icub.playAction(action_id)
77 | icub.exportAction(action_id=action_id, path=os.path.join(os.getcwd(), 'json'))
78 |
--------------------------------------------------------------------------------
/pyicub/modules/camera.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import yarp
30 |
31 | class cameraPyCtrl:
32 |
33 | def __init__(self, robot, side="right", proxy_host=None):
34 | self.__portImg__ = yarp.BufferedPortImageRgb()
35 | self.__portImg__.open("/read/"+ side + "_image:o")
36 | self.__portCamera__ = []
37 | self._proxy_host_ = proxy_host
38 | if robot == "icubSim":
39 | self.__portCamera__ = "/" + robot + "/cam/" + side + "/rgbImage:o"
40 | elif robot == "icub":
41 | self.__portCamera__ = "/" + robot + "/camcalib/" + side + "/out"
42 | yarp.Network.connect(self.__portCamera__, self.__portImg__.getName())
43 |
44 | def getImgRes(self):
45 | if yarp.Network.isConnected(self.__portCamera__, self.__portImg__.getName()):
46 | receivedImage = self.__portImg__.read()
47 | if receivedImage:
48 | img = yarp.ImageRgb()
49 | img.copy(receivedImage)
50 | return [img.width(), img.height()]
51 | return False
52 |
53 | def getPort(self):
54 | portcam = yarp.Network.queryName(self.__portCamera__)
55 | if portcam:
56 | return portcam.getPort()
57 | else:
58 | return False
59 |
60 | def getHost(self):
61 | if self._proxy_host_:
62 | return self._proxy_host_
63 | portcam = yarp.Network.queryName(self.__portCamera__)
64 | if portcam:
65 | return portcam.getHost()
66 | else:
67 | return False
68 |
69 | def getURI(self):
70 | port = self.getPort()
71 | host = self.getHost()
72 | if port and host:
73 | return "http://" + str(host) + ":" + str(port) + "/?action"
74 | return None
75 |
76 | def __del__(self):
77 | yarp.Network.disconnect(self.__portCamera__, self.__portImg__.getName())
78 | self.__portImg__.interrupt()
79 | self.__portImg__.close()
--------------------------------------------------------------------------------
/pyicub/modules/llm.py:
--------------------------------------------------------------------------------
1 |
2 | # BSD 2-Clause License
3 | #
4 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
5 | # Istituto Italiano di Tecnologia, Genova
6 | #
7 | # All rights reserved.
8 | #
9 | # Redistribution and use in source and binary forms, with or without
10 | # modification, are permitted provided that the following conditions are met:
11 | #
12 | # 1. Redistributions of source code must retain the above copyright notice, this
13 | # list of conditions and the following disclaimer.
14 | #
15 | # 2. Redistributions in binary form must reproduce the above copyright notice,
16 | # this list of conditions and the following disclaimer in the documentation
17 | # and/or other materials provided with the distribution.
18 | #
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 |
31 | import yarp
32 | from pyicub.core.rpc import RpcClient
33 |
34 |
35 | class iLLM:
36 | """
37 | General interface to any YARP-based Large Language Model module.
38 | """
39 |
40 | def __init__(self, rpc_port_name="/LLM/rpc:i"):
41 | self.__rpcPort__ = RpcClient(rpc_port_name)
42 |
43 | def isValid(self):
44 | return self.__rpcPort__.connection_result
45 |
46 | def _send(self, command: str):
47 | btl = yarp.Bottle()
48 | btl.fromString(command)
49 | response = self.__rpcPort__.execute(btl)
50 | return response.toString()
51 |
52 | def status(self):
53 | return self._send("status")
54 |
55 | def query(self, text: str):
56 | return self._send(f'query {text}')
57 |
58 | def set_system_prompt(self, prompt: str):
59 | return self._send(f'set_system_prompt {prompt}')
60 |
61 | def create_session(self, session_id: str):
62 | return self._send(f'create_session {session_id}')
63 |
64 | def switch_session(self, session_id: str):
65 | return self._send(f'switch_session {session_id}')
66 |
67 | def reset_session(self, session_id: str):
68 | return self._send(f'reset_session {session_id}')
69 |
70 | def delete_session(self, session_id: str):
71 | return self._send(f'delete_session {session_id}')
72 |
73 | def list_sessions(self):
74 | return self._send('list_sessions')
75 |
76 | def set_model(self, model_name: str):
77 | return self._send(f'set_model {model_name}')
78 |
79 | def quit(self):
80 | return self._send('quit')
81 |
82 |
83 |
84 | class iGPT(iLLM):
85 | """
86 | Specialized interface for the GPT YARP module.
87 | Uses /GPT/rpc:i as default port.
88 | """
89 |
90 | def __init__(self):
91 | super().__init__(rpc_port_name="/GPT/rpc:i")
--------------------------------------------------------------------------------
/examples/7_FSM/5.icub_subs/1.pub.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import iCubRESTApp, iCubFSM
30 | from pyicub.helper import iCubFullbodyStep, iCubFullbodyAction
31 |
32 |
33 | class LookUp(iCubFullbodyStep):
34 |
35 | def prepare(self):
36 | g1 = self.createGazeMotion("lookAtFixationPoint")
37 | g1.addCheckpoint([-1.0, -0.5, 1.0])
38 |
39 | class LookDown(iCubFullbodyStep):
40 |
41 | def prepare(self):
42 | g1 = self.createGazeMotion("lookAtFixationPoint")
43 | g1.addCheckpoint([-1.0, 0.2, 0.1])
44 |
45 | class LookHome(iCubFullbodyStep):
46 |
47 | def prepare(self):
48 | g2 = self.createGazeMotion("lookAtAbsAngles")
49 | g2.addCheckpoint([0.0, 0.0, 0.0, True, 1.5])
50 |
51 | class LookUpAction(iCubFullbodyAction):
52 |
53 | def prepare(self):
54 | self.addStep(LookUp())
55 |
56 | class LookDownAction(iCubFullbodyAction):
57 |
58 | def prepare(self):
59 | self.addStep(LookDown())
60 |
61 | class LookHomeAction(iCubFullbodyAction):
62 | def prepare(self):
63 | self.addStep(LookHome())
64 |
65 |
66 |
67 | action_up = LookUpAction()
68 | action_down = LookDownAction()
69 | action_home = LookHomeAction()
70 |
71 | fsm = iCubFSM()
72 | lookup_state = fsm.addAction(action_up)
73 | lookdown_state = fsm.addAction(action_down)
74 | lookhome_state = fsm.addAction(action_home)
75 |
76 | fsm.addTransition(iCubFSM.INIT_STATE, lookup_state)
77 | fsm.addTransition(lookup_state, lookdown_state)
78 | fsm.addTransition(lookdown_state, lookhome_state)
79 | fsm.addTransition(lookhome_state, iCubFSM.INIT_STATE)
80 |
81 | fsm.draw('diagram.png')
82 | fsm.exportJSONFile('fsm.json')
83 |
84 |
85 | class Publisher(iCubRESTApp):
86 |
87 | def __init__(self):
88 | self.myFSM = iCubFSM(JSON_file="fsm.json")
89 | iCubRESTApp.__init__(self)
90 |
91 | def configure(self, input_args):
92 | self.setFSM(self.myFSM)
93 |
94 | app = Publisher()
95 | app.rest_manager.run_forever()
96 |
--------------------------------------------------------------------------------
/examples/GazeController/lookat.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | """
30 | lookat.py
31 | ===========
32 |
33 | This script controls the gaze movement of the iCub humanoid robot. It demonstrates
34 | how to direct the robot’s gaze to a specific 3D point and then reset its gaze
35 | to an absolute angle.
36 |
37 | Usage:
38 | ------
39 | Run this script to move the iCub's gaze to a fixation point and then reset it to a neutral position.
40 |
41 | """
42 |
43 | from pyicub.helper import iCub
44 |
45 | # Create an instance of the iCub robot
46 | icub = iCub()
47 |
48 | def look_at_fixation_point(x: float = -1.0, y: float = -0.5, z: float = 1.0):
49 | """
50 | Directs the iCub’s gaze to a specific 3D fixation point in space.
51 |
52 | Parameters
53 | ----------
54 | x : float, optional
55 | The x-coordinate of the fixation point (default: -1.0).
56 |
57 | y : float, optional
58 | The y-coordinate of the fixation point (default: -0.5).
59 |
60 | z : float, optional
61 | The z-coordinate of the fixation point (default: 1.0).
62 |
63 | Example
64 | -------
65 | >>> look_at_fixation_point(-1.0, -0.5, 1.0)
66 |
67 | Notes
68 | -----
69 | - The fixation point is specified in 3D coordinates.
70 | - This function is useful for directing the robot’s attention to a specific location.
71 | """
72 | icub.gaze.lookAtFixationPoint(x, y, z)
73 |
74 | def reset_gaze_to_neutral():
75 | """
76 | Resets the iCub's gaze to the absolute neutral angles.
77 |
78 | Example
79 | -------
80 | >>> reset_gaze_to_neutral()
81 |
82 | Notes
83 | -----
84 | - The gaze is reset by setting the azimuth (`azi`), elevation (`ele`),
85 | and vergence (`ver`) angles to zero.
86 | - This function is useful for returning the gaze to a predefined reference position.
87 | """
88 | icub.gaze.lookAtAbsAngles(azi=0.0, ele=0.0, ver=0.0)
89 |
90 | if __name__ == "__main__":
91 | look_at_fixation_point()
92 | reset_gaze_to_neutral()
93 |
94 |
--------------------------------------------------------------------------------
/examples/4_Actions/4.complete_action.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.helper import iCub, JointPose, LimbMotion, iCubFullbodyAction, iCubFullbodyStep, ICUB_RIGHTARM_FULL, ICUB_LEFTARM_FULL
30 |
31 | import os
32 |
33 | arm_down = JointPose(target_joints=[0.0, 15.0, 0.0, 25.0, 0.0, 0.0, 0.0, 60.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
34 | arm_up = JointPose(target_joints=[-90.0, 20.0, 10.0, 90.0, 0.0, 0.0, 0.0, 60.0, 20.0, 20.0, 20.0, 10.0, 10.0, 10.0, 10.0, 10.0])
35 |
36 | right_arm_motion = LimbMotion(ICUB_RIGHTARM_FULL)
37 | right_arm_motion.createJointsTrajectory(arm_up)
38 | right_arm_motion.createJointsTrajectory(arm_down)
39 |
40 | left_arm_motion = LimbMotion(ICUB_LEFTARM_FULL)
41 | #left_arm_motion.createJointsTrajectory(arm_up, duration=1.0)
42 | #left_arm_motion.createJointsTrajectory(arm_down, duration=1.0)
43 | left_arm_motion.createJointsTrajectory(arm_up)
44 | left_arm_motion.createJointsTrajectory(arm_down)
45 |
46 | class Step1(iCubFullbodyStep):
47 |
48 | def prepare(self):
49 | self.createCustomCall(target="gaze.lookAtAbsAngles", args=(0.0, 15.0, 0.0,))
50 | self.createCustomCall(target="emo.neutral")
51 |
52 | class Step2(iCubFullbodyStep):
53 |
54 | def prepare(self):
55 | self.setLimbMotion(left_arm_motion)
56 |
57 | class Step3(iCubFullbodyStep):
58 |
59 | def prepare(self):
60 | g = self.createGazeMotion(lookat_method="lookAtAbsAngles")
61 | g.addCheckpoint([20.0, 0.0, 0.0])
62 | g.addCheckpoint([-20.0, 0.0, 0.0])
63 | g.addCheckpoint([0.0, 0.0, 0.0])
64 |
65 | self.setLimbMotion(right_arm_motion)
66 | self.setLimbMotion(left_arm_motion)
67 | self.createCustomCall(target="emo.smile")
68 |
69 | class CompleteAction(iCubFullbodyAction):
70 |
71 | def prepare(self):
72 | self.addStep(Step1(), wait_for_completed=False)
73 | self.addStep(Step2())
74 | self.addStep(Step3(offset_ms=500))
75 |
76 | action = CompleteAction()
77 | icub = iCub()
78 | action_id = icub.addAction(action)
79 | icub.playAction(action_id)
80 | icub.exportAction(action_id=action_id, path=os.path.join(os.getcwd(), 'json'))
81 |
82 |
--------------------------------------------------------------------------------
/docker/compose.yaml:
--------------------------------------------------------------------------------
1 | x-pyicub-common: &pyicub-common
2 | image: ${PYICUB_IMAGE_NAME:?error}
3 | stdin_open: true
4 | tty: true
5 | network_mode: host
6 | privileged: true
7 |
8 |
9 | services:
10 |
11 | pyicub-yarpserver:
12 | <<: *pyicub-common
13 | container_name: pyicub-yarpserver
14 |
15 | command: ["/bin/bash", "-c", "yarpserver --write"]
16 |
17 | restart: unless-stopped
18 |
19 | healthcheck:
20 | test: ["CMD", "/bin/bash", "-c", "yarp detect"]
21 | interval: 10s
22 | timeout: 5s
23 | retries: 6
24 | start_period: 1s
25 |
26 | profiles:
27 | - backend
28 | - frontend
29 |
30 | pyicub-backend:
31 | <<: *pyicub-common
32 | container_name: pyicub-backend
33 |
34 | build:
35 | context: ..
36 | dockerfile: docker/Dockerfile.pyicub
37 | args:
38 | DOCKER_SRC: ${ROBOTOLOGY_IMAGE_NAME}
39 | PYICUB_VERSION: ${PYICUB_VERSION:-master}
40 | PYICUB_APPS_VERSION: ${PYICUB_APPS_VERSION:-master}
41 | WORKDIR: ${WORKDIR:-/usr/local/src/robot}
42 |
43 | runtime: ${DOCKER_RUNTIME:-runc}
44 |
45 | env_file:
46 | - pyicub.env
47 |
48 | environment:
49 | - DISPLAY=${DISPLAY:-:0}
50 | - PULSE_SERVER=unix:${XDG_RUNTIME_DIR:?error}/pulse/native
51 | - PULSE_COOKIE=/run/pulse/cookie
52 | - XDG_RUNTIME_DIR=/tmp/runtime-root
53 | - XDG_DATA_DIRS=${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
54 | - QT_X11_NO_MITSHM=1
55 | - NO_AT_BRIDGE=1
56 | - NVIDIA_VISIBLE_DEVICES=${GPU_DEVICES:-none}
57 | - NVIDIA_DRIVER_CAPABILITIES=all
58 |
59 | command: ["/bin/bash", "-c", "bash ${WORKDIR:?error}/pyicub/scripts/start.sh"]
60 |
61 | profiles:
62 | - backend
63 |
64 | healthcheck:
65 | test: ["CMD", "/bin/bash", "-c", "yarp ping /${PYICUB_NODE:?error}"]
66 | interval: 1m30s
67 | timeout: 30s
68 | retries: 5
69 | start_period: 30s
70 |
71 | depends_on:
72 | pyicub-yarpserver:
73 | condition: service_healthy
74 |
75 | volumes:
76 | - /tmp/.X11-unix:/tmp/.X11-unix
77 | - ${HOME}/.config/pulse/cookie:/run/pulse/cookie
78 | - ${XDG_RUNTIME_DIR:?error}/pulse:${XDG_RUNTIME_DIR:?error}/pulse
79 |
80 | pyicub.frontend:
81 | image: ${PYICUB_FRONTEND_IMAGE_NAME:?error}
82 | container_name: pyicub-frontend
83 |
84 | build:
85 | context: .
86 | dockerfile: Dockerfile.pyicub-frontend
87 | args:
88 | - PYICUB_FRONTEND_VERSION=${PYICUB_FRONTEND_VERSION:?error}
89 |
90 | environment:
91 | - SSH_AUTH_SOCK=/ssh-agent
92 |
93 | network_mode: host
94 |
95 | volumes:
96 | - pyicub-frontend-workspace:${WORKDIR:?error}/pyicub-frontend
97 | - ${HOME}/.gitconfig:/root/.gitconfig:ro
98 | - ${HOME}/.ssh:/root/.ssh:ro
99 | - ${SSH_AUTH_SOCK:-/dev/null}:/ssh-agent
100 |
101 | profiles:
102 | - frontend
103 |
104 | depends_on:
105 | pyicub-yarpserver:
106 | condition: service_healthy
107 | pyicub-backend:
108 | condition: service_healthy
109 |
110 | pyicub.test:
111 | <<: *pyicub-common
112 | container_name: pyicub-test
113 |
114 | command: ["/bin/bash", "-c", "bash ${WORKDIR:?error}/pyicub/scripts/tests.sh"]
115 |
116 | env_file:
117 | - pyicub.env
118 |
119 | environment:
120 | - DISPLAY=:99
121 |
122 | volumes:
123 | - ./shared:/shared
124 |
125 | profiles:
126 | - test
127 |
128 | volumes:
129 | pyicub-frontend-workspace:
130 | name: pyicub-frontend-workspace
131 |
--------------------------------------------------------------------------------
/.github/workflows/readTheDocs.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deploy Docs to pyicub-doc
2 |
3 | on:
4 | push:
5 | branches:
6 | - master # Trigger on pushes to the main branch of your pyicub code repository
7 |
8 | jobs:
9 | build-and-deploy:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout pyicub repository (the code)
14 | uses: actions/checkout@v4
15 | with:
16 | path: pyicub-code-repo # Clones your pyicub code repo into this directory
17 | fetch-depth: 0 # Needed for Git history if you use tags etc.
18 |
19 | - name: Checkout pyicub-doc repository (the docs)
20 | uses: actions/checkout@v4
21 | with:
22 | # Replace 'sS4HRITECH/pyicub-doc' with your actual organization/username if different
23 | repository: S4HRITECH/pyicub-doc
24 | path: pyicub-doc-repo # Clones your pyicub-doc repo into this directory
25 | token: ${{ secrets.DOCS_REPO_PAT }} # Uses the PAT for write access
26 |
27 | - name: Set up Python
28 | uses: actions/setup-python@v5
29 | with:
30 | python-version: '3.x' # Use a Python version compatible with your projects
31 |
32 | - name: Install documentation build dependencies in pyicub-doc
33 | run: |
34 | # Navigate to the pyicub-doc repository checkout
35 | cd pyicub-doc-repo
36 | # Install Sphinx and theme from pyicub-doc's requirements.txt
37 | pip install -r requirements.txt
38 | # - name: Install pyicub project dependencies (if needed for sphinx-apidoc)
39 | # # This step is crucial if your pyicub code imports libraries that sphinx-apidoc needs
40 | # # to successfully parse your code's docstrings and structure.
41 | # # ADJUST THIS SECTION based on your pyicub project's actual dependencies.
42 | # run: |
43 | # cd pyicub-code-repo
44 | # # Example: if your pyicub is a pip installable package
45 | # # pip install -e .
46 | # # Example: if your pyicub has a requirements.txt
47 | # pip install -r requirements.txt
48 | # # Example: if it just needs numpy
49 | # # pip install numpy
50 | # echo "No specific pyicub dependencies installed for sphinx-apidoc. Remove this echo if you add actual install commands."
51 |
52 | - name: Generate API reStructuredText files using sphinx-apidoc
53 | run: |
54 | # Navigate to the pyicub-doc repository's source directory
55 | cd pyicub-doc-repo/source
56 | # Run sphinx-apidoc, pointing to the pyicub-code-repo/pyicub package
57 | # The path to pyicub is relative from pyicub-doc-repo/source
58 | # Assuming: pyicub-doc-repo/source/../pyicub-code-repo/pyicub
59 | # This will create .rst files in pyicub-doc-repo/source/api/
60 | sphinx-apidoc -o api ../../pyicub-code-repo/pyicub --force
61 | - name: Build full HTML documentation in pyicub-doc
62 | run: |
63 | # Navigate back to the root of the pyicub-doc repository checkout
64 | cd pyicub-doc-repo
65 | # Run make html from the pyicub-doc root
66 | make html
67 | - name: Commit and Push updated docs to pyicub-doc repository
68 | working-directory: pyicub-doc-repo # Perform git operations from within pyicub-doc-repo
69 | run: |
70 | git config user.name "GitHub Actions"
71 | git config user.email "actions@github.com"
72 | git add . # Add all changes (new .rst files in source/api, updated HTML files in build/html)
73 | # Check if there are any changes before committing to avoid empty commits
74 | git diff-index --quiet HEAD || git commit -m "Automated API docs update from pyicub commit ${{ github.sha }}"
75 | git push origin master # IMPORTANT: Replace 'master' with your pyicub-doc's default branch if different
76 | env:
77 | GITHUB_TOKEN: ${{ secrets.DOCS_REPO_PAT }} # Use the PAT for authentication
78 |
--------------------------------------------------------------------------------
/pyicub/modules/emotions.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import yarp
30 | from pyicub.core.rpc import RpcClient
31 | from pyicub.core.ports import BufferedWritePort
32 |
33 | class emotionsPyCtrl:
34 |
35 | def __init__(self, robot):
36 | self.__port__ = BufferedWritePort("/pyicub/emotions:o", "/%s/face/emotions/in" % robot)
37 |
38 | def __emoCmd__(self, part, emo):
39 | return self.__port__.write("set %s %s" % (part, emo))
40 |
41 | def smile(self):
42 | self.__emoCmd__("all", "hap")
43 |
44 | def eb_smile(self):
45 | self.__emoCmd__("leb", "hap")
46 | self.__emoCmd__("reb", "hap")
47 |
48 | def eb_surprised(self):
49 | self.__emoCmd__("leb", "sur")
50 | self.__emoCmd__("reb", "sur")
51 |
52 | def surprised(self):
53 | self.__emoCmd__("mou", "sur")
54 | self.__emoCmd__("leb", "sur")
55 | self.__emoCmd__("reb", "sur")
56 |
57 | def neutral(self):
58 | self.__emoCmd__("mou", "neu")
59 | self.__emoCmd__("leb", "neu")
60 | self.__emoCmd__("reb", "neu")
61 |
62 | def sad(self):
63 | self.__emoCmd__("mou", "sad")
64 | self.__emoCmd__("leb", "sad")
65 | self.__emoCmd__("reb", "sad")
66 |
67 | def openingEyes(self):
68 | self.__emoCmd__("eli", "hap")
69 |
70 | def closingEyes(self):
71 | self.__emoCmd__("eli", "sad")
72 |
73 | def cun(self):
74 | self.__emoCmd__("leb", "cun")
75 | self.__emoCmd__("reb", "cun")
76 |
77 | def angry(self):
78 | self.__emoCmd__("all", "ang")
79 |
80 | def evil(self):
81 | self.__emoCmd__("all", "evil")
82 |
83 | def sendCmd(self, part, emo):
84 | return self.__emoCmd__(part, emo)
85 |
86 | #set col set the color of the led
87 | # !! available only for rfe board !!
88 | # the available colors are: black, white, red, lime, blue, yellow, cyan, magenta, silver, gray, maroon, olive, green, purple, teal, navy
89 | def setColor(self, color):
90 | return self.__emoCmd__("col", color)
91 |
92 | #set brig set the brightness of the leds
93 | # !! available only for rfe board !!
94 | # the brightness is defined by an integer from 0 to 5, where 0 means led off
95 | def setBrightness(self, brightness):
96 | return self.__emoCmd__("brig", brightness)
97 |
--------------------------------------------------------------------------------
/examples/PositionController/move_part.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | """
31 | move_part.py
32 | ============
33 |
34 | This script controls the movement of the iCub humanoid robot's head and eyes.
35 | It demonstrates how to define motion trajectories using multiple joint poses and execute
36 | them sequentially.
37 |
38 | Usage:
39 | ------
40 | Run this script to move the iCub's neck through a series of predefined positions and
41 | coordinate the movement of its eyes.
42 |
43 |
44 | """
45 |
46 | from pyicub.helper import iCub, JointPose, LimbMotion, ICUB_NECK, ICUB_EYES
47 |
48 | def move_neck_and_eyes():
49 | """
50 | Moves the iCub's neck and eyes through predefined motion sequences.
51 |
52 | Steps
53 | -----
54 | 1. Moves the neck through a sequence: "Up" -> "Down" -> "Home".
55 | 2. Moves the eyes through a sequence: "Left" -> "Right" -> "Home".
56 |
57 | Example
58 | -------
59 | >>> move_neck_and_eyes()
60 |
61 | Notes
62 | -----
63 | - The function sequentially executes predefined motion trajectories.
64 | - `LimbMotion` objects store multiple poses for smooth transitions.
65 | - The iCub executes head and eye movements independently.
66 | """
67 | # Create an instance of the iCub robot
68 | icub = iCub()
69 |
70 | # Define neck poses (Up, Down, Home)
71 | neck_up = JointPose(target_joints=[20.0, 0.0, 0.0])
72 | neck_down = JointPose(target_joints=[-20.0, 0.0, 0.0])
73 | neck_home = JointPose(target_joints=[0.0, 0.0, 0.0])
74 |
75 | # Create a motion trajectory for the neck
76 | neck_motion = LimbMotion(ICUB_NECK)
77 | neck_motion.createJointsTrajectory(neck_up)
78 | neck_motion.createJointsTrajectory(neck_down)
79 | neck_motion.createJointsTrajectory(neck_home)
80 |
81 | # Define eye movements
82 | eyes_left = JointPose(target_joints=[0.0, 20.0, 5.0])
83 | eyes_right = JointPose(target_joints=[0.0, -20.0, 5.0])
84 | eyes_home = JointPose(target_joints=[0.0, 0.0, 0.0])
85 |
86 | # Create a motion trajectory for the eyes
87 | eyes_motion = LimbMotion(ICUB_EYES)
88 | eyes_motion.createJointsTrajectory(eyes_left)
89 | eyes_motion.createJointsTrajectory(eyes_right)
90 | eyes_motion.createJointsTrajectory(eyes_home)
91 |
92 | # Execute head and eye movement sequences
93 | icub.movePart(neck_motion)
94 | icub.movePart(neck_motion)
95 |
96 | if __name__ == "__main__":
97 | move_neck_and_eyes()
98 |
99 |
--------------------------------------------------------------------------------
/examples/PositionController/move_head_timeout.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2024, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | """
31 | move_head_timeout.py
32 | ====================
33 |
34 | This script controls the head movement of the iCub humanoid robot with a timeout feature.
35 | It demonstrates how to retrieve the position controller for the head, define joint poses,
36 | and execute timed head movements with a specified timeout.
37 |
38 | Usage:
39 | ------
40 | Run this script to move the iCub's head to an "up" position and then return it to the "home" position
41 | within a specific timeout period.
42 |
43 |
44 | """
45 |
46 | from pyicub.helper import iCub, JointPose, ICUB_HEAD
47 |
48 | # Create an instance of the iCub robot
49 | icub = iCub()
50 |
51 | # Retrieve the position controller for the iCub's head
52 | head_ctrl = icub.getPositionController(ICUB_HEAD)
53 |
54 | # Define the "up" pose for the head
55 | up = JointPose(target_joints=[20.0, 0.0, 0.0, 0.0, 0.0, 0.0])
56 |
57 | # Define the "home" pose for the head (neutral position)
58 | home = JointPose(target_joints=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
59 |
60 | def move_head_with_timeout(req_time: float = 1.0, timeout: float = 0.5):
61 | """
62 | Moves the iCub's head to the "up" position and then back to the "home" position within a specified timeout.
63 |
64 | Parameters
65 | ----------
66 | req_time : float, optional
67 | The requested time (in seconds) for the motion to complete. Default is 1.0 seconds.
68 |
69 | timeout : float, optional
70 | The maximum time allowed (in seconds) for the motion to complete before timeout occurs. Default is 0.5 seconds.
71 |
72 | Steps
73 | -----
74 | 1. Move the head to the `up` position within the requested time.
75 | 2. If the movement does not complete within the timeout period, it stops.
76 | 3. Move the head back to the `home` position with the same timeout settings.
77 |
78 | Example
79 | -------
80 | >>> move_head_with_timeout(req_time=1.0, timeout=0.5)
81 |
82 | Notes
83 | -----
84 | - The timeout ensures that the robot does not get stuck in an unfinished movement.
85 | - The `req_time` is the expected duration for the motion to complete.
86 | - If `timeout` is exceeded, the motion is forcefully stopped.
87 | """
88 | head_ctrl.move(up, req_time=req_time, timeout=timeout)
89 | head_ctrl.move(home, req_time=req_time, timeout=timeout)
90 |
91 | if __name__ == "__main__":
92 | move_head_with_timeout()
93 |
94 |
--------------------------------------------------------------------------------
/examples/7_FSM/5.icub_subs/fsm.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "iCubFSM",
3 | "states": [
4 | {
5 | "name": "LookUpAction",
6 | "description": null
7 | },
8 | {
9 | "name": "LookDownAction",
10 | "description": null
11 | },
12 | {
13 | "name": "LookHomeAction",
14 | "description": null
15 | }
16 | ],
17 | "transitions": [
18 | {
19 | "trigger": "init>LookUpAction",
20 | "source": "init",
21 | "dest": "LookUpAction"
22 | },
23 | {
24 | "trigger": "LookUpAction>LookDownAction",
25 | "source": "LookUpAction",
26 | "dest": "LookDownAction"
27 | },
28 | {
29 | "trigger": "LookDownAction>LookHomeAction",
30 | "source": "LookDownAction",
31 | "dest": "LookHomeAction"
32 | },
33 | {
34 | "trigger": "LookHomeAction>init",
35 | "source": "LookHomeAction",
36 | "dest": "init"
37 | }
38 | ],
39 | "initial_state": "init",
40 | "actions": {
41 | "LookUpAction": {
42 | "steps": [
43 | {
44 | "name": "LookUp",
45 | "limb_motions": {},
46 | "gaze_motion": {
47 | "checkpoints": [
48 | [
49 | -1.0,
50 | -0.5,
51 | 1.0
52 | ]
53 | ],
54 | "lookat_method": "lookAtFixationPoint"
55 | },
56 | "custom_calls": [],
57 | "offset_ms": null
58 | }
59 | ],
60 | "wait_for_steps": [
61 | true
62 | ],
63 | "name": "LookUpAction",
64 | "description": null,
65 | "offset_ms": null
66 | },
67 | "LookDownAction": {
68 | "steps": [
69 | {
70 | "name": "LookDown",
71 | "limb_motions": {},
72 | "gaze_motion": {
73 | "checkpoints": [
74 | [
75 | -1.0,
76 | 0.2,
77 | 0.1
78 | ]
79 | ],
80 | "lookat_method": "lookAtFixationPoint"
81 | },
82 | "custom_calls": [],
83 | "offset_ms": null
84 | }
85 | ],
86 | "wait_for_steps": [
87 | true
88 | ],
89 | "name": "LookDownAction",
90 | "description": null,
91 | "offset_ms": null
92 | },
93 | "LookHomeAction": {
94 | "steps": [
95 | {
96 | "name": "LookHome",
97 | "limb_motions": {},
98 | "gaze_motion": {
99 | "checkpoints": [
100 | [
101 | 0.0,
102 | 0.0,
103 | 0.0,
104 | true,
105 | 1.5
106 | ]
107 | ],
108 | "lookat_method": "lookAtAbsAngles"
109 | },
110 | "custom_calls": [],
111 | "offset_ms": null
112 | }
113 | ],
114 | "wait_for_steps": [
115 | true
116 | ],
117 | "name": "LookHomeAction",
118 | "description": null,
119 | "offset_ms": null
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/examples/7_FSM/6.icub_rest_import/fsm.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "iCubFSM",
3 | "states": [
4 | {
5 | "name": "LookUpAction",
6 | "description": null
7 | },
8 | {
9 | "name": "LookDownAction",
10 | "description": null
11 | },
12 | {
13 | "name": "LookHomeAction",
14 | "description": null
15 | }
16 | ],
17 | "transitions": [
18 | {
19 | "trigger": "init>LookUpAction",
20 | "source": "init",
21 | "dest": "LookUpAction"
22 | },
23 | {
24 | "trigger": "LookUpAction>LookDownAction",
25 | "source": "LookUpAction",
26 | "dest": "LookDownAction"
27 | },
28 | {
29 | "trigger": "LookDownAction>LookHomeAction",
30 | "source": "LookDownAction",
31 | "dest": "LookHomeAction"
32 | },
33 | {
34 | "trigger": "LookHomeAction>init",
35 | "source": "LookHomeAction",
36 | "dest": "init"
37 | }
38 | ],
39 | "initial_state": "init",
40 | "actions": {
41 | "LookUpAction": {
42 | "steps": [
43 | {
44 | "name": "LookUp",
45 | "limb_motions": {},
46 | "gaze_motion": {
47 | "checkpoints": [
48 | [
49 | -1.0,
50 | -0.5,
51 | 1.0
52 | ]
53 | ],
54 | "lookat_method": "lookAtFixationPoint"
55 | },
56 | "custom_calls": [],
57 | "offset_ms": null
58 | }
59 | ],
60 | "wait_for_steps": [
61 | true
62 | ],
63 | "name": "LookUpAction",
64 | "description": null,
65 | "offset_ms": null
66 | },
67 | "LookDownAction": {
68 | "steps": [
69 | {
70 | "name": "LookDown",
71 | "limb_motions": {},
72 | "gaze_motion": {
73 | "checkpoints": [
74 | [
75 | -1.0,
76 | 0.2,
77 | 0.1
78 | ]
79 | ],
80 | "lookat_method": "lookAtFixationPoint"
81 | },
82 | "custom_calls": [],
83 | "offset_ms": null
84 | }
85 | ],
86 | "wait_for_steps": [
87 | true
88 | ],
89 | "name": "LookDownAction",
90 | "description": null,
91 | "offset_ms": null
92 | },
93 | "LookHomeAction": {
94 | "steps": [
95 | {
96 | "name": "LookHome",
97 | "limb_motions": {},
98 | "gaze_motion": {
99 | "checkpoints": [
100 | [
101 | 0.0,
102 | 0.0,
103 | 0.0,
104 | true,
105 | 1.5
106 | ]
107 | ],
108 | "lookat_method": "lookAtAbsAngles"
109 | },
110 | "custom_calls": [],
111 | "offset_ms": null
112 | }
113 | ],
114 | "wait_for_steps": [
115 | true
116 | ],
117 | "name": "LookHomeAction",
118 | "description": null,
119 | "offset_ms": null
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/examples/8_Attention/REST/client.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from pyicub.rest import PyiCubRESTfulClient
30 |
31 | # Define the name of the robot and application as registered in the iCub server
32 | robot_name = 'icubSim'
33 | app_name = 'helper'
34 |
35 | # Initialize the RESTful client to communicate with iCub on localhost and port 9001
36 | client = PyiCubRESTfulClient(host='localhost', port=9001)
37 |
38 | # Parameters for workspace observation (e.g., a table)
39 | Table_center = (-1.0, 0.0, 0.0) # 3D center of the workspace
40 | Table_width = 0.6 # Width of the workspace area
41 | Table_depth = 0.4 # Depth of the workspace area
42 | num_points = 4 # Number of fixation points
43 | fixation_time = 1.0 # Time in seconds to fixate on each point
44 | lookat_point_timeout = 5.0 # Timeout in seconds for each lookat request
45 |
46 | # Parameters for scene observation (area above the workspace)
47 | Area_center = (-1.0, 0.0, 0.5) # 3D center of the scene area
48 | Area_width = 1.0 # Width of the scene area
49 | Area_height = 0.5 # Height of the scene area
50 |
51 | # Wait for user input to start the first request
52 | input("PRESS ENTER to start the request")
53 |
54 | # Send synchronous request to observe the workspace
55 | client.run_target(
56 | robot_name=robot_name,
57 | app_name=app_name,
58 | target_name='attention.observe_workspace',
59 | center=Table_center,
60 | width=Table_width,
61 | depth=Table_depth,
62 | num_points=num_points,
63 | fixation_time=fixation_time,
64 | lookat_point_timeout=lookat_point_timeout,
65 | waitMotionDone=True # Wait for the motion to complete before proceeding
66 | )
67 |
68 | # Wait for user input before starting the next observation
69 | input("PRESS ENTER to start the request")
70 |
71 | # Send asynchronous request to observe the scene (this won't block)
72 | req_id = client.run_target_async(
73 | robot_name=robot_name,
74 | app_name=app_name,
75 | target_name='attention.observe_scene',
76 | center=Area_center,
77 | width=Area_width,
78 | height=Area_height,
79 | num_points=num_points,
80 | fixation_time=fixation_time,
81 | lookat_point_timeout=lookat_point_timeout,
82 | waitMotionDone=True # Still ensures that the internal motion finishes
83 | )
84 |
85 | # Wait until the asynchronous request completes
86 | print("WAITING FOR THE REQUEST TO FINISH...")
87 | client.wait_until_completed(req_id)
88 |
--------------------------------------------------------------------------------
/examples/8_Attention/observe.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2025, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | """
30 | observe.py
31 | ============
32 |
33 | This script controls an iCub robot to systematically observe and scan two defined regions:
34 | 1. Workspace area (e.g., a table surface).
35 | 2. General scene area (e.g., space in front of the robot).
36 |
37 | Usage:
38 | ------
39 | python observe.py
40 | """
41 |
42 | # Import the helper class to interface with iCub robot
43 | from pyicub.helper import iCub
44 |
45 | # Main function to control robot observation
46 | def observe():
47 | # Initialize an instance of the iCub robot
48 | icub = iCub()
49 |
50 | # Define parameters for observing the workspace (e.g., table surface)
51 | Table_center = (-1.0, 0.0, 0.0) # Coordinates for the center of the workspace
52 | Table_width = 0.6 # Width of the workspace area
53 | Table_depth = 0.4 # Depth of the workspace area
54 |
55 | # Common parameters for observation
56 | num_points = 10 # Number of fixation points during observation
57 | fixation_time = 1.0 # Time (in seconds) the robot fixates on each point
58 | lookat_point_timeout = 5.0 # Timeout (in seconds) for reaching a fixation point
59 |
60 | # Define parameters for observing the general scene area (above the workspace)
61 | Area_center = (-1.0, 0.0, 0.5) # Coordinates for the center of the observation area
62 | Area_width = 1.0 # Width of the observation area
63 | Area_height = 0.5 # Height of the observation area
64 |
65 | # Command the robot to observe points within the workspace (table surface)
66 | icub.attention.observe_workspace(
67 | center=Table_center,
68 | width=Table_width,
69 | depth=Table_depth,
70 | num_points=num_points,
71 | fixation_time=fixation_time,
72 | lookat_point_timeout=lookat_point_timeout,
73 | waitMotionDone=True # Wait until motion is completed before proceeding
74 | )
75 |
76 | # Command the robot to observe points within the general scene area
77 | icub.attention.observe_scene(
78 | center=Area_center,
79 | width=Area_width,
80 | height=Area_height,
81 | num_points=num_points,
82 | fixation_time=fixation_time,
83 | lookat_point_timeout=lookat_point_timeout,
84 | waitMotionDone=True # Wait until motion is completed before proceeding
85 | )
86 |
87 | # Execute the observation behavior if this script is run as main
88 | if __name__ == "__main__":
89 | observe()
--------------------------------------------------------------------------------
/pyicub/utils.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import math
30 | import pyicub
31 | import socket
32 | import json
33 |
34 | class SingletonMeta(type):
35 |
36 | _instances = {}
37 |
38 | def __call__(cls, *args, **kwargs):
39 | if cls not in cls._instances:
40 | instance = super().__call__(*args, **kwargs)
41 | cls._instances[cls] = instance
42 | return cls._instances[cls]
43 |
44 |
45 | def vector_distance(v, w):
46 | t = 0
47 | for i in range(0, len(v)):
48 | try:
49 | t = t + math.pow(v[i]-w[i],2)
50 | except OverflowError:
51 | t = t + 0
52 | return math.sqrt(t)
53 |
54 | def norm(v):
55 | t = 0
56 | for i in range(0, len(v)):
57 | try:
58 | t = t + math.pow(v[i],2)
59 | except OverflowError:
60 | t = t + 0
61 | return math.sqrt(t)
62 |
63 | def getPublicMethods(obj):
64 | object_methods = [method_name for method_name in dir(obj) if callable(getattr(obj, method_name))]
65 | public_object_methods = list(filter(lambda x: not x.startswith('_'), object_methods))
66 | return public_object_methods
67 |
68 | def getDecoratedMethods(obj, decorator_name):
69 | decorated_methods = []
70 |
71 | for method_name in dir(obj):
72 | method = getattr(obj, method_name)
73 | if callable(method) and hasattr(method, '__call__'):
74 | decorators = getattr(method, '__decorators__', [])
75 | if decorator_name in decorators:
76 | decorated_methods.append(method_name)
77 |
78 | return decorated_methods
79 |
80 | def getPyiCubInfo():
81 | info = {
82 | 'Name': pyicub.__name__,
83 | 'Version': pyicub.__version__,
84 | 'License': pyicub.__license__,
85 | 'Authors': pyicub.__authors__,
86 | 'Emails': pyicub.__emails__,
87 | 'Description': pyicub.__description__
88 | }
89 | return info
90 |
91 | def firstAvailablePort(host, start_port):
92 | res = 1
93 | while True:
94 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
95 | try:
96 | sock.bind((host, start_port))
97 | sock.close()
98 | break
99 | except:
100 | start_port+=1
101 | sock.close()
102 | return start_port
103 |
104 | def importFromJSONFile(JSON_file):
105 | with open(JSON_file, encoding='UTF-8') as f:
106 | data = f.read()
107 | return json.loads(data)
108 |
109 | def exportJSONFile(filepath, obj):
110 | with open(filepath, 'w', encoding='utf-8') as f:
111 | f.write(obj)
112 |
--------------------------------------------------------------------------------
/icub-apps/applications/icubSim/icub-gazebo.xml:
--------------------------------------------------------------------------------
1 |
2 | iCub Gazebo
3 |
4 |
5 |
6 |
7 |
8 | gzserver
9 | $ENV{ICUB_APPS}/gazebo/icub-world.sdf
10 | $ENV{PYICUB_NODE}
11 |
12 |
13 |
14 | gzclient
15 | $ENV{PYICUB_NODE}
16 |
17 |
18 |
19 | yarprobotinterface
20 | --context gazeboCartesianControl --config no_legs.xml
21 |
22 | /$ENV{ICUB_NAME}/torso/state:o
23 | /$ENV{ICUB_NAME}/left_arm/state:o
24 | /$ENV{ICUB_NAME}/right_arm/state:o
25 |
26 |
27 | 5
28 |
29 | $ENV{PYICUB_NODE}
30 |
31 |
32 |
33 |
34 | yarpview
35 | --name /camera_view --x 0 --y 0 --p 50 --w 320 --h 240
36 | $ENV{PYICUB_NODE}
37 |
38 |
39 |
40 | iKinGazeCtrl
41 | --context gazeboCartesianControl --from iKinGazeCtrl.ini
42 |
43 | /$ENV{ICUB_NAME}/torso/state:o
44 | /$ENV{ICUB_NAME}/head/state:o
45 |
46 |
47 | 5
48 |
49 | $ENV{PYICUB_NODE}
50 |
51 |
52 |
53 | iKinCartesianSolver
54 | --context gazeboCartesianControl --part right_arm
55 |
56 | /$ENV{ICUB_NAME}/torso/state:o
57 | /$ENV{ICUB_NAME}/right_arm/state:o
58 |
59 | $ENV{PYICUB_NODE}
60 |
61 |
62 |
63 | iKinCartesianSolver
64 | --context gazeboCartesianControl --part left_arm
65 |
66 | /$ENV{ICUB_NAME}/torso/state:o
67 | /$ENV{ICUB_NAME}/left_arm/state:o
68 |
69 | $ENV{PYICUB_NODE}
70 |
71 |
72 |
73 | wholeBodyDynamics
74 | --robot $ENV{ICUB_NAME} --autoconnect --dummy_ft --headV2 --no_legs
75 |
76 | /$ENV{ICUB_NAME}/head/state:o
77 | /$ENV{ICUB_NAME}/torso/state:o
78 | /$ENV{ICUB_NAME}/right_arm/state:o
79 | /$ENV{ICUB_NAME}/left_arm/state:o
80 | /$ENV{ICUB_NAME}/head/inertials/measures:o
81 |
82 | $ENV{PYICUB_NODE}
83 |
84 |
85 |
86 | iSpeak
87 |
88 | YARP_FORWARD_LOG_ENABLE=1
89 | $ENV{PYICUB_NODE}
90 |
91 |
92 |
93 | yarpdev
94 | --device speech --lingware-context speech --default-language it-IT --pitch 120 --speed 100 --robot $ENV{ICUB_NAME}
95 | YARP_FORWARD_LOG_ENABLE=1
96 | $ENV{PYICUB_NODE}
97 |
98 |
99 |
100 | /iSpeak/speech-dev/rpc
101 | /$ENV{ICUB_NAME}/speech:rpc
102 | tcp
103 |
104 |
105 |
106 | /$ENV{ICUB_NAME}/cam/right/rgbImage:o
107 | /camera_view
108 | udp
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/examples/GazeController/lookat_events.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | """
30 | lookat_events.py
31 | ==================
32 |
33 | This script controls the gaze movement of the iCub humanoid robot with event-based motion monitoring.
34 | It demonstrates how to direct the robot’s gaze to a specific point, detect the motion onset,
35 | wait for the motion to complete, and reset the gaze.
36 |
37 | Usage:
38 | ------
39 | Run this script to move the iCub's gaze while detecting when the movement starts and ends.
40 |
41 | """
42 |
43 | from pyicub.helper import iCub
44 |
45 | # Create an instance of the iCub robot
46 | icub = iCub()
47 |
48 | def look_at_fixation_point_with_events(x: float = -1.0, y: float = -0.5, z: float = 1.0):
49 | """
50 | Moves the iCub's gaze to a specific 3D fixation point and monitors the motion onset and completion.
51 |
52 | Parameters
53 | ----------
54 | x : float, optional
55 | The x-coordinate of the fixation point (default: -1.0).
56 |
57 | y : float, optional
58 | The y-coordinate of the fixation point (default: -0.5).
59 |
60 | z : float, optional
61 | The z-coordinate of the fixation point (default: 1.0).
62 |
63 | Steps
64 | -----
65 | 1. Starts the gaze movement towards the given fixation point.
66 | 2. Does not wait for motion completion (`waitMotionDone=False`).
67 | 3. Waits for the motion onset (`waitMotionOnset()`).
68 | 4. Prints a confirmation message.
69 | 5. Waits for the motion to complete (`waitMotionDone()`).
70 | 6. Prints another confirmation message.
71 |
72 | Example
73 | -------
74 | >>> look_at_fixation_point_with_events(-1.0, -0.5, 1.0)
75 |
76 | Notes
77 | -----
78 | - This function provides real-time feedback on gaze motion events.
79 | - It is useful for synchronizing gaze movement with other robot actions.
80 | """
81 | icub.gaze.lookAtFixationPoint(x, y, z, waitMotionDone=False)
82 | icub.gaze.waitMotionOnset()
83 | print("Motion onset")
84 | icub.gaze.waitMotionDone()
85 | print("Motion done")
86 |
87 | def reset_gaze_to_neutral():
88 | """
89 | Resets the iCub's gaze to the absolute neutral angles.
90 |
91 | Example
92 | -------
93 | >>> reset_gaze_to_neutral()
94 |
95 | Notes
96 | -----
97 | - The gaze is reset by setting the azimuth (`azi`), elevation (`ele`),
98 | and vergence (`ver`) angles to zero.
99 | - This function is useful for returning the gaze to a predefined reference position.
100 | """
101 | icub.gaze.lookAtAbsAngles(azi=0.0, ele=0.0, ver=0.0)
102 |
103 | if __name__ == "__main__":
104 | look_at_fixation_point_with_events()
105 | reset_gaze_to_neutral()
106 |
107 |
--------------------------------------------------------------------------------
/examples/GazeController/lookat_timeout.py:
--------------------------------------------------------------------------------
1 | # BSD 2-Clause License
2 | #
3 | # Copyright (c) 2022, Social Cognition in Human-Robot Interaction,
4 | # Istituto Italiano di Tecnologia, Genova
5 | #
6 | # All rights reserved.
7 | #
8 | # Redistribution and use in source and binary forms, with or without
9 | # modification, are permitted provided that the following conditions are met:
10 | #
11 | # 1. Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # 2. Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
30 | """
31 | lookat_timeout.py
32 | ===================
33 |
34 | This script controls the gaze movement of the iCub humanoid robot with a timeout feature.
35 | It demonstrates how to direct the robot’s gaze to absolute angles while enforcing a
36 | timeout constraint on specific gaze operations.
37 |
38 | Usage:
39 | ------
40 | Run this script to move the iCub's gaze through a sequence of absolute angles
41 | while ensuring that one of the movements respects a timeout limit.
42 |
43 | """
44 |
45 | from pyicub.helper import iCub
46 |
47 | # Create an instance of the iCub robot
48 | icub = iCub()
49 |
50 | def set_gaze_absolute(azi: float, ele: float, ver: float, timeout: float = None):
51 | """
52 | Moves the iCub's gaze to the specified absolute angles.
53 |
54 | Parameters
55 | ----------
56 | azi : float
57 | The azimuth angle in degrees (left/right movement).
58 |
59 | ele : float
60 | The elevation angle in degrees (up/down movement).
61 |
62 | ver : float
63 | The vergence angle in degrees (eye convergence).
64 |
65 | timeout : float, optional
66 | The maximum time allowed (in seconds) for the motion to complete.
67 | If None, the motion executes without a timeout (default: None).
68 |
69 | Example
70 | -------
71 | >>> set_gaze_absolute(10.0, 0.0, 0.0, timeout=1.0)
72 |
73 | Notes
74 | -----
75 | - If `timeout` is specified, the gaze movement must complete within the given duration.
76 | - This function is useful for controlling gaze operations in time-sensitive scenarios.
77 | """
78 | if timeout is not None:
79 | icub.gaze.lookAtAbsAngles(azi, ele, ver, timeout=timeout)
80 | else:
81 | icub.gaze.lookAtAbsAngles(azi, ele, ver)
82 |
83 | def execute_gaze_sequence():
84 | """
85 | Executes a sequence of gaze movements, including a timeout-constrained operation.
86 |
87 | Steps
88 | -----
89 | 1. Moves the gaze to a neutral position `(azi=0.0, ele=0.0, ver=0.0)`.
90 | 2. Moves the gaze to `(azi=10.0, ele=0.0, ver=0.0)` with a timeout of 1 second.
91 | 3. Moves the gaze to `(azi=-10.0, ele=0.0, ver=0.0)` without a timeout.
92 | 4. Resets the gaze back to the neutral position.
93 |
94 | Example
95 | -------
96 | >>> execute_gaze_sequence()
97 |
98 | Notes
99 | -----
100 | - The timeout ensures that one of the gaze movements does not exceed the allowed time limit.
101 | - The function ensures a controlled, sequential execution of gaze motions.
102 | """
103 | set_gaze_absolute(0.0, 0.0, 0.0) # Neutral position
104 | set_gaze_absolute(10.0, 0.0, 0.0, timeout=1.0) # Move with timeout
105 | set_gaze_absolute(-10.0, 0.0, 0.0) # Move without timeout
106 | set_gaze_absolute(0.0, 0.0, 0.0) # Reset to neutral
107 |
108 | if __name__ == "__main__":
109 | execute_gaze_sequence()
110 |
111 |
--------------------------------------------------------------------------------