├── 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 | --------------------------------------------------------------------------------