Skip to content

Fixed crc.py to match crc_aarch64.so lib file instead of crc_arm64.so. #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added example/go2/audiohub/example.mp3
Binary file not shown.
Binary file added example/go2/audiohub/example.wav
Binary file not shown.
42 changes: 42 additions & 0 deletions example/go2/audiohub/megaphone_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import time
import sys

from unitree_sdk2py.core.channel import ChannelFactoryInitialize
from unitree_sdk2py.go2.audiohub.audiohub_client import AudioHubClient

#from unitree_sdk2py.idl.idl_dataclass import IDLDataClass
#from unitree_sdk2py.utils.logger import setup_logging
#from unitree_sdk2py.sdk.sdk import create_standard_sdk

if __name__ == "__main__":

if len(sys.argv) < 2:
print(f"Usage: python3 {sys.argv[0]} networkInterface")
sys.exit(-1)

ChannelFactoryInitialize(0, sys.argv[1])

# Initialize the SDK with a custom name, which is used to identify the SDK instance and its associated logs.
#sdk = create_standard_sdk('UnitreeGo2SDK')

# Create a robot instance using the DDS protocol.
# `domainId=0` is used as it is currently the standard for all Go2 robots, although a script to change this on the robot is planned.
# `interface="eth0"` specifies the network interface the DDS should use.
# Each robot is uniquely identified by a serial number, allowing for multiple robots to be managed by the SDK.
# Check if the network interface argument is provided


client = AudioHubClient()
client.SetTimeout(3.0)
client.Init()

# Enable Megaphone
client.MegaphoneEnter()

# uploading mp3/wav
#client.MegaphoneUpload("oiia-oiia-sound.mp3")
client.MegaphoneUpload("oiia-oiia-sound.wav")
time.sleep(5)

# Disable Megaphone
client.MegaphoneExit()
Binary file added example/go2/audiohub/oiia-oiia-sound.mp3
Binary file not shown.
Binary file added example/go2/audiohub/oiia-oiia-sound.wav
Binary file not shown.
Binary file added example/go2/audiohub/sound_1.mp3
Binary file not shown.
Binary file added example/go2/audiohub/sound_1.wav
Binary file not shown.
78 changes: 78 additions & 0 deletions unitree_sdk2py/go2/audiohub/audiohub_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""
" service name
"""
AUDIOHUB_SERVICE_NAME = "audiohub"


"""
" service api version
"""
AUDIOHUB_API_VERSION = "1.0.0.1"


"""
" api id
"""
# API ID | FUNCTION
# 1001 | audio list
# 1002 | select a recording and start playing it
# 1003 | pause
# 1004 | unsuspend
# 1005 | select the previous recording and start playing
# 1006 | select the next recording and start playing
# 1007 | set play mode (no cycle, single cycle, list loop)
# 1008 | select a recording and rename it
# 1009 | select a recording and delete it. (If the recording is being played,
# a pop-up message is displayed to confirm that the recording cannot
# be played after deletion.)
# 1010 | get play mode (no cycle, single cycle, list loop)


AUDIOHUB_API_ID_AUDIO_PLAYER_AUDIO_LIST = 1001
AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_START_PLAY = 1002
AUDIOHUB_API_ID_AUDIO_PLAYER_PAUSE = 1003
AUDIOHUB_API_ID_AUDIO_PLAYER_UNSUSPEND = 1004
AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_PREV_START_PLAY = 1005
AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_NEXT_START_PLAY = 1006
AUDIOHUB_API_ID_AUDIO_PLAYER_SET_PLAY_MODE = 1007
AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_RENAME = 1008
AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_DELETE = 1009
AUDIOHUB_API_ID_AUDIO_PLAYER_GET_PLAY_MODE = 1010

# API ID | FUNCTION
# 2001 | upload audio file

AUDIOHUB_API_ID_AUDIO_PLAYER_UPLOAD_AUDIO_FILE = 2001

# API ID | FUNCTION
# 3001 | play start_obstacle_avoidance audio
# 3002 | play exit_obstacle_avoidance audio
# 3003 | play start_companion_mode audio
# 3004 | play exit_companion_mode audio

AUDIOHUB_INTERNAL_CORPUS_BASE = 3000
AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_OBSTACLE_AVOIDANCE = 1
AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_OBSTACLE_AVOIDANCE = 2
AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_COMPANION_MODE = 3
AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_COMPANION_MODE = 4

# API ID | FUNCTION
# 4001 | enter megaphone
# 4002 | exit megaphone
# 4003 | upload

AUDIOHUB_API_ID_ENTER_MEGAPHONE = 4001
AUDIOHUB_API_ID_EXIT_MEGAPHONE = 4002
AUDIOHUB_API_ID_UPLOAD_MEGAPHONE = 4003

# API ID | FUNCTION
# 5001 Select internal long corpus to play
# 5002 Internal long corpus playback completed notification
# 5003 Stops playing current internal long corpus

AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_SELECT_TO_PLAY = 5001
AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_PLAYBACK_COMPLETED = 5002
AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_STOP_PLAYING = 5003



243 changes: 243 additions & 0 deletions unitree_sdk2py/go2/audiohub/audiohub_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
import logging
import json

from ...rpc.client import Client
from .audiohub_api import *

from pydub import AudioSegment
import base64
import time
import uuid

CHUNK_SIZE = 61440

"""
" class AudioHubClient
"""
class AudioHubClient(Client):
default_service_name = AUDIOHUB_SERVICE_NAME

def __init__(self, *args, **kwargs):
#self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__)
#self.communicator = communicator
self.serviceName = AudioHubClient.default_service_name
super().__init__(serviceName=self.serviceName, enabaleLease=False)

def Init(self):
# set api version
self._SetApiVerson(AUDIOHUB_API_VERSION)

# regist api
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_AUDIO_LIST, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_START_PLAY, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_PAUSE, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_UNSUSPEND, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_SET_PLAY_MODE, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_RENAME, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_DELETE, 0)
self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_GET_PLAY_MODE, 0)

self._RegistApi(AUDIOHUB_API_ID_AUDIO_PLAYER_UPLOAD_AUDIO_FILE, 0)

self._RegistApi(AUDIOHUB_INTERNAL_CORPUS_BASE + AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_OBSTACLE_AVOIDANCE, 0)
self._RegistApi(AUDIOHUB_INTERNAL_CORPUS_BASE + AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_OBSTACLE_AVOIDANCE, 0)
self._RegistApi(AUDIOHUB_INTERNAL_CORPUS_BASE + AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_COMPANION_MODE, 0)
self._RegistApi(AUDIOHUB_INTERNAL_CORPUS_BASE + AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_COMPANION_MODE, 0)

self._RegistApi(AUDIOHUB_API_ID_ENTER_MEGAPHONE, 0)
self._RegistApi(AUDIOHUB_API_ID_EXIT_MEGAPHONE, 0)
self._RegistApi(AUDIOHUB_API_ID_UPLOAD_MEGAPHONE, 0)

self._RegistApi(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_SELECT_TO_PLAY, 0)
self._RegistApi(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_PLAYBACK_COMPLETED, 0)
self._RegistApi(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_STOP_PLAYING, 0)

# 1001
def AudioPlayerGetAudioList(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_AUDIO_LIST, parameter)
if code == 0:
return code, json.loads(data)
else:
return code, None

# 1002
def AudioPlayerPlayByUUID(self, uuid):
p = {}
p['unique_id'] = uuid
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_START_PLAY, parameter)
return code

# 1003
def AudioPlayerPause(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_PAUSE, parameter)
return code

# 1004
def AudioPlayerResume(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_UNSUSPEND, parameter)
return code

# 1007
#playmode: single_cycle, no_cycle, list_loop
def AudioPlayerSetPlayMode(self, playMode):
p = {}
p["play_mode"] = playMode
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_SET_PLAY_MODE, parameter)
return code

# 1008
def AudioPlayerRenameRecord(self, uuid, newName):
p = {}
p["unique_id"] = uuid
p["new_name"] = newName
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_RENAME, parameter)
return code

# 1009
def AudioPlayerdeleteRecord(self, uuid):
p = {}
p["unique_id"] = uuid
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_DELETE, parameter)
return code

# 1009
def AudioPlayerGetPlayMode(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_GET_PLAY_MODE, parameter)
if code == 0:
return code, json.loads(data)
else:
return code, None


# 2001
# Upload mp3 or wav
def AudioPlayerUploadAudioFile(self, audiofile_path):
if audiofile_path.endswith(".mp3"):
# Convert MP3 to WAV
audio = AudioSegment.from_mp3(audiofile_path)
wav_file_path = audiofile_path.replace('.mp3', '.wav')
audio.export(wav_file_path, format='wav')
else:
wav_file_path = audiofile_path

# Read WAV file and split into chunks
with open(wav_file_path, 'rb') as f:
audio_data = f.read()

chunks = [audio_data[i:i + CHUNK_SIZE] for i in range(0, len(audio_data), CHUNK_SIZE)]
total_chunks = len(chunks)

for index, chunk in enumerate(chunks):
block_content = base64.b64encode(chunk).decode('utf-8')
p = {
'file_size': len(audio_data),
'current_block_size': len(chunk),
'file_type': 'wav',
'file_md5': 'asdasd', # Replace with actual MD5 hash
'file_name': 'audio_' + str(uuid.uuid4())[:4],
'create_time': int(time.time() * 1000),
'block_content': block_content,
'current_block_index': index + 1,
'total_block_number': total_chunks
}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_AUDIO_PLAYER_UPLOAD_AUDIO_FILE, parameter)
if code != 0:
# Handle error
#self.logger.error(f"Error uploading chunk {index + 1}/{total_chunks}: Error code: {code}")
return code

return code

# 3001
def InternalCorpusPlay(self, num):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_INTERNAL_CORPUS_BASE + num, parameter)
return code

#4001
def MegaphoneEnter(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_ENTER_MEGAPHONE, parameter)
return code

#4002
def MegaphoneExit(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_EXIT_MEGAPHONE, parameter)
return code

#4003
def MegaphoneUpload(self, audiofile_path):
if audiofile_path.endswith(".mp3"):
# Convert MP3 to WAV
audio = AudioSegment.from_mp3(audiofile_path)
wav_file_path = audiofile_path.replace('.mp3', '.wav')
audio.export(wav_file_path, format='wav')
else:
wav_file_path = audiofile_path

# Read WAV file and split into chunks
with open(wav_file_path, 'rb') as f:
audio_data = f.read()

chunks = [audio_data[i:i + CHUNK_SIZE] for i in range(0, len(audio_data), CHUNK_SIZE)]
total_chunks = len(chunks)

for index, chunk in enumerate(chunks):
block_content = base64.b64encode(chunk).decode('utf-8')
p = {
'current_block_size': len(chunk),
'block_content': block_content,
'current_block_index': index + 1,
'total_block_number': total_chunks
}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_UPLOAD_MEGAPHONE, parameter)
if code != 0:
# Handle error
#self.logger.error(f"Error uploading chunk {index + 1}/{total_chunks}: Error code: {code}")
return code

return code

#5001
def InternalLongCorpusPlay(self, name, callback=None):
p = {}
p['corpus_name'] = name
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_SELECT_TO_PLAY, parameter)
return code


#5002
def InternalLongCorpusPlaybackCompleted(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_PLAYBACK_COMPLETED, parameter)
return code


#5003
def InternalLongCorpusStop(self):
p = {}
parameter = json.dumps(p)
code, data = self._Call(AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_STOP_PLAYING, parameter)
return code