jrl-umi3218 / mc_rtc

mc_rtc is an interface for simulated and real robotic systems suitable for real-time control
BSD 2-Clause "Simplified" License
122 stars 37 forks source link

Add Python bindings for ControllerClient #384

Closed mmurooka closed 1 year ago

mmurooka commented 1 year ago

This is just an introduction to a new feature I am experimenting with right now. I thought it was interesting and will submit a PR, but it may not necessarily need to be merged.

I thought it would be useful If we could send commands (walking, reaching, etc.) of mc_rtc controller from a Python script or interpreter, and I realized this by using Python bindings in ControllerClient. This PR adds that bindings.

This allows the Python interpreter to send walking and gripper opening/closing commands, as shown in the video below, using BaselineWalkingController as an example. (BaselineWalkingController does not require any changes for this purpose.) In addition to calling it from the interpreter, it will be easy to determine the destination of a walk based on the results of a deep learning model and send walking commands in a Python script.

https://github.com/jrl-umi3218/mc_rtc/assets/6636600/73590010-e4c1-414b-8749-759cd17a67e1

Here is the ControllerClient wrapper for Python.

import mc_rtc
import mc_control

def setup():
    global cli
    cli = mc_control.ControllerClient(b"ipc:///tmp/mc_rtc_pub.ipc", b"ipc:///tmp/mc_rtc_rep.ipc")

def walk(x, y, theta):
    global cli
    elem = mc_control.ElementId([b"BWC", b"GuiWalk"], b"Walk")
    config = mc_rtc.Configuration()
    config.add("goal x [m]", x)
    config.add("goal y [m]", y)
    config.add("goal theta [deg]", theta)
    config.add("number of last footstep", 0)
    cli.send_request(elem, config)

def openGripper():
    global cli
    elem = mc_control.ElementId([b"Global", b"Grippers", b"jvrc1", b"r_gripper"], b"Open")
    cli.send_request(elem)

def closeGripper():
    elem = mc_control.ElementId([b"Global", b"Grippers", b"jvrc1", b"r_gripper"], b"Close")
    cli.send_request(elem)
gergondet commented 1 year ago

Thanks @mmurooka

I think that except for the usability issue with passing bytes instead of strings, which can be worked around using the encode trick I mentionned, this can be merged as-is for a first usable product.

mmurooka commented 1 year ago

Thanks @gergondet I updated it to allow strings