Nous utilisons des cookies pour vous garantir une expérience optimale. Si vous acceptez, vous êtes en accord avec cette utilisation. Pour plus d'informations, veuillez consulter notre politique de confidentialité.
/

Développement

Comment interagir avec Spot SDK

Robin Kurtz
Robin Kurtz
read time

Comme vous le savez sans doute, nous sommes les fiers propriétaires d'un robot Spot. Ce fut un plaisir d'explorer cette nouvelle technologie et de découvrir comment elle peut combler les besoins de nos clients. Au fur et à mesure que nous en apprenons davantage sur Spot, nous voulons partager avec vous nos découvertes, et tout particulièrement la façon dont vous pouvez commander à Spot d’effectuer des tâches dans le contrôleur. Nous pouvons facilement y entrer avec l'aide de Spot SDK (software development kit) et du Knowledge Center fournis par Boston Dynamics.

Communiquer avec Spot

Premièrement, nous devons établir une connexion sécurisée avec Spot afin de le commander. Spot propose différentes méthodes, pour de meilleurs résultats, nous vous recommandons de vous connecter à son réseau Wifi 2,4 GHz. Notez que si vous faites la même chose, il serait idéal d'avoir plusieurs connexions Wifi (ou LAN) sur votre machine, car vous devrez probablement maintenir une connexion à votre Internet pour télécharger des ressources ou demander de l'aide en cours de route.

Une fois authentifié, nous pouvons maintenant envoyer un ping à son adresse IP avec succès.

$ ping 192.168.80.3PING 192.168.80.3 (192.168.80.3) 56(84) bytes of data.64 bytes from 192.168.80.3: icmp_seq=1 ttl=64 time=5.23 ms64 bytes from 192.168.80.3: icmp_seq=2 ttl=64 time=3.04 ms

Pour commander Spot, vous aurez également besoin d'un compte utilisateur et d'un mot de passe fonctionnels. Nous utiliserons des espaces réservés, super sécurisés, pour cet article.

Configuration de l'environnement

Techniquement, vous pouvez exécuter notre code python directement sur votre machine. Cependant, chez Osedea, nous aimons utiliser Docker, avec l'aide de Visual Studio Code Remote - Containers, c'est un rêve !

$ mkdir hello_spot$ cd hello_spot$ touch Dockerfile$ touch docker-requirements.txt$ touch hello_spot.py

Tout d'abord, notre Dockerfile doit contenir les éléments suivants:

FROM python:3.7-slimCOPY docker-requirements.txt .RUN python3 -m pip install -r docker-requirements.txtCOPY . /app/WORKDIR /appENTRYPOINT ["python3", "/app/hello_spot.py"]

Et notre docker-requirements.txt contiendra les bibliothèques dont nous avons besoin pour communiquer avec Spot :

bosdyn-api==3.0.0bosdyn-client==3.0.0bosdyn-core==3.0.0

Maintenant, à partir de VSCode « Open Folder in Container » et laissez la magie opérer. Une fois le conteneur créé, vous pouvez confirmer que vous pouvez toujours vous connecter à Spot en envoyant une fois de plus un ping à son adresse IP :

$ ping 192.168.80.3

Commander Spot

Maintenant que nous avons établi une connexion avec Spot et mis en place un environnement de travail, nous pouvons commencer !

import argparseimport sysimport timeimport bosdyn.clientimport bosdyn.client.leaseimport bosdyn.client.utilimport bosdyn.geometryfrom bosdyn.client.robot_command import (RobotCommandBuilder,                                         RobotCommandClient, blocking_stand)def hello_spot(options):    """A simple example of using the Boston Dynamics API to command a Spot robot."""    # The SDK object is the primary entry point to the Boston Dynamics API.    # create_standard_sdk will initialize an SDK object with typical default    # parameters. The argument passed in is a string identifying the client.    sdk = bosdyn.client.create_standard_sdk('HelloSpotClient')    # A Robot object represents a single robot. Clients using the Boston    # Dynamics API can manage multiple robots, but this tutorial limits    # access to just one. The network address of the robot needs to be    # specified to reach it. This can be done with a DNS name    # (e.g. spot.intranet.example.com) or an IP literal (e.g. 10.0.63.1)    robot = sdk.create_robot(options.hostname)    # Clients need to authenticate to a robot before being able to use it.    robot.authenticate(options.username, options.password)    # Establish time sync with the robot. This kicks off a background thread to establish time sync.    # Time sync is required to issue commands to the robot. After starting time sync thread, block    # until sync is established.    robot.time_sync.wait_for_sync()    # Verify the robot is not estopped and that an external application has registered and holds    # an estop endpoint.    assert not robot.is_estopped(), "Robot is estopped. Please use an external E-Stop client, " \                                    "such as the estop SDK example, to optionsure E-Stop."    # Only one client at a time can operate a robot. Clients acquire a lease to    # indicate that they want to control a robot. Acquiring may fail if another    # client is currently controlling the robot. When the client is done    # controlling the robot, it should return the lease so other clients can    # control it. Note that the lease is returned as the "finally" condition in this    # try-catch-finally block.    lease_client = robot.ensure_client(        bosdyn.client.lease.LeaseClient.default_service_name)    lease = lease_client.acquire()    try:        with bosdyn.client.lease.LeaseKeepAlive(lease_client):            # Now, we are ready to power on the robot. This call will block until the power            # is on. Commands would fail if this did not happen. We can also check that the robot is            # powered at any point.            robot.power_on(timeout_sec=20)            assert robot.is_powered_on(), "Robot power on failed."            # Tell the robot to stand up. The command service is used to issue commands to a robot.            # The set of valid commands for a robot depends on hardware optionsuration. See            # SpotCommandHelper for more detailed examples on command building. The robot            # command service requires timesync between the robot and the client.            command_client = robot.ensure_client(                RobotCommandClient.default_service_name)            blocking_stand(command_client, timeout_sec=10)            time.sleep(3)            # Tell the robot to stand in a twisted position.            #            # The RobotCommandBuilder constructs command messages, which are then            # issued to the robot using "robot_command" on the command client.            #            # In this example, the RobotCommandBuilder generates a stand command            # message with a non-default rotation in the footprint frame. The footprint            # frame is a gravity aligned frame with its origin located at the geometric            # center of the feet. The X axis of the footprint frame points forward along            # the robot's length, the Z axis points up aligned with gravity, and the Y            # axis is the cross-product of the two.            footprint_R_body = bosdyn.geometry.EulerZXY(                yaw=0.4, roll=0.0, pitch=0.0)            cmd = RobotCommandBuilder.synchro_stand_command(                footprint_R_body=footprint_R_body)            command_client.robot_command(cmd)            time.sleep(3)            # Now tell the robot to stand taller, using the same approach of constructing            # a command message with the RobotCommandBuilder and issuing it with            # robot_command.            cmd = RobotCommandBuilder.synchro_stand_command(body_height=0.1)            command_client.robot_command(cmd)            time.sleep(3)            # Power the robot off. By specifying "cut_immediately=False", a safe power off command            # is issued to the robot. This will attempt to sit the robot before powering off.            robot.power_off(cut_immediately=False, timeout_sec=20)            assert not robot.is_powered_on(), "Robot power off failed."    finally:        # If we successfully acquired a lease, return it.        lease_client.return_lease(lease)def main(argv):    """Command line interface."""    parser = argparse.ArgumentParser()    bosdyn.client.util.add_common_arguments(parser)    options = parser.parse_args(argv)    try:        hello_spot(options)        return True    except Exception as exc:        logger = bosdyn.client.util.get_logger()        logger.error(f"Hello, Spot! threw an exception: {str(exc)}")        return Falseif __name__ == '__main__':    if not main(sys.argv[1:]):        sys.exit(1)

Notez que l'extrait ci-dessus a été extrait du SDK mentionné ci-haut et supprimé. Nous vous invitons à jeter un œil à un exemple plus fonctionnel de hello spot.py.

Une fois cela fait, l'exécution de la commande suivante active Spot et le fait se tenir debout, poser, se tenir plus grand, puis s'éteindre [1].

$ export USERNAME=osedea$ export PASSWORD=secret$ export ROBOT_IP=192.168.80.3$ python3 hello_spot.py --username USERNAME --password PASSWORD ROBOT_IP

Félicitations 🎉 ! Vous avez en théorie commandé avec succès votre Spot… cependant, si vous n'en avez pas, envoyez-nous un message et peut-être pourrez-vous rencontrer le nôtre.

[1] Pour ce faire vous devez techniquement établir une estop externe. Cela peut facilement se faire en suivant l’exemple suivant : Boston-Dynamic/spot-sdk

Crédit Photo: yakari_pixel

Did this article start to give you some ideas? We’d love to work with you! Get in touch and let’s discover what we can do together.

Get in touch
Button Arrow

Further Reading

Développement

Exploiter les données de votre organisation avec les bases de données vectorielles

Carl Lapierre
Carl Lapierre
read time
Développement

Modèles réactifs de domaines riches en React + Typescript

Zack Therrien
Zack Therrien
read time
Développement

Voyez ce que le robot Spot voit avec AME: Autowalk Mission Evaluator

Robin Kurtz
Robin Kurtz
read time
Développement

Trois astuces pour se remettre rapidement au code suite à une réunion

Nicolas Carlo
Nicolas Carlo
read time
Développement

Astuces et meilleures pratiques pour Flutter

Polina Rolich
Polina Rolich
read time
Développement

Comment l'EventStorming a facilité le transfert de connaissances et la découverte d'un domaine métier complexe

Alizée Gottardo
Alizée Gottardo
read time