Skip to content

Commit

Permalink
bump version to v3.0.14 (#87)
Browse files Browse the repository at this point in the history
カチャカソフトウェア
[v3.0.14](https://kachaka.zendesk.com/hc/ja/articles/9738402154639-%E3%82%AB%E3%83%81%E3%83%A3%E3%82%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%AE%E3%81%8A%E7%9F%A5%E3%82%89%E3%81%9B-Ver-3-0-14)
に合わせてカチャカAPIを更新します。

変更点は、以下です。

新機能として、以下をサポートします。

- GetBatteryInfo: バッテリー情報の取得
- GetTofCameraXXX: ToFセンサ画像/情報の取得
- SwitchMap: マップの切り替え
- SetFront/BackTorchIntensity: フロント・バックLEDライトの点灯
- ActivateLaserScan: LiDAR強制起動
- MoveForwardCommand: 前進コマンド
- RotateInPlaceCommand: その場回転コマンド
  • Loading branch information
kmurase-pfr committed May 16, 2024
1 parent 0f87b19 commit 60280ed
Show file tree
Hide file tree
Showing 17 changed files with 949 additions and 150 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@

![kachaka-api](docs/images/kachka-api.png)

## 前提条件

* カチャカ本体内で動作するJupyterLabに関しては、ブラウザのみ用意すれば使用する事ができます。
## 対応環境・言語

* カチャカ本体内で動作するJupyterLabを利用することで、OSを問わずWebブラウザのみ用意すれば開発を行うことができます。
* 対応ブラウザについては、[JupyterLab公式ドキュメント](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html#supported-browsers)をご確認ください。
* カチャカの外部から本書の手順に従ってカチャカAPIを使用する場合には、以下の条件に準拠したソフトウェアをインストールしたPCが必要となります
* OS
* Ubuntu 22.04 LTS
* カチャカ外部のPCからAPIを利用することも可能で、本ドキュメントの内容は以下の環境にて確認していますが、多くはmacOSやWindowsなど他の環境でも可能です
* 動作確認済みのOS
* Ubuntu 22.04 LTS
* 開発言語
* Python3.10
* ROS 2(使用する場合)
Expand Down
83 changes: 83 additions & 0 deletions protos/kachaka-api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ message TwistWithCovariance {
repeated double covariance = 2;
}

enum PowerSupplyStatus {
POWER_SUPPLY_STATUS_UNSPECIFIED = 0;
POWER_SUPPLY_STATUS_CHARGING = 1;
POWER_SUPPLY_STATUS_DISCHARGING = 2;
POWER_SUPPLY_STATUS_NOT_CHARGING = 3;
POWER_SUPPLY_STATUS_FULL = 4;
}

message Map {
bytes data = 1; // uint8[]
string name = 2;
Expand Down Expand Up @@ -242,6 +250,8 @@ message Command {
SpeakCommand speak_command = 12;
MoveToPoseCommand move_to_pose_command = 13;
LockCommand lock_command = 15;
MoveForwardCommand move_forward_command = 16;
RotateInPlaceCommand rotate_in_place_command = 17;
}
}

Expand Down Expand Up @@ -285,6 +295,14 @@ message LockCommand {
double duration_sec = 1;
}

message MoveForwardCommand {
double distance_meter = 1;
}

message RotateInPlaceCommand {
double angle_radian = 1;
}

enum CommandState {
COMMAND_STATE_UNSPECIFIED = 0;
COMMAND_STATE_PENDING = 1; // No command is running. Waiting for requests.
Expand Down Expand Up @@ -314,6 +332,12 @@ message GetRobotPoseResponse {
Pose pose = 2;
}

message GetBatteryInfoResponse {
Metadata metadata = 1;
double remaining_percentage = 2; // [0, 100]
PowerSupplyStatus power_supply_status = 3;
}

message GetPngMapResponse {
Metadata metadata = 1;
Map map = 2;
Expand Down Expand Up @@ -376,11 +400,29 @@ message GetBackCameraRosCompressedImageResponse {
RosCompressedImage image = 2;
}

message GetTofCameraRosCameraInfoResponse {
Metadata metadata = 1;
RosCameraInfo camera_info = 2;
}

message GetTofCameraRosImageResponse {
Metadata metadata = 1;
RosImage image = 2;
bool is_available = 3;
}

message GetTofCameraRosCompressedImageResponse {
Metadata metadata = 1;
RosCompressedImage image = 2;
bool is_available = 3;
}

message StartCommandRequest {
Command command = 1;
bool cancel_all = 2;
string tts_on_success = 3;
string title = 4;
bool deferrable = 5;
}

message StartCommandResponse {
Expand Down Expand Up @@ -462,6 +504,22 @@ message GetManualControlEnabledResponse {
bool enabled = 2;
}

message SetFrontTorchIntensityRequest {
int32 intensity = 1; // [0, 255]
}

message SetFrontTorchIntensityResponse {
Result result = 1;
}

message SetBackTorchIntensityRequest {
int32 intensity = 1; // [0, 255]
}

message SetBackTorchIntensityResponse {
Result result = 1;
}

message SetRobotVelocityRequest {
double linear = 1; // [-1, 1]
double angular = 2; // [-1, 1]
Expand All @@ -471,6 +529,14 @@ message SetRobotVelocityResponse {
Result result = 1;
}

message ActivateLaserScanRequest {
double duration_sec = 1;
}

message ActivateLaserScanResponse {
Result result = 1;
}

message GetStaticTransformResponse {
Metadata metadata = 1;
repeated RosTransformStamped transforms = 2;
Expand Down Expand Up @@ -545,11 +611,21 @@ message GetHistoryListResponse {
repeated History histories = 2;
}

message SwitchMapRequest {
string map_id = 1;
Pose initial_pose = 2; // use the charger pose if the message is empty
}

message SwitchMapResponse {
Result result = 1;
}

// Services
service KachakaApi {
rpc GetRobotSerialNumber (GetRequest) returns (GetRobotSerialNumberResponse);
rpc GetRobotVersion (GetRequest) returns (GetRobotVersionResponse);
rpc GetRobotPose (GetRequest) returns (GetRobotPoseResponse);
rpc GetBatteryInfo (GetRequest) returns (GetBatteryInfoResponse);
rpc GetPngMap (GetRequest) returns (GetPngMapResponse);
rpc GetObjectDetection (GetRequest) returns (GetObjectDetectionResponse);
rpc GetObjectDetectionFeatures (GetRequest) returns (GetObjectDetectionFeaturesResponse);
Expand All @@ -562,6 +638,9 @@ service KachakaApi {
rpc GetBackCameraRosCameraInfo (GetRequest) returns (GetBackCameraRosCameraInfoResponse);
rpc GetBackCameraRosImage (GetRequest) returns (GetBackCameraRosImageResponse);
rpc GetBackCameraRosCompressedImage (GetRequest) returns (GetBackCameraRosCompressedImageResponse);
rpc GetTofCameraRosCameraInfo (GetRequest) returns (GetTofCameraRosCameraInfoResponse);
rpc GetTofCameraRosImage (GetRequest) returns (GetTofCameraRosImageResponse);
rpc GetTofCameraRosCompressedImage (GetRequest) returns (GetTofCameraRosCompressedImageResponse);
rpc StartCommand (StartCommandRequest) returns (StartCommandResponse);
rpc CancelCommand (EmptyRequest) returns (CancelCommandResponse);
rpc GetCommandState (GetRequest) returns (GetCommandStateResponse);
Expand All @@ -575,7 +654,10 @@ service KachakaApi {
rpc GetAutoHomingEnabled (GetRequest) returns (GetAutoHomingEnabledResponse);
rpc SetManualControlEnabled (SetManualControlEnabledRequest) returns (SetManualControlEnabledResponse);
rpc GetManualControlEnabled (GetRequest) returns (GetManualControlEnabledResponse);
rpc SetFrontTorchIntensity (SetFrontTorchIntensityRequest) returns (SetFrontTorchIntensityResponse);
rpc SetBackTorchIntensity (SetBackTorchIntensityRequest) returns (SetBackTorchIntensityResponse);
rpc SetRobotVelocity (SetRobotVelocityRequest) returns (SetRobotVelocityResponse);
rpc ActivateLaserScan (ActivateLaserScanRequest) returns (ActivateLaserScanResponse);
rpc GetMapList (GetRequest) returns (GetMapListResponse);
rpc GetCurrentMapId (GetRequest) returns (GetCurrentMapIdResponse);
rpc LoadMapPreview (LoadMapPreviewRequest) returns (LoadMapPreviewResponse);
Expand All @@ -584,4 +666,5 @@ service KachakaApi {
rpc GetHistoryList (GetRequest) returns (GetHistoryListResponse);
rpc GetStaticTransform (GetRequest) returns (GetStaticTransformResponse);
rpc GetDynamicTransform (EmptyRequest) returns (stream GetDynamicTransformResponse);
rpc SwitchMap (SwitchMapRequest) returns (SwitchMapResponse);
}
64 changes: 47 additions & 17 deletions python/demos/get_laser_scan.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,55 @@
"client = kachaka_api.aio.KachakaApiClient()\n",
"await client.set_manual_control_enabled(True)\n",
"\n",
"async for scan in client.ros_laser_scan.stream():\n",
" clear_output(wait=True)\n",
" fig = plt.figure(figsize=(5, 5))\n",
"\n",
" n = len(scan.ranges)\n",
" x = list(range(n))\n",
" y = list(range(n))\n",
" for i in range(n):\n",
" theta = scan.angle_min + scan.angle_increment * i\n",
" x[i] = scan.ranges[i] * math.cos(theta)\n",
" y[i] = scan.ranges[i] * math.sin(theta)\n",
"async def get_and_show_laser_scan_loop():\n",
" async for scan in client.ros_laser_scan.stream():\n",
" clear_output(wait=True)\n",
" fig = plt.figure(figsize=(5, 5))\n",
"\n",
" plt.plot(0, 0, \"o\", color=\"black\")\n",
" plt.plot(x, y, \".\")\n",
" plt.xlim(-6.0, 6.0)\n",
" plt.ylim(-6.0, 6.0)\n",
" plt.grid(True)\n",
" plt.gca().set_aspect(\"equal\", adjustable=\"box\")\n",
" plt.show()"
" n = len(scan.ranges)\n",
" x = list(range(n))\n",
" y = list(range(n))\n",
" for i in range(n):\n",
" theta = scan.angle_min + scan.angle_increment * i\n",
" x[i] = scan.ranges[i] * math.cos(theta)\n",
" y[i] = scan.ranges[i] * math.sin(theta)\n",
"\n",
" plt.plot(0, 0, \"o\", color=\"black\")\n",
" plt.plot(x, y, \".\")\n",
" plt.xlim(-6.0, 6.0)\n",
" plt.ylim(-6.0, 6.0)\n",
" plt.grid(True)\n",
" plt.gca().set_aspect(\"equal\", adjustable=\"box\")\n",
" plt.show()\n",
"\n",
"\n",
"await get_and_show_laser_scan_loop()"
]
},
{
"cell_type": "markdown",
"id": "d43ec70a-3f57-4b72-9ba8-097f9d87b361",
"metadata": {},
"source": [
"上記の方法は、手動操縦モードをONにすることでLiDARを動かしており、カチャカが動かずしばらく経つとスキャンが止まります。\n",
"以下のようにActivatorを使うことで、カチャカが静止している状態でもスキャンを継続することができます。\n",
"\n",
"ただし**必要以上にスキャンを動かし続けると、LiDARの製品寿命を大幅に縮めることになります**ので、ご注意下さい。"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4c65434b-bc3b-4d19-9c7f-247e7668dcf1",
"metadata": {},
"outputs": [],
"source": [
"from kachaka_api.util.vision import LaserScanActivator\n",
"\n",
"activator = LaserScanActivator()\n",
"with activator.activate():\n",
" await get_and_show_laser_scan_loop()"
]
}
],
Expand Down
27 changes: 27 additions & 0 deletions python/kachaka_api/aio/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,33 @@ async def get_back_camera_ros_compressed_image(
)
return response.image

async def get_tof_camera_ros_camera_info(self) -> pb2.RosCameraInfo:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosCameraInfoResponse = (
await self.stub.GetTofCameraRosCameraInfo(request)
)
return response.camera_info

async def get_tof_camera_ros_image(self) -> pb2.RosImage:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosImageResponse = (
await self.stub.GetTofCameraRosImage(request)
)
if not response.is_available:
raise Exception("tof is not available on charger.")
return response.image

async def get_tof_camera_ros_compressed_image(
self,
) -> pb2.RosCompressedImage:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosCompressedImageResponse = (
await self.stub.GetTofCameraRosCompressedImage(request)
)
if not response.is_available:
raise Exception("tof is not available on charger.")
return response.image

async def start_command(
self,
command: pb2.Command,
Expand Down
27 changes: 27 additions & 0 deletions python/kachaka_api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,33 @@ def get_back_camera_ros_compressed_image(
)
return response.image

def get_tof_camera_ros_camera_info(self) -> pb2.RosCameraInfo:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosCameraInfoResponse = (
self.stub.GetTofCameraRosCameraInfo(request)
)
return response.camera_info

def get_tof_camera_ros_image(self) -> pb2.RosImage:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosImageResponse = (
self.stub.GetTofCameraRosImage(request)
)
if not response.is_available:
raise Exception("tof is not available on charger.")
return response.image

def get_tof_camera_ros_compressed_image(
self,
) -> pb2.RosCompressedImage:
request = pb2.GetRequest()
response: pb2.GetTofCameraRosCompressedImageResponse = (
self.stub.GetTofCameraRosCompressedImage(request)
)
if not response.is_available:
raise Exception("tof is not available on charger.")
return response.image

def start_command(
self,
command: pb2.Command,
Expand Down
232 changes: 127 additions & 105 deletions python/kachaka_api/generated/kachaka_api_pb2.py

Large diffs are not rendered by default.

Loading

0 comments on commit 60280ed

Please sign in to comment.