From a7413e293c19fc1491391409f511efdc0def99e2 Mon Sep 17 00:00:00 2001 From: lgv Date: Mon, 2 Feb 2026 09:37:47 +0800 Subject: [PATCH] feat:add http server --- .idea/grpc_client.iml | 2 +- .idea/misc.xml | 2 +- clients/__init__.py | 0 clients/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 142 bytes .../__pycache__/base_client.cpython-39.pyc | Bin 0 -> 2032 bytes .../__pycache__/hand_client.cpython-39.pyc | Bin 0 -> 2316 bytes .../__pycache__/http_server.cpython-39.pyc | Bin 0 -> 3074 bytes .../__pycache__/movej_client.cpython-39.pyc | Bin 0 -> 6659 bytes clients/base_client.py | 7 +- clients/get_joint_state_client.py | 114 +++++- clients/hand_client.py | 16 +- clients/http_server.py | 133 +++++++ clients/main.py | 141 +++++++ clients/movej_client.py | 359 +++++++++++++++--- clients/test.py | 21 +- generated/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 144 bytes .../cmvr/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 149 bytes .../api/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 153 bytes .../api/__pycache__/common_pb2.cpython-39.pyc | Bin 0 -> 2186 bytes .../dexhand_command_pb2.cpython-39.pyc | Bin 0 -> 6894 bytes .../dexhand_service_pb2_grpc.cpython-39.pyc | Bin 0 -> 6977 bytes .../hlc_command_pb2.cpython-39.pyc | Bin 0 -> 1444 bytes .../humanoid_robot_command_pb2.cpython-39.pyc | Bin 0 -> 5397 bytes ...noid_robot_service_pb2_grpc.cpython-39.pyc | Bin 0 -> 6691 bytes 24 files changed, 713 insertions(+), 82 deletions(-) create mode 100644 clients/__init__.py create mode 100644 clients/__pycache__/__init__.cpython-39.pyc create mode 100644 clients/__pycache__/base_client.cpython-39.pyc create mode 100644 clients/__pycache__/hand_client.cpython-39.pyc create mode 100644 clients/__pycache__/http_server.cpython-39.pyc create mode 100644 clients/__pycache__/movej_client.cpython-39.pyc create mode 100644 clients/http_server.py create mode 100644 clients/main.py create mode 100644 generated/__pycache__/__init__.cpython-39.pyc create mode 100644 generated/cmvr/__pycache__/__init__.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/__init__.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/common_pb2.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/dexhand_command_pb2.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/dexhand_service_pb2_grpc.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/hlc_command_pb2.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/humanoid_robot_command_pb2.cpython-39.pyc create mode 100644 generated/cmvr/api/__pycache__/humanoid_robot_service_pb2_grpc.cpython-39.pyc diff --git a/.idea/grpc_client.iml b/.idea/grpc_client.iml index 7584dbd..2c80e12 100644 --- a/.idea/grpc_client.iml +++ b/.idea/grpc_client.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a031d5d..366343e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/clients/__init__.py b/clients/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/clients/__pycache__/__init__.cpython-39.pyc b/clients/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf6364807ba813ba1cd095e03729ae05cebf3462 GIT binary patch literal 142 zcmYe~<>g`k0#7feOc4DTL?8o3AjbiSi&=m~3PUi1CZpdjFNXe3{*m7(jXv?5QTB5Ds7)aV0MUli#nqG{+E*g{&Kv3M3O@$(v z<;sZ&VHV_-NYR|eH- zjW2MMskg`xJ*8lCNyoIg9{lKGeb{gs6k}B2z3DV5`I<0;na6~gM~bt^=pM1FXK)^} zW7AxF=E;M+y3ZpnJjq$E`NKm28}A*AhF%m0%oTAjmTt<$Vc>H&>20|CBJsgwjq%q9 zUc|2L`RM)Pqr&0=jPwo&PVnw36K24eo;J4W4tk#2&R&J0V=gjUXfEt;)eLA*2nz(;`R44jk=JmJC#RNN2vO&v5Q zXd2~L^2T%tHCS`slb6~$jDio%9f5FUt6L=vfE1lh$NFf-5ldiGcuQ@Y7OBfV+#C5m zP@+Ey!||LuoLys2_U_za99hU7W&wXbvAmLdR%TdzF9G?t|6bCRuHA!9|>Sl$=#BXNFAp=Qvqc? zHg@|X33hn}$Uh2YNm}fG&f3#iCn?CaSN4%Tr~t7D+oFOtOWXYQQ)nd@cJnG$iHi-! zS$a}9|F*2C$3ny+U;G!WQlTMaxt@lcC$=J%(62GWuBe+*v@z%n5I12I4T(^V)@Yk5 zv`KHmXwnuGMU$E^*Ff9;TT_>4_WrfvxL&xI>I6x0-h)1X1u{-pD5n&=i&ToPqs}=! z?>4u$!Z?NO&-@2ShfAHtvNeG@$aNnri;NYS0m|XMuU_{Z(0vReMX<5vYcyNAdY!`6 zj;#t4Yy=i~L1epveIxRQ+;#Js>keZ!3h}+}x-UmwSnh}wv`1J42D@+o>{y}z9sVH+ z_Ojv>CaqP?6@fatC05bs7KmI;$IvMg_*V*pp1@Xv;rl>)2nnq;jl)A=S>g%!S8&Wn z5BDCs+u!Ww8h(;jyd>cf120nKCicjVmjnWNSP-p<_g{z0%`eM~eT7*|5kwORVA48m LDQ&t2b6xodG)Iw58<%SrHGMl$rztLQ&Ngl78?~p#)K3QY@c$bMe)8c6NQG zIqrB#Un{{gt&~3YzrYK;?JE*e-jH~!D#VQKTyqs=t)1DKotd4TnH>ksrcGe1cD(3m zosd6}I6EvLuEUgFN(dv2#>7Lc#dM%~8YP_c^<#tS&nQK{5myGLSIyTISX-Wzug$nN zusu6pSDE!hV>MP_yTtVpH%i=OEtKn-ULEYVOPvDSC0#FZqr|Ut8ldyP=kyG(2{NR# zTVT7S>&4lu!4~rUW`V(%)-A#o+0rAzmbiVSdu_hJmhWpnQt>Ts9}#a6EWGL5;y#AA z#25R^yur?~^N%rti^u1l5r_=kA)N~+82vjPs+w6e;4%vash@T~7&lz^{T?535oDaf z_A=uS_k$tx!(=c(3_`%RkxYgq)!t6JNwyhBe3*R}NZv!^IG$@tiu@hK81`Z=Lv-+T)L?xBUaOR8kH~~>ks~^-WVOEC2c1cU z>5sLkIsS4&`t^QeVxrr?sb)=P9zl%*u1>1`R=@o-d8(BhE9Wen;nZ?YwZC}EyGw?y zL9(U8UnrTvn;2gJOZLP%f(p1xz9y_bwSKUMc7fN(8gL*`jq$IxQ;s488%`X_%t`hf z7KNEyb-3GeS7$;f`^_AMobOj6wzA=@tvV}t%5m*}G@VyFBe*^%_{o0=x~@BS%DoxI z_=70qe#ADMV(EOoHQNla)=meOoC$LWrd$EgBNKA(?J31XPN0G=L4p{)1nuUr_LFvC zKtOa+1wny*NuX{ADmm?XjhljVmJGhaf<~UZrfBe-h;tzG;^VE2-EiC(_U_%51kla<_O$eSFy+9Ow-)=y71wzdUUeKsawSwiiS(XB&4q%L3o3YHk*d<96X)b(z4 zEPn#?qiQqrs&$KJnC z*JM;B6%joCi+E}^zq^#G$?>{=d0pUh=nzb*+Kq=HPqQc)c52FyJl+!vpeWu!kekpl zDK4QcUGM{C2rg4ad0r3&IFFmQoaJvFX!$MxQn#r|E%+LGOE;-TwSP=gqYJ=Ug6|@2 z(ecGMl>szw(FP+OQ(3-035JW@JuV7T+ACQNjb6)B4P^xw>NuZ|OR3ur_9qko4HPRs4 zhn||Ie8|+&?7!mTBXNT?64+<+R2IduTs{!D3xARF(FpuScr`p#?g#gw9P-zbfK9JH z7{%Dz*=~4FGbZHS`9B&%jKT d-wVT@t*P~jdTCg5{My2Mwq~AczBCqE#=p$ePk8_U literal 0 HcmV?d00001 diff --git a/clients/__pycache__/http_server.cpython-39.pyc b/clients/__pycache__/http_server.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5a6359ade8cf386f741844f91e0f2a6fcb759f4 GIT binary patch literal 3074 zcmbVO+iw(A7(Zubc4qd{?Y5NrZ7FD24Ny^eXbj<^c!^X48gwj7rgKi)fw?SaW-Hwk zV^X3Lso_E61tIi-2r=!U&^238+OW@`|rm3j9@H4Kz!WI?c}ox}{4# z=No}(nUdH2d{D3ok~jQfP_jxvm(>-Nt#Z(9bq5uz67*O-lyIGyEI&i7-WLfgu;LlQ zirk!5tz{sWSQp4$Qtsp0G_jVmva^CI&Pw=J!MB=qvm&c}t*{=}dq%U?@ZRHV*)qP2 z_01@3Ia_gtOjB!})UIr4SFzPnyIyM7w6ts4I;q_N+Kp^I?~^lZU>l{j$~Up<3FSN$ z0}_dTtDpBD-^@0#ezuvF*_Ii^Lpe-pk1ZgcHJTQkFpLr>@uDyu0$F=Ca!B9|ZHYI`(z^nw}O9Micy%{l3S;BrQ2EHrPQU_T044k{nN@eJ!2| zZ-U!y6pTh9xlha8D2#&1_AKMv_oL>nml}Z+MjopkibkTOx<3jN5&2cHtGacc50-l2 zSoO*3!A8PQ!T;s4FcQ25X66zv@wtne?0i%Z_MqeJ0)`WdGGZxjf&+1tDbIn^z+Z!Z z&eE6;yaBvvX@R+E(wkuC*IQzxJ<4IDtV=gAR*j}F$WfK#oTONWQrT?? z0Ul*%fTcwrJh3G-yW60S`jL|yO)Ii>)C;|MoHN@=hH9Ev3G;|mNLC|RgQN{o#;rr$ zdLY=XW7{T`+5@5o^fd+IBXes!hg26lX^7BOpl$KdfI;~7qg&M>A0^~CWt1s1H11Cn zrcTidglQL*Davw8pV1DJM4cw56_#_fDeC0T)27}$HbthCX~*HR+}z)}pz#)p7^p$gB! z`(Mp}diCbnZ*I+=yLol?=EWPguYV<5wpHhDdxqbbk`ENg- zoB83^jZfz;T)KVz-0wflWP@*CKie8Mf9>am&%cL}3t#*)H+yNZ`CP`#eRpo|gPCl+ z9B=@0;GYa2cn} z?P*6Fp)2~ayPhSAl=6BUERqF3ZdIsR_1abNqN<@+?HJNNbwJ7D!@*N!ZDcgUgy zCsP)!oQ-*w`%5M_8OV75NJs)qZ^%OyrT zEO;6%Fm}YU1U#@dUg{+F7#4_qq9kgfF^VY@P5=VtUiX%cUCYUQy;ReZ78b^MVrLed zLep?7L_sH&?_Kc>$XJpC#|v${+1*ho2c3GoX$)+aueS%{tfr>gcoakRuj8Et>H}0I zR@;J=e6#_z0xG${(-&KD+I%uDxWlm2sVEzxP}-cjC$Na5W_^-5VdA+WhoYWL*0Cqz zl9mFvY8`J?@hsNSA%*k=bXHMBg1bpoFf+>uSl`6sNR~iOx-uFL*Aw(ifes?@j8YXq zl0e8xni`D>&y7Twsu252qG~>u-CK5J%8GXbDJgh`kgrlz3wlMbn7WF=4X;{xwnPhR P>+6Ak9xokQ`xO2LEnn}U literal 0 HcmV?d00001 diff --git a/clients/__pycache__/movej_client.cpython-39.pyc b/clients/__pycache__/movej_client.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90a9f1c7b1df54a33e4b2af15ea0b11410f82199 GIT binary patch literal 6659 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 RoFRMz&Y&Idscykp`M;!PIrIPk literal 0 HcmV?d00001 diff --git a/clients/base_client.py b/clients/base_client.py index dc6c854..6896f03 100644 --- a/clients/base_client.py +++ b/clients/base_client.py @@ -1,8 +1,11 @@ import grpc import time import sys -sys.path.append("/home/lgv/cmvr/0-workspace/grpc_client/generated") # 指向 generated -sys.path.append("/home/lgv/cmvr/0-workspace/grpc_client/generated/cmvr") # 指向 cmvr 顶层 +from pathlib import Path +BASE_DIR = Path(__file__).resolve().parent.parent # 上一级目录 + +sys.path.append(str(BASE_DIR / "generated")) +sys.path.append(str(BASE_DIR / "generated" / "cmvr")) from cmvr.api import humanoid_robot_service_pb2_grpc from cmvr.api import dexhand_service_pb2_grpc diff --git a/clients/get_joint_state_client.py b/clients/get_joint_state_client.py index f0d8d00..e856b76 100644 --- a/clients/get_joint_state_client.py +++ b/clients/get_joint_state_client.py @@ -2,19 +2,42 @@ import sys import time from google.protobuf import timestamp_pb2 +import matplotlib.pyplot as plt # 新增 + sys.path.append("../generated") from generated.cmvr.api import humanoid_robot_service_pb2_grpc as rpc from generated.cmvr.api import humanoid_robot_command_pb2 as pb from clients.base_client import RobotClientBase +# 固定关节顺序 +JOINT_ORDER = [ + "L_SHOULDER_P", "L_SHOULDER_R", "L_SHOULDER_Y", + "L_ELBOW_R", "L_WRIST_P", "L_WRIST_Y", "L_WRIST_R", + "R_SHOULDER_P", "R_SHOULDER_R", "R_SHOULDER_Y", + "R_ELBOW_R", "R_WRIST_P", "R_WRIST_Y", "R_WRIST_R", + "HEAD_P", "HEAD_Y", "HEAD_R","WAIST_Y","WAIST_R" +] + class GetJointStateClient(RobotClientBase): """Continuous client to fetch robot joint states""" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # 时间轴 + self.time_history = [] + self._start_time = None + # 记录每个关节的角度、速度 + self.pos_history = {name: [] for name in JOINT_ORDER} + self.vel_history = {name: [] for name in JOINT_ORDER} + def send(self, interval=0.5, device_id="hc01"): """Continuously fetch joint states and print in fixed order""" try: + if self._start_time is None: + self._start_time = time.time() + while True: # Construct request req = pb.JointRequest() @@ -31,24 +54,25 @@ class GetJointStateClient(RobotClientBase): time.sleep(interval) continue - # Fixed order for printing - joint_order = [ - "L_SHOULDER_P", "L_SHOULDER_R", "L_SHOULDER_Y", - "L_ELBOW_R", "L_WRIST_P", "L_WRIST_Y", "L_WRIST_R", - "R_SHOULDER_P", "R_SHOULDER_R", "R_SHOULDER_Y", - "R_ELBOW_R", "R_WRIST_P", "R_WRIST_Y", "R_WRIST_R", - "HEAD_P", "HEAD_Y","HEAD_R" - ] - - - # Map response to dictionary - joint_dict = {} + # ====== 1. 同时取 position 和 velocity ====== + joint_pos_dict = {} + joint_vel_dict = {} for state in resp.state: - for name, pos in zip(state.name, state.position): - joint_dict[name] = round(pos, 12) + # 这里就用你说的三元 zip + for name, pos, vel in zip(state.name, state.position, state.velocity): + joint_pos_dict[name] = round(pos, 12) + joint_vel_dict[name] = round(vel, 12) - joint_list = [{"joint_name": name, "rad": joint_dict.get(name, 0.0)} - for name in joint_order] + # ====== 2. 记录到历史数据里,用于之后画图 ====== + t = time.time() - self._start_time + self.time_history.append(t) + for name in JOINT_ORDER: + self.pos_history[name].append(joint_pos_dict.get(name, 0.0)) + self.vel_history[name].append(joint_vel_dict.get(name, 0.0)) + + # 保持原来的打印逻辑(打印角度) + joint_list = [{"joint_name": name, "rad": joint_pos_dict.get(name, 0.0)} + for name in JOINT_ORDER] # Print timestamp print(f"[{time.strftime('%H:%M:%S')}]") @@ -63,11 +87,67 @@ class GetJointStateClient(RobotClientBase): except KeyboardInterrupt: print("\nStopped fetching joint states.") + # 例子:退出时画几个关节的角度 & 速度曲线 + # try: + # # 你可以根据需要改关节列表 + # self.plot_pos_and_vel([ "R_SHOULDER_P", "R_SHOULDER_R", "R_SHOULDER_Y", + # "R_ELBOW_R", "R_WRIST_P", "R_WRIST_Y", "R_WRIST_R"]) + # except Exception as e: + # print(f"绘图失败: {e}") + + # ====== 3. 绘制速度和角度(同一张图,两行子图) ====== + def plot_pos_and_vel(self, joint_names): + """ + 在一张图中绘制多个关节的角度和速度: + - 上 subplot:角度(rad) + - 下 subplot:速度(rad/s) + + joint_names: str 或 [str, ...] + """ + if isinstance(joint_names, str): + joint_names = [joint_names] + + # 检查关节名合法性 + invalid = [n for n in joint_names if n not in self.pos_history] + if invalid: + print(f"未知关节名: {invalid}") + print(f"可选关节: {list(self.pos_history.keys())}") + return + + if not self.time_history: + print("还没有采集到任何数据,无法绘图。") + return + + t = self.time_history + + plt.figure(figsize=(10, 6)) + + # 上:角度 + plt.subplot(2, 1, 1) + for name in joint_names: + plt.plot(t, self.pos_history[name], label=name) + plt.ylabel("Position (rad)") + plt.title("Joint Position") + plt.grid(True) + plt.legend() + + # 下:速度 + plt.subplot(2, 1, 2) + for name in joint_names: + plt.plot(t, self.vel_history[name], label=name) + plt.xlabel("Time (s)") + plt.ylabel("Velocity (rad/s)") + plt.title("Joint Velocity") + plt.grid(True) + plt.legend() + + plt.tight_layout() + plt.show() if __name__ == "__main__": client = GetJointStateClient() try: - client.send(interval=0.5) + client.send(interval=0.005) finally: client.close() diff --git a/clients/hand_client.py b/clients/hand_client.py index 9c74bb2..dc212e4 100644 --- a/clients/hand_client.py +++ b/clients/hand_client.py @@ -14,16 +14,16 @@ handshake = [ {"id": 1, "value": 0.0}, {"id": 2, "value": 0.0}, {"id": 3, "value": 0.0}, - {"id": 4, "value": 0.1}, - {"id": 5, "value": 0.0}, + {"id": 4, "value": 0.0}, + {"id": 5, "value": 1.0}, ] hand_open = [ - {"id": 0, "value": 0.8}, - {"id": 1, "value": 0.8}, - {"id": 2, "value": 0.8}, - {"id": 3, "value": 0.8}, - {"id": 4, "value": 0.8}, + {"id": 0, "value": 0.7}, + {"id": 1, "value": 0.7}, + {"id": 2, "value": 0.7}, + {"id": 3, "value": 0.7}, + {"id": 4, "value": 0.7}, {"id": 5, "value": 1.0}, ] @@ -104,7 +104,7 @@ if __name__ == "__main__": # ] # client.set_angles(hand_open, device_id="hand2") - client.set_angles(angles, device_id="hand2") + client.set_angles(hand_open, device_id="hand2") # client.set_angles(handshake, device_id="hand1") # Close client diff --git a/clients/http_server.py b/clients/http_server.py new file mode 100644 index 0000000..9489167 --- /dev/null +++ b/clients/http_server.py @@ -0,0 +1,133 @@ +from __future__ import annotations + +import time +from threading import Lock +from fastapi import FastAPI +from pydantic import BaseModel +from typing import Optional + +from clients.movej_client import MoveJClient, action_music,action_air,action_drive_comfort,action_drive_economy,action_hello + + +app = FastAPI(title="Humanoid Robot Control API (Blocking + Mutex + Ignore)") + +class ActionResponse(BaseModel): + code: int + msg: str + action: Optional[str] = None + ignored: bool = False + +class StatusResponse(BaseModel): + running: bool + current_action: Optional[str] + last_action: Optional[str] + last_finished_at: Optional[float] + + +# 🔒 全局唯一互斥锁:保证同一时间只能执行一个 action +action_lock = Lock() + +# 状态变量(简单可用;多线程更严谨可再加锁,这里够用) +running = False +current_action = None +last_action = None +last_finished_at = None + + +def run_action_blocking_ignore_if_busy(action_func, action_name: str) -> ActionResponse: + """ + 通用执行模板: + - 忙:直接忽略(立即返回,不执行) + - 空闲:阻塞执行,执行完再返回 + """ + global running, current_action, last_action, last_finished_at + + # 忙就忽略(静默丢弃动作) + if not action_lock.acquire(blocking=False): + return ActionResponse( + code=0, + msg=f"{action_name} ignored: robot busy", + action=action_name, + ignored=True, + ) + + client = MoveJClient() + # client = 0 + running = True + current_action = action_name + + try: + action_func(client) # ✅ 阻塞到动作执行结束 + last_action = action_name + last_finished_at = time.time() + return ActionResponse( + code=0, + msg=f"{action_name} finished", + action=action_name, + ignored=False, + ) + except Exception as e: + return ActionResponse( + code=1, + msg=f"{action_name} failed: {e}", + action=action_name, + ignored=False, + ) + finally: + try: + # print("closing action") + client.close() + finally: + running = False + current_action = None + action_lock.release() + + +# @app.post("/action/one", response_model=ActionResponse) +# def call_action_one(): +# return run_action_blocking_ignore_if_busy(action_one, "action_one") + +@app.post("/action/music", response_model=ActionResponse) +def call_action_music(): + return run_action_blocking_ignore_if_busy(action_music, "action_music") + +@app.post("/action/air", response_model=ActionResponse) +def call_action_air(): + return run_action_blocking_ignore_if_busy(action_air, "action_air") + +@app.post("/action/hello", response_model=ActionResponse) +def call_action_hello(): + return run_action_blocking_ignore_if_busy(action_hello, "action_hello") +# @app.post("/action/drive_comfort", response_model=ActionResponse) +# def call_action_drive_comfort(): +# return run_action_blocking_ignore_if_busy(action_drive_comfort, "action_drive_comfort") +# +# @app.post("/action/drive_economy", response_model=ActionResponse) +# def call_action_drive_economy(): +# return run_action_blocking_ignore_if_busy(action_drive_economy, "action_drive_economy") +# +# @app.post("/action/two", response_model=ActionResponse) +# def call_action_two(): +# return run_action_blocking_ignore_if_busy(action_two, "action_two") +# @app.post("/action/two", response_model=ActionResponse) +# def call_action_two(): +# return run_action_blocking_ignore_if_busy(action_two, "action_two") + +@app.get("/status", response_model=StatusResponse) +def get_status(): + return StatusResponse( + running=running, + current_action=current_action, + last_action=last_action, + last_finished_at=last_finished_at, + ) + + +if __name__ == "__main__": + import uvicorn + uvicorn.run( + "http_server:app", + host="0.0.0.0", + port=8000, + reload=False + ) \ No newline at end of file diff --git a/clients/main.py b/clients/main.py new file mode 100644 index 0000000..68da937 --- /dev/null +++ b/clients/main.py @@ -0,0 +1,141 @@ +# import time +# +# from hand_client import DexHandClient +# +# +# from movej_client import MoveJClient +# +# import atexit +# +# hand_open = [ +# {"id": 0, "value": 0.8}, +# {"id": 1, "value": 0.8}, +# {"id": 2, "value": 0.8}, +# {"id": 3, "value": 0.8}, +# {"id": 4, "value": 0.8}, +# {"id": 5, "value": 1.0}, +# ] +# +# +# hand_touch = [ +# {"id": 0, "value": 0}, +# {"id": 1, "value": 0}, +# {"id": 2, "value": 0}, +# {"id": 3, "value": 1.0}, +# {"id": 4, "value": 0.3}, +# {"id": 5, "value": 0.3}, +# ] +# +# handshake = [ +# {"id": 0, "value": 0.0}, +# {"id": 1, "value": 0.0}, +# {"id": 2, "value": 0.0}, +# {"id": 3, "value": 0.0}, +# {"id": 4, "value": 0.0}, +# {"id": 5, "value": 1.0}, +# ] +# +# +# left_joint_list = [ +# +# {'joint_name': 'L_SHOULDER_P', 'rad': -0.230949540675}, +# {'joint_name': 'L_SHOULDER_R', 'rad': -1.0384195613}, +# {'joint_name': 'L_SHOULDER_Y', 'rad': -15.045008286377}, +# {'joint_name': 'L_ELBOW_R', 'rad': -1.615503893099}, +# {'joint_name': 'L_WRIST_P', 'rad': 14.787740913187}, +# {'joint_name': 'L_WRIST_Y', 'rad': -0.353138324696}, +# {'joint_name': 'L_WRIST_R', 'rad': 0.28}, +# ] +# +# right_joint_list = [ +# +# {'joint_name': 'L_SHOULDER_P', 'rad': -0.038843127376}, +# {'joint_name': 'L_SHOULDER_R', 'rad': -0.782479233371}, +# {'joint_name': 'L_SHOULDER_Y', 'rad': -14.639593111463}, +# {'joint_name': 'L_ELBOW_R', 'rad': -2.009983759425}, +# {'joint_name': 'L_WRIST_P', 'rad': 14.79076046324}, +# {'joint_name': 'L_WRIST_Y', 'rad': -0.022087994402}, +# {'joint_name': 'L_WRIST_R', 'rad': 0.28}, +# +# +# ] +# start_joint_list = [ +# {'joint_name': 'L_SHOULDER_P', 'rad': -0.029367758425}, +# {'joint_name': 'L_SHOULDER_R', 'rad': -1.448823970756}, +# {'joint_name': 'L_SHOULDER_Y', 'rad': -14.5604203382}, +# {'joint_name': 'L_ELBOW_R', 'rad': -0.184456443516}, +# {'joint_name': 'L_WRIST_P', 'rad': 14.629440930445}, +# {'joint_name': 'L_WRIST_Y', 'rad': -0.021720636379}, +# {'joint_name': 'L_WRIST_R', 'rad': -0.120802885537}, +# ] +# +# single_joint = [ +# {'joint_name': 'R_SHOULDER_Y', 'rad': 0}, +# ] +# +# +# first_joint_list = [ +# {'joint_name': 'L_SHOULDER_P', 'rad': 0.013117624077}, +# {'joint_name': 'L_SHOULDER_R', 'rad': -1.153729162914}, +# {'joint_name': 'L_SHOULDER_Y', 'rad': -14.255272070875}, +# {'joint_name': 'L_ELBOW_R', 'rad': -1.477644963752}, +# {'joint_name': 'L_WRIST_P', 'rad': 15.28202635377}, +# {'joint_name': 'L_WRIST_Y', 'rad': -0.000359764059}, +# {'joint_name': 'L_WRIST_R', 'rad': 0.124166062475}, +# ] +# +# second_joint_list=[ +# {'joint_name': 'L_SHOULDER_P', 'rad': -0.563525308548}, +# {'joint_name': 'L_SHOULDER_R', 'rad': -1.290596130675}, +# {'joint_name': 'L_SHOULDER_Y', 'rad': -14.162486167364}, +# {'joint_name': 'L_ELBOW_R', 'rad': -1.021621712276}, +# {'joint_name': 'L_WRIST_P', 'rad': 15.432362166456}, +# {'joint_name': 'L_WRIST_Y', 'rad': 0.018426754365}, +# {'joint_name': 'L_WRIST_R', 'rad': -0.005352795583}, +# ] +# +# def action_hello(): +# # client.send(start_joint_list, vel=2.0, acc=2.0) +# hand_client.set_angles(hand_open, device_id="hand1") +# client.send(right_joint_list, vel=2.0, acc=2.0) +# # time.sleep(1) +# while True: +# client.send(right_joint_list, vel=3.0, acc=3.0) +# client.send(left_joint_list, vel=3.0, acc=3.0) +# # client.send(start_joint_list, vel=1.0, acc=1.0) +# +# def action_touch(): +# # client.send(start_joint_list, vel=2.0, acc=2.0) +# hand_client.set_angles(hand_touch, device_id="hand1") +# client.send(first_joint_list, vel=2.0, acc=2.0) +# # time.sleep(1) +# while True: +# client.send(first_joint_list, vel=5.0, acc=3.0) +# client.send(second_joint_list, vel=5.0, acc=3.0) +# # client.send(start_joint_list, vel=1.0, acc=1.0) +# +# +# def cleanup(): +# time.sleep(3) +# hand_client.set_angles(handshake, device_id="hand1") +# client.send(start_joint_list, vel=2.0, acc=2.0) +# if hand_client is not None: +# hand_client.close() +# if client is not None: +# client.close() +# print("程序结束:已执行清理并打印此信息。") +# +# atexit.register(cleanup) +# +# +# if __name__ == "__main__": +# # Initialize client +# global hand_client +# global client +# +# hand_client = DexHandClient() +# client = MoveJClient() +# +# action_touch() +# +# diff --git a/clients/movej_client.py b/clients/movej_client.py index fda57e2..e6c3440 100644 --- a/clients/movej_client.py +++ b/clients/movej_client.py @@ -3,6 +3,8 @@ import time from google.protobuf import timestamp_pb2 +from clients.hand_client import DexHandClient + sys.path.append("../generated") from generated.cmvr.api import humanoid_robot_command_pb2 as pb @@ -13,6 +15,7 @@ import math from typing import List, Dict, Literal + class MoveJClient(RobotClientBase): """Client to send MoveJ commands to the robot""" @@ -29,20 +32,7 @@ class MoveJClient(RobotClientBase): device_id: device ID """ # Construct JointCmd list - # cmds = [pb.JointCmd(joint_name=j["joint_name"], rad=j["rad"], vel=vel) for j in joint_list] - - offset = { - "R_WRIST_Y": -0.0, - } - - cmds = [ - pb.JointCmd( - joint_name=j["joint_name"], - rad=j["rad"] + offset.get(j["joint_name"], 0), - vel=vel - ) - for j in joint_list - ] + cmds = [pb.JointCmd(joint_name=j["joint_name"], rad=j["rad"], vel=vel) for j in joint_list] # Construct request header header = common_pb2.CommandHeader.Request() @@ -73,56 +63,327 @@ class MoveJClient(RobotClientBase): print("MoveJ RPC call failed:", e) -zero_joint_list = [ +# init_joint_list = [ +# {'joint_name': 'R_SHOULDER_P', 'rad': -0.003768504782}, +# {'joint_name': 'R_SHOULDER_R', 'rad': -0.256264020657}, +# {'joint_name': 'R_SHOULDER_Y', 'rad': 2.526736892626}, +# {'joint_name': 'R_ELBOW_R', 'rad': -1.542952107456}, +# {'joint_name': 'R_WRIST_P', 'rad': 0.117851681162}, +# {'joint_name': 'R_WRIST_Y', 'rad': 0.097711538603}, +# {'joint_name': 'R_WRIST_R', 'rad': 0.021115966972}, +# ] - {'joint_name': 'R_WRIST_R', 'rad': 0}, - {'joint_name': 'R_WRIST_Y', 'rad': 0}, - {'joint_name': 'R_WRIST_P', 'rad': 0}, - {'joint_name': 'R_ELBOW_R', 'rad': 0}, - {'joint_name': 'R_SHOULDER_Y', 'rad': 0}, - {'joint_name': 'R_SHOULDER_R', 'rad': 0}, - {'joint_name': 'R_SHOULDER_P', 'rad': 0}, +init_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': -0.062633119026}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.013667237243}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.563999526183}, +{'joint_name': 'R_ELBOW_R', 'rad': -0.275263170082}, +{'joint_name': 'R_WRIST_P', 'rad': 0.21726806475}, +{'joint_name': 'R_WRIST_Y', 'rad': -0.044427538871}, +{'joint_name': 'R_WRIST_R', 'rad': -0.065047050427}, ] start_joint_list = [ - - {'joint_name': 'R_WRIST_R', 'rad': -0.182982265197}, - {'joint_name': 'R_WRIST_Y', 'rad': 0.057211977764}, - {'joint_name': 'R_WRIST_P', 'rad': -2.450283707826}, - {'joint_name': 'R_ELBOW_R', 'rad': 1.691315387916}, - {'joint_name': 'R_SHOULDER_Y', 'rad': 1.741483963795}, - {'joint_name': 'R_SHOULDER_R', 'rad': 1.000908225412}, - {'joint_name': 'R_SHOULDER_P', 'rad': -0.275362840863}, +{'joint_name': 'R_SHOULDER_P', 'rad': 0.212733518819}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.391965314899}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.564591855398}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.503521397093}, +{'joint_name': 'R_WRIST_P', 'rad': 0.217252876821}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.164711187099}, +{'joint_name': 'R_WRIST_R', 'rad': 0.227967960443}, ] -end_joint_list = [ +air_in_joint_list= [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.467093352929}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.397918033661}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.332349442301}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.108740619931}, +{'joint_name': 'R_WRIST_P', 'rad': 0.184619713748}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.165660432636}, +{'joint_name': 'R_WRIST_R', 'rad': 0.013328010806}, +] - {'joint_name': 'R_WRIST_R', 'rad': 0.590444918686}, - {'joint_name': 'R_WRIST_Y', 'rad': 0.133274073403}, - {'joint_name': 'R_WRIST_P', 'rad': -2.832957807407}, - {'joint_name': 'R_ELBOW_R', 'rad': 0.722278081411}, - {'joint_name': 'R_SHOULDER_Y', 'rad': 1.454527987188}, - {'joint_name': 'R_SHOULDER_R', 'rad': 1.319798720377}, - {'joint_name': 'R_SHOULDER_P', 'rad': 0.886766195809}, +air_open_joint_list= [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.562264710474}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.375382944612}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.390867581924}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.143580778878}, +{'joint_name': 'R_WRIST_P', 'rad': 0.19485637762}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.159855796177}, +{'joint_name': 'R_WRIST_R', 'rad': 0.26605484086}, +] + +air_close_joint_list= air_open_joint_list + +go_home_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.451632041621}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.307911521083}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.13536865317}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.294201365225}, +{'joint_name': 'R_WRIST_P', 'rad': 0.378274346518}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.037015483938}, +{'joint_name': 'R_WRIST_R', 'rad': 0.148664191295}, +] + +empty_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.255359389661}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.283898456732}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.498425644483}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.261196097901}, +{'joint_name': 'R_WRIST_P', 'rad': 0.159945974503}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.124704284694}, +{'joint_name': 'R_WRIST_R', 'rad': 0.089323055792}, ] +music_in_joint_list= [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.534755574811}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.370206708698}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.318657524675}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.133308992921}, +{'joint_name': 'R_WRIST_P', 'rad': 0.217250029084}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.151281261241}, +{'joint_name': 'R_WRIST_R', 'rad': 0.087528290167}, +] -if __name__ == "__main__": - # Initialize client - client = MoveJClient() +music_open_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.562264710474}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.375382944612}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.390867581924}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.143580778878}, +{'joint_name': 'R_WRIST_P', 'rad': 0.19485637762}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.149855796177}, +{'joint_name': 'R_WRIST_R', 'rad': 0.25605484086}, +] +music_close_joint_list = music_open_joint_list +set_in_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.494828409031}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.305430193249}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.207381267348}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.228615143333}, +{'joint_name': 'R_WRIST_P', 'rad': 0.262071504853}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.097687807464}, +{'joint_name': 'R_WRIST_R', 'rad': 0.069247461928}, +] +dirve_mode_joint_list = [ +{'joint_name': 'R_SHOULDER_P', 'rad': 0.563493983445}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.162294407962}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.249594216381}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.289937354272}, +{'joint_name': 'R_WRIST_P', 'rad': 0.142454226992}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.000561004112}, +{'joint_name': 'R_WRIST_R', 'rad': 0.167736130893}, +] - R_WRIST_R_joint = [ - {'joint_name': 'R_WRIST_R', 'rad': 0.0}, +dirve_soft_joint_list = [ + +{'joint_name': 'R_SHOULDER_P', 'rad': 0.535399163285}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.308316848927}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.505504168453}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.088469481487}, +{'joint_name': 'R_WRIST_P', 'rad': -0.006021064442}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.165673722074}, +{'joint_name': 'R_WRIST_R', 'rad': 0.062983648315}, +] + +dirve_jie_joint_list = [ + +{'joint_name': 'R_SHOULDER_P', 'rad': 0.511487668206}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.330508311093}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.33301771116}, +{'joint_name': 'R_ELBOW_R', 'rad': -1.139994529239}, +{'joint_name': 'R_WRIST_P', 'rad': 0.228347658658}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.164826995055}, +{'joint_name': 'R_WRIST_R', 'rad': 0.075367851372}, +] + +head_front_joint_list = [ + {'joint_name': 'HEAD_P', 'rad': -0.15311278316}, + {'joint_name': 'HEAD_Y', 'rad': -0.04022955268}, + {'joint_name': 'HEAD_R', 'rad': 0.050031017646}, +] + +head_screen_joint_list = [ + {'joint_name': 'HEAD_P', 'rad': -0.307521160933}, + {'joint_name': 'HEAD_Y', 'rad': -0.474696809681}, + {'joint_name': 'HEAD_R', 'rad': 0.074742644342}, +] + +singal_joint_list = [ +{'joint_name': 'R_WRIST_P', 'rad': 0.217252876821}, +] + +hand_touch = [ + {"id": 0, "value": 0}, + {"id": 1, "value": 0}, + {"id": 2, "value": 0}, + {"id": 3, "value": 1.0}, + {"id": 4, "value": 0.3}, + {"id": 5, "value": 0.3}, +] + +hand_open = [ + {"id": 0, "value": 0.8}, + {"id": 1, "value": 0.8}, + {"id": 2, "value": 0.8}, + {"id": 3, "value": 0.8}, + {"id": 4, "value": 0.8}, + {"id": 5, "value": 1.0}, ] - # client.send(start_joint_list, 2.0, 1.0) - # client.send(start_joint_list,2.0,2.0) - # client.send(end_joint_list, 1.5, 1.5) - while True: - client.send(start_joint_list,1.5,1.5) - client.send(end_joint_list,1.5,1.5) +hello_l_joint_list = [ + # {'joint_name': 'R_SHOULDER_P', 'rad': 0.399221347784}, + # {'joint_name': 'R_SHOULDER_R', 'rad': -0.287301501983}, + # {'joint_name': 'R_SHOULDER_Y', 'rad': 2.066446782461}, + # {'joint_name': 'R_ELBOW_R', 'rad': -2.153093915083}, + # {'joint_name': 'R_WRIST_P', 'rad': 0.005766666638}, + # {'joint_name': 'R_WRIST_Y', 'rad': 0.292756816084}, + # {'joint_name': 'R_WRIST_R', 'rad': -0.466447865964}, +{'joint_name': 'R_SHOULDER_P', 'rad': 0.500229616137}, +{'joint_name': 'R_SHOULDER_R', 'rad': -0.252456596808}, +{'joint_name': 'R_SHOULDER_Y', 'rad': 2.183436548675}, +{'joint_name': 'R_ELBOW_R', 'rad': -2.107785476354}, +{'joint_name': 'R_WRIST_P', 'rad': -0.115909524794}, +{'joint_name': 'R_WRIST_Y', 'rad': 0.10194042747}, +{'joint_name': 'R_WRIST_R', 'rad': -0.283499773607}, +] + +hello_r_joint_list = [ + {'joint_name': 'R_SHOULDER_P', 'rad': 0.406399542535}, + {'joint_name': 'R_SHOULDER_R', 'rad': -0.299956843483}, + {'joint_name': 'R_SHOULDER_Y', 'rad': 2.461169655645}, + {'joint_name': 'R_ELBOW_R', 'rad': -2.049333783919}, + {'joint_name': 'R_WRIST_P', 'rad': 0.185113321427}, + {'joint_name': 'R_WRIST_Y', 'rad': -0.44407319941}, + {'joint_name': 'R_WRIST_R', 'rad': -0.491400683396}, +] + + + + +# + + +def action_hello(client): + hand_client.set_angles(hand_open, device_id="hand2") + client.send(init_joint_list, vel=1.0, acc=1.0) + client.send(hello_l_joint_list, vel=2.0, acc=2.0) + for _ in range(3): + client.send(hello_l_joint_list, vel=3.0, acc=5.0) + time.sleep(0.1) + client.send(hello_r_joint_list, vel=3.0, acc=5.0) + time.sleep(0.1) + client.send(init_joint_list, vel=1.5, acc=1.5) + hand_client.set_angles(hand_open, device_id="hand2") + +def action_air(client): + hand_client.set_angles(hand_touch, device_id="hand2") + client.send(init_joint_list, vel=2.0, acc=2.0) + client.send(head_screen_joint_list, vel=1.0, acc=1.0) + client.send(start_joint_list, vel=1.0, acc=1.0) + client.send(air_in_joint_list, vel=3.0, acc=3.0) + client.send(start_joint_list, vel=3.0, acc=3.0) + # # # # # + # # time.sleep(1) + # # client.send(air_open_joint_list, vel=3.0, acc=3.0) + # # client.send(start_joint_list, vel=3.0, acc=3.0) + time.sleep(1) + client.send(air_close_joint_list, vel=3.0, acc=2.0) + client.send(start_joint_list, vel=3.0, acc=2.0) + time.sleep(1) + client.send(go_home_joint_list, vel=3.0, acc=2.0) + client.send(start_joint_list, vel=3.0, acc=3.0) + client.send(head_front_joint_list, vel=1.0, acc=1.0) + client.send(init_joint_list, vel=2.0, acc=2.0) + hand_client.set_angles(hand_open, device_id="hand2") + +def action_music(client): + # init_joint_list + hand_client.set_angles(hand_touch, device_id="hand2") + client.send(init_joint_list, vel=2.0, acc=2.0) + client.send(head_screen_joint_list, vel=1.0, acc=1.0) + client.send(start_joint_list, vel=1.0, acc=1.0) + client.send(music_in_joint_list, vel=3.0, acc=3.0) + client.send(start_joint_list, vel=3.0, acc=3.0) + # # # + time.sleep(1) + client.send(music_open_joint_list, vel=3.0, acc=3.0) + client.send(start_joint_list, vel=3.0, acc=3.0) + # time.sleep(2) + # client.send(music_close_joint_list, vel=3.0, acc=3.0) + # client.send(start_joint_list, vel=3.0, acc=3.0) + time.sleep(1) + client.send(go_home_joint_list, vel=3.0, acc=2.0) + client.send(start_joint_list, vel=3.0, acc=2.0) + client.send(head_front_joint_list, vel=1.0, acc=1.0) + client.send(init_joint_list, vel=2.0, acc=2.0) + hand_client.set_angles(hand_open, device_id="hand2") +def action_drive_economy(client): + # client.send(head_screen_joint_list, vel=1.0, acc=1.0) + # client.send(start_joint_list, vel=1.0, acc=1.0) + # client.send(set_in_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # # # + time.sleep(1) + # client.send(dirve_mode_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # + # time.sleep(1) + # client.send(dirve_jie_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # time.sleep(2) + # client.send(go_home_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # client.send(head_front_joint_list, vel=1.0, acc=1.0) +def action_drive_comfort(client): + # client.send(head_screen_joint_list, vel=1.0, acc=1.0) + # client.send(start_joint_list, vel=1.0, acc=1.0) + # client.send(set_in_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # # # + time.sleep(1) + # client.send(dirve_mode_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # + # time.sleep(1) + # client.send(dirve_soft_joint_list, vel=3.0, acc=2.0) + # client.send(start_joint_list, vel=3.0, acc=2.0) + # time.sleep(2) + # client.send(go_home_joint_list, vel=3.0, acc=2) + # client.send(start_joint_list, vel=3.0, acc=2) + # client.send(head_front_joint_list, vel=1.0, acc=1.0) + + # client.send(init_joint_list, vel=1.0, acc=1.0) +client = MoveJClient() +hand_client = DexHandClient() +if __name__ == "__main__": + # Initialize client + + # action_air(client) + action_hello(client) + # client.send(head_front_joint_list, vel=1.0, acc=1.0) + # client.send(go_home_joint_list, vel=3.0, acc=3.0) + # action_music(client) + + # action_music(client) + # action_air(client) + # action_one(client) + # action_drive_soft(client) + # action_drive_economy(client) + # action_drive_comfort(client) + # client.send(singal_joint_list, vel=1.0, acc=1.0) + # client.send(start_joint_list, vel=1.0, acc=1.0) + # while True: + # client.send(hello_l_joint_list, vel=1.0, acc=1.0) + # time.sleep(0.1) + # client.send(hello_r_joint_list, vel=1.0, acc=1.0) + # time.sleep(0.1) + # # hello_l_joint_list + + + + # Close client client.close() diff --git a/clients/test.py b/clients/test.py index f424beb..42991ca 100644 --- a/clients/test.py +++ b/clients/test.py @@ -1,5 +1,18 @@ -from google.protobuf import timestamp_pb2 +import requests -timestamp = timestamp_pb2.Timestamp() -timestamp.GetCurrentTime() -print(timestamp) \ No newline at end of file + +#netsh advfirewall firewall add rule name="FastAPI 8000" dir=in action=allow protocol=TCP localport=8000 + +# "http://192.168.0.131:8000/action/one", +resp = requests.post( + "http://127.0.0.1:8000/action/drive_economy", + timeout=80000 +) + + +# resp = requests.post( +# "http://192.168.0.131:8000/action/one", +# timeout=800000 +# ) + +print(resp.json()) diff --git a/generated/__pycache__/__init__.cpython-39.pyc b/generated/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fc2ab7cf07cc9ee2a3b7d00488badb158c4161d GIT binary patch literal 144 zcmYe~<>g`k0#7feOc4DTL?8o3AjbiSi&=m~3PUi1CZpd0hlvt9Q5)&VvnU`4-AFo$Xd5gm)H$SB` NC)EyQ+-D$W000nIAwvKF literal 0 HcmV?d00001 diff --git a/generated/cmvr/__pycache__/__init__.cpython-39.pyc b/generated/cmvr/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..526278d8e6ccfed8cd866b263ef7ce06148945d7 GIT binary patch literal 149 zcmYe~<>g`k0#7feOc4DTL?8o3AjbiSi&=m~3PUi1CZpd0hlvt9Q0#OzppP83g5+AQuPg`k0#7feOc4DTL?8o3AjbiSi&=m~3PUi1CZpd0hlvt9Q0#TM&kQoynpP83g5+AQuPNV%}T zp^JV%7Iqc|`Ul+w=x1=-Rd!t$XwW-D>JgzpMdCW>T2$Z&;FuN{I0`tSB?XQFMp{aiXzD)w zAZZy`7Y8n@<$#NF?mkZv53*LEg`q-{Tas232mvb5(r}HW0Ids@2DBk&Gk`W}akxdY zfXXy^|A-`MeE7I8(;~@{{F~52SlgzV`zLh!K?Yx30|go!rvkh_(-s=(fZdq0B|wEY z5wNx+tnCPE-0seBcL{$o_mT;0Y|dj*{SX1?ck5 zz_te#Jrq2IcsMuWtM2_SqgYPL29X^ za>cKYUks>Er86sXSx1RuN=Z*Qt|6AVGc^p@EMY65tf35L%w{;)Kw)piMfm?*?7fvy zs%DS-=HOCi`bbd_ns9)}`pB<-QYoUOId<`lZcVB15h0K0}#y<3+$0UZN6eImWcpp+kl@Y#!r-ucp7Z4>X~;(N2w zd-Jk+%gJer{vSrEs~ z_bR;J|HH-4Tu5+*n(w$MaM9)BM=t*0g1~t>c;>}1CbogGms{C+2J@1a!iz)7!ko!3 zG2+;=2&WUXoo7*h-QxJNn7?l22z&85?dwy^g&1H8lOBtMqPFh`0%5s$c1*=!-mI9{ z$179`X;WtEmU&0Xv1w6J3~w!HLG0d6U@v>OqI_9eNJQ%P9FKMnt2PTBfW^5AJrQYBlQ%}KHZ57wR z<*b+5uvzwmU#yN-z|Opc7%n;Hdbwqaj>&Hld&cc@@%L%{t1fTW?ibI0ve~txPYl`} zu!(^U%cNts>%W|CrE)l!eH8o^aQ$`{?OmDNdWo<7mi~r!kTV1kk<+s$oCv4G*$9#s kPg)Mip$~~D3Z+9nj>Us_3}*gH6cJw?%=vmT`M;lk0qyi_XaE2J literal 0 HcmV?d00001 diff --git a/generated/cmvr/api/__pycache__/dexhand_command_pb2.cpython-39.pyc b/generated/cmvr/api/__pycache__/dexhand_command_pb2.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca3379f70fc18228207f473a64ecc3994849ce08 GIT binary patch literal 6894 zcmds5TW=f373T7;Atg~OiK6Zlb+P0NCChefD|RA^7fCTC(IlNVgo-W287Y)WF1t&` zvHwK#1N>k=20>7uC<3G{`WyOE6j-27eez3D6fFt_Xwh?qyTheG>7jZkToF3_=A3WN zcXoDmX1L}4e&T??-A}fvxu*`tpRr;83qoTP{`C=`!$BP-2bHL^Ce@uKmxR~_*j@5) z>;~*D`8f6f_LurN_5voQfaG9-H^H}#Qa|+b)duQ=r4aZ$=zB9n{coj`%;eKy+Bfbf zjc`N&jdBzK6lUSmF&YFE;l6%A;~WhDnqU(U9RxJVQ3%i!j}8HvX47VLh9iv5@~8|b z%A#g;jw6i5cyt)hJexP83mjo|kw-@WEwLptdW|EDF7xOppcS@aMz3>((HlG(26U6% zG^4jT!f2dF#{jLeRWrKA5k_yr7_8F>pgSCm1G>xl-rS>o%y;_1vBXB`1f6{CeCsOR zXZ>#;u={T%7-eJ-lQAk74>{wZU<6DCvV$g$SZo#sH1*mAnKyX94c-qmHcmejIr`0h z<5s`YBhG##7y~wyK@(3}Y+h-|^iB!y1fc2HZqR&jEWOU|0KNe>OK-BfoO2iOEjA7~4mL|y*#zJu z=PUw#%$5Lu1Qt2hIOiJYEOX8>;E&k~;7zbunqb!fZ-K>nZg9>Gz)5x!a0)D5*Db*7 zV6!yM;@lqxoMEegx4|N3jdRvG=Qiiu20UAEtn9p+-DVA@m0OHPo0{5ED{3uzbas5q zv}i@8EdCBR)D_7fl<5_%+H9#Bv<5pZrKzelaQW&?*UKjixf(mJu}Z6|Hjt~otRJa0 zg_c|8qq5Ek6}4Vh8%pzNUH_Bc;UF`W`WM=2xmjJM?90!~4XPjmzT>%dMq`Ys^-s&SGbR(_tkQ@Sm6knnKkrF@l43?iL0?*4X2l7~qD-fk+DO)D92r1K%C47}a_RQksu7sBGsv%Rg58@uEZ z*}ae_wnO~l>U_ji+|5BoLcC@INd{*wk%CMi66D>Lwge;$LSM+DVB8(sBf%8=atG#S zd-jCMKvh?&4VVJuTJ;so6P$H^d69T7E>>VDCn;j-9#GipVdsMDGhx^~%Ioc_uyR+y4wd?q3 z@cY+QyS>iX?<6u&5Vhyb$3VC0Kl<*(GAlRP&Y?J?EKm z$xSTTHv5v;qF+skBh9(edDj4|aJo`-XY$(47znN$-;I^{$3S1yhYkU?$Og1BB{d5CstRqbZ}Qp!pWf4`}{{ z<~tXdF*Hxn6wrK+=7k%~9}zu7^m9b75Z&{Dd4T3`X#Rob7hW*GMDr7PZB_j}qFF>g zMH7bOa`jh;#u5Di%*vkOQxvLJ6vY@kQB~N*+NWYT$7@iR!w4vy^STD&4kKjq@DscS ztC7MNz9oif!L<9E*(H4no4)T%2-FZofl)URan>2&H~@6$x~S-R6K6cfdC zDWDY6`-OviDp5=rBMmq?F?ue+u#KYR4}OGHNCQX5oy2~son}ngP8aQ-9cg9Sc+am$UxCsiR6>gBNl<7kTt*T)5gRM9znz8W z#k`2JecOgThAG1+12l-^$%07ERKqR-z+j}ZKa~E0&uHipV5;~(e5jvC6Qkd@P7P)77heg)O?s%b?Pbc=Q-1CvpJ?!gJejkTUF^LJPAvs}6~V)y3~`67CaDe+n%XTDX~Yrh`A-s#)GX@M`#KzrC8{YkaLAO=m3+VRHzLjAj_k2%1qeVK9cQJS(J?Bs|*I zR#AZUO>N>&b=?>^uCf{x3yU$V=wcNTq#?T#ei3OcW69+W`!M|Xw8aJsa4^Hz+wAKKa9s$PptPY?H;f;9`@Ml;?0+a|51B?`v{k4 z{qL|Dxuu}>ars?A*MOTySNQ}br{w&%-$R@>WMZ!uV*m69i4^P=^|gC&)?fX@z(StY Q_x~vB08m+4YXATM literal 0 HcmV?d00001 diff --git a/generated/cmvr/api/__pycache__/dexhand_service_pb2_grpc.cpython-39.pyc b/generated/cmvr/api/__pycache__/dexhand_service_pb2_grpc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41cc4b18529d637cd740e5600b044e268e132ec3 GIT binary patch literal 6977 zcmd5>TW=f372aLmmN$tKb@L?-tae7qG9;Io zT_(1`07c`6zNEh(K<%PHVW6+=Lw`X3LV-cwiUjR@fucf-_B*pnk;{-VjmSk;m@{+c z3}?@obLL!DcCnb#@NB*L9rwrI*0jG6GWsNe+(h&50x+$iF`XGLy`iH|w2XG5k<_(2 z8cVX&1C6D4>Z3#>4Lr>uWq}(PyB#K&vESlY%tI1wIPHZxLyZrw+X4Zok~q{Tsd%Cyynnb2M>)?XzOVH z-vRo16Q>*KO{1A;CRLwmrkU|^qOVyQMNMGVjHqUFNX;rL{U#Stb0gHeqNYGCMAX6v zwWz3RQ0F4*+z54EQ8S>HB5G-bx}c~gsEZMGafDh1b%|v`U5=>BBh(d^!wKh)w${Cl zABdh4c%qieRifvXIP`CvU^MAKsU6wzUZ|zJ9^Qp(C(TVr zy>C13%G{>#+R<$GM91=MOgk=JNq?|$F-DWCLsTi~WZnE2L9PrZl!68ujx1F3qYIUO zCM;C*F*XP487wXj-*%!pxfDD3!O~)ERu*xYpb;zVKb?NOVhI4jvH83o_ygBfR;|`hHmQSzs=NXjE>F?jBMz~YlFAe;pf3Z z$8K}Wk~zz2d#u-@alx|Q>)EY{lCfaOj%A4}U{D>(2&mFr0>DJ`DQud0(oi$ggAa*1 zIrvaGZKT35+DJzMG!ur;hRF)72zr*yv3c}4R$>e2^K20=wJcZ0gbigDg1B;s$H7Bm zYU^nJC4j#1P=mil1bU?Fge93yqaelfkMy4*_TvSK-ZGYc`pZ9j_Q`KQ`^9fQ{rT^Q zE_ijD2k&^S((w@e+T9kXILO%x^~Y&x`aHnxXIv&p^D-B@dPzFQU#|B!+ouRn9G=;knkKp-Voh$7-yHC$eHq?&z!gO;OqNO&71Ph&z!dl;OmD^&6^4c&z!dk`1;8hZ&#kE z)06n~%=x+tNgP?mT$lwK8mZ%V*a}xCC5pI-YQ9k7w2z0moMF0vyX2whp z{{+!vl?XYi0-A~fhOTLW*3|o2(+E(9P{ywMOw(lg$BBrR#hj`!R3E41F{dgF)yHW? z%&Gc9^>Nxf=2Uf|`Z#R?bE>vbeVkUt+)~8nQgcXKh72p9twyxf0gV}-m>(K}_Hd0Q z`o<&U!$e|=@0;FU?@mMSoC=*bIvq~dnJ!fd7Oz0eqlpQ@sqY8oN z2`Gzt0V7$7rH_*sP=-gzf_y&Cns2GR&vgd8$~Bv@lSz^#62h-0DH~9kppa=Ap$IE~ zURqzykL@{P@?`Du61`%w53>S~YCLS+#Y(>cpczR$sq)Gs^2$>f{W*OF`}_x)-W}{t z&MWq0f!##&e+n>~>G336X2|azAgyYofUPimCQ(=#*ec7ioWe4|)>xhu6lMZD!-{N9 zVOd~j**q&LEC=iyTVRU{%L6;l%4|tt1(twOKPTtnCl%%>OVcDNMUMw>LO7&K1C!IKV}t) zBFP^L+XU(azDHn(0M(7+Z34Rl#vCN& zHs>bFKd#o8{9!VWB#^eN*Ej2U{s&lbQtcoMKK&QM33Ibq)6$WHP)9*-{!u9X|I8_VVFjv!x(=45Imoqz0aTffOnduH?gZ+~oT`OX=B9o-=@6v( ZTKGBeb=pGR3#5%kAyK+s`iA++e*shNOA`P9 literal 0 HcmV?d00001 diff --git a/generated/cmvr/api/__pycache__/hlc_command_pb2.cpython-39.pyc b/generated/cmvr/api/__pycache__/hlc_command_pb2.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f420ba8a14d85c729575e9d69cc488d03cf418d GIT binary patch literal 1444 zcmZ`&&2HO95ayDSC{dDS$+E4eZmk3;P#q!%>8%KYw6@&1Kx0>uFNA;v#U06#NiDOa z(%PpyLLVRp>)0UZ1MRgZ_f+)QL(y4Me=txkIQz{vv%9l1J5I4^Y51M}@ZI=*PSgHS z%H~%<GlY>g47d&JjmgD7kuPTA=grx0gsGsbDeSvwcw3}Va96Akirg}G)I zah>UH`6YWBxwPW$$}Br4b_FVv9hQ5f*;S}ccA14}FGhJp`;fb01Alhy%6_6?(|Z zP^Ar4LHU^Nz#if%%ExRM_G5k@@pe~h?%f`K4^t3M1gsGV9&wj@jlpa<1krFggVw!D zZj(rhLFkHc5OIN8X|2(Ka}O!ghcI+TpnL@kJ#eEjpDN$*#vgExGAD8dP8d75-1qsE z27~9}-?+b3cl~$b$O*1ona^RBMR55~>YO-`u~#>Hbe8&XoA1#P2AYPozmH z<1VGLG~#^ZL6S@?z0lD?=IOe`!cffi1``)uq!gW{i^7X^vTj{`kxAA)cmUEofuS?= zB8&k|lnv}vjfIIz>;sho3@@Ts_IO@A7?lQD{+6*Wh_U01Z-JeTJ&5ltcNc-s=q7-W z4sPhw@xji}-udP6YgwJ*y8!mUx|LXIr~T7qyW6u%E4_Ph{-)cO2df6TSoFt_$wTkq zDbidhBCD=i>cD7>hlnM+s*0@8%Wj(<({%y6m^vP)CJAMkhN}zFFmgmBOPdr-*>9To z63>XmKkbum`YK2LXHS3T;yQE!7y2U+VDETim`454va1s}Ok@ASYib2IGW#NVK`&J$ q!xI!KQdkZnYZQ#Fltt7i=mnw^{ojnam@}yTmEA#$vgsMJ9{&MQa;AX* literal 0 HcmV?d00001 diff --git a/generated/cmvr/api/__pycache__/humanoid_robot_command_pb2.cpython-39.pyc b/generated/cmvr/api/__pycache__/humanoid_robot_command_pb2.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14150d66209c55cb04d984c4d6b28fd182ef8112 GIT binary patch literal 5397 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 N$v)vXD1AS_{{bmIo$vqv literal 0 HcmV?d00001 diff --git a/generated/cmvr/api/__pycache__/humanoid_robot_service_pb2_grpc.cpython-39.pyc b/generated/cmvr/api/__pycache__/humanoid_robot_service_pb2_grpc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93203b05f15bb39135876a6abcb0a25ce71de145 GIT binary patch literal 6691 zcmd5=UvC@75x+Z<$KyZ!qh!gF?a+zsgleL&^lG*#ID4;R)PWt71z`4NswKw|9-P~qE0j=(WwNK#Ln*Q-0sfI z&d$uPU8xim{O;ZViTl0Vit=Yd(!VT_J1D`g0GMJbOl4YIHC5D^w${m*S(W;-Xy;5_ zRX$W$j_FSort|z)8PfosX9jRX;ssV<#ixo{M1P5u(O;JRC8n(_^~%o5a@*xzShGD= z3%Gd9Ma^m3LBNBW;|sxquJ19|+pdLvtts(7`+Si%BV&x?@a|G3p)NEL273El} zOM|gxNzH*;NvM?+bwW~gP$v`WWQsZ^sd-SR6Y6w|IwPqDs8w)WXw44RoRgFS`pzZe z&ZWl9vm$g{+PSyvdqF6APUwq9u~Zj&JQfYR>o!Jh+)b?TS&#p0YpbrAGlHWXgcc0ZwcG9v7v@}Sf&sS}Kj_|jeY|PC zy(=et*zq6p`(u5zx_9-2xq>d|?EZM4t?s>f!fe|-yzjeSxDMmxd)H3>`hg$tW_=+l z^*mcVu_TNxkoql#!-p-9b#g-K5Jr{d_(XohZN^2Ee;98-G>vl=@4(0YdMI$HBI7QE z+q9ieqvBoRcaq-1VE-Z`X?juPg*69$AaMi(PawI-tMqOev@LSdB!bp*0^$S5>-N^v#|ENu6 z86~&^(AS3LMLNU1U>QAT<&);UwFj#!Yb(u>k@eS#SmYw z9jmX{U!OT+H8AzdmuKwkHTD{qa)ubYeyqk01*v)Lqb#mtp!g1f zHwoMzK%Pj@kr#Bh1X;2mvk^4{qz*xArksRy7t&KSKzI)&m;sgFqlSqLndv$@VbPv(Nn*r1bmPM8hqS&HQ{eG{fmEnG>eFG>}dlS6Z+jGOE_x=u?R zcc`q;r+W_;=;Hgp1W>fBnw2SG7AfJkX;Dg;8v7^xI_CKg(zEYlcJfJwew4x8K?!~h zkWSBdmd(jm24q2I4%j*Q#z2@3Y+k-G5S9nFAm14XGk~3E6*lpdumZ3}Hp!+WRs^=h zrrC_dO296#Dw~y9nPp(e7o*ux`jXj~)Nb>xBi~ZMEd8iWb|oDFWg>LgpJ{zu;BkE) zat3{^pXulN*}mS-_lF{iWst6X|2+3$%1!_ z;vH0x9@+vPJj(lBdUXiQYI3Kr9Kji~MBJNQvTH^3>H%C;13*r28CK9CEmSd`WRuPk(nvKSzioW5BrLP}KO#NO6`% z?oN`qp8EEbj+RG8vT^09VV-}ytUSl;52bJ~dQJFFy_G-8W0H?S5^)RF@X3*}SRNV~ zkdHhx6u66O$_*fF#r|sKMXYf+JwEl_sgOjYeF3Etamq4=FQ5cuDJ|B(4Uc@MAhG0A zlo3a_=G`WKP%U})<{4s@QAvDM4(QR`iBqR>bHr36I!Nh%0REq&1iu5IlwQjy>Y@MN z%Txb9eS-L{m*cApnRR6BC%!@h8Ycl6YEgWMbbqtOolw4b$?J(suH-DE)Dao)#m{U% WqR9e^Gsx_;vRckey*>4gaqGYJB=R)? literal 0 HcmV?d00001