Skip to content

Commit ff5baff

Browse files
authored
Implements new Parameter Dump to API (#59)
* added actuator parameter dump api
1 parent 9fff821 commit ff5baff

8 files changed

Lines changed: 86 additions & 6 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ members = [
77
]
88

99
[workspace.package]
10-
version = "0.7.5"
10+
version = "0.7.7"
1111
authors = [
1212
"Benjamin Bolte <ben@kscale.dev>",
1313
"Denys Bezmenov <denys@kscale.dev>",
1414
"Jingxiang Mo <jx@kscale.dev>",
1515
"Pawel Budzianowski <pawel@kscale.dev>",
1616
"Wesley Maa <wesley@kscale.dev>",
17+
"Scott Carlson <scott@kscale.dev>",
1718
]
1819
edition = "2021"
1920
license = "MIT"

kos-py/pykos/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""KOS Python client."""
22

3-
__version__ = "0.7.6"
3+
__version__ = "0.7.7"
44

55
from . import services
66
from .client import KOS

kos-py/pykos/services/actuator.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,18 @@ async def zero_actuators(
378378
actuator_id=actuator_id,
379379
zero_position=True,
380380
)
381+
382+
async def parameter_dump(
383+
self,
384+
actuator_ids: list[int],
385+
) -> actuator_pb2.ParameterDumpResponse:
386+
"""Fetch parameters for specified actuators.
387+
388+
Args:
389+
actuator_ids: List of actuator IDs to query.
390+
391+
Returns:
392+
A ParameterDumpResponse containing parameter maps for each actuator.
393+
"""
394+
request = actuator_pb2.ParameterDumpRequest(actuator_ids=actuator_ids)
395+
return await self.stub.ParameterDump(request)

kos-stub/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ eyre = "0.6"
1414
uuid = { version = "1", features = ["v4"] }
1515
tokio = { version = "1", features = ["full"] }
1616
tracing = "0.1"
17+
prost-types = "0.13.5"

kos-stub/src/actuator.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ use kos::{
99
},
1010
kos_proto::{actuator::*, common::ActionResult},
1111
};
12+
use prost_types::{Struct, Value};
1213
use std::sync::mpsc::{channel, Sender};
1314
use std::sync::Arc;
1415
use std::thread;
1516
use tokio::runtime::Runtime;
1617
use tokio::time::Duration;
1718
use tracing::debug;
18-
1919
pub struct StubActuator {
2020
operations: Arc<OperationsServiceImpl>,
2121
calibration_tx: Sender<u32>,
@@ -128,4 +128,23 @@ impl Actuator for StubActuator {
128128
faults: vec![],
129129
}])
130130
}
131+
132+
async fn get_parameters(&self, actuator_ids: Vec<u32>) -> Result<Vec<(u32, Struct)>> {
133+
let dummy_struct = Struct {
134+
fields: vec![
135+
("model".to_string(), Value::from("stub")),
136+
("firmware_version".to_string(), Value::from("0.0.1")),
137+
("max_torque".to_string(), Value::from(0.5)),
138+
]
139+
.into_iter()
140+
.collect(),
141+
};
142+
143+
let results = actuator_ids
144+
.into_iter()
145+
.map(|id| (id, dummy_struct.clone()))
146+
.collect();
147+
148+
Ok(results)
149+
}
131150
}

kos/proto/kos/actuator.proto

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package kos.actuator;
44

55
import "google/protobuf/empty.proto";
66
import "google/longrunning/operations.proto";
7+
import "google/protobuf/struct.proto";
78
import "kos/common.proto";
89

910
option go_package = "kos/actuator;actuator";
@@ -28,6 +29,9 @@ service ActuatorService {
2829

2930
// Retrieves the state of multiple actuators.
3031
rpc GetActuatorsState(GetActuatorsStateRequest) returns (GetActuatorsStateResponse);
32+
33+
// Retrieves all available parameters for specified actuators.
34+
rpc ParameterDump(ParameterDumpRequest) returns (ParameterDumpResponse);
3135
}
3236

3337
// Message representing a command to an actuator.
@@ -104,3 +108,16 @@ message ActuatorStateResponse {
104108
optional float current = 8; // Current in amperes
105109
repeated string faults = 9; // Faults
106110
}
111+
112+
message ParameterDumpRequest {
113+
repeated uint32 actuator_ids = 1; // Actuators to query
114+
}
115+
116+
message ParameterDumpResponse {
117+
repeated ParameterDumpEntry entries = 1; // One entry per actuator
118+
}
119+
120+
message ParameterDumpEntry {
121+
uint32 actuator_id = 1; // Actuator ID
122+
google.protobuf.Struct parameters = 2; // Generic parameter dump (key-value map)
123+
}

kos/src/hal.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ pub trait Actuator: Send + Sync {
2525
&self,
2626
actuator_ids: Vec<u32>,
2727
) -> Result<Vec<ActuatorStateResponse>>;
28+
async fn get_parameters(
29+
&self,
30+
actuator_ids: Vec<u32>,
31+
) -> Result<Vec<(u32, prost_types::Struct)>>;
2832
}
2933

3034
#[async_trait]

kos/src/services/actuator.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::telemetry::Telemetry;
77
use crate::telemetry_types::{ActuatorCommand, ActuatorState};
88
use std::sync::Arc;
99
use tonic::{Request, Response, Status};
10-
use tracing::trace;
10+
use tracing::{trace, warn};
1111

1212
pub struct ActuatorServiceImpl {
1313
actuator: Arc<dyn Actuator>,
@@ -49,7 +49,7 @@ impl ActuatorService for ActuatorServiceImpl {
4949
.publish("actuator/command", &telemetry_commands)
5050
.await
5151
{
52-
tracing::warn!("Failed to publish telemetry: {}", e);
52+
warn!("Failed to publish telemetry: {}", e);
5353
}
5454
}
5555

@@ -99,7 +99,7 @@ impl ActuatorService for ActuatorServiceImpl {
9999
let telemetry = Telemetry::get().await;
100100
if let Some(telemetry) = telemetry {
101101
if let Err(e) = telemetry.publish("actuator/state", &telemetry_states).await {
102-
tracing::warn!("Failed to publish telemetry: {}", e);
102+
warn!("Failed to publish telemetry: {}", e);
103103
}
104104
}
105105

@@ -110,4 +110,27 @@ impl ActuatorService for ActuatorServiceImpl {
110110
);
111111
Ok(Response::new(GetActuatorsStateResponse { states }))
112112
}
113+
114+
async fn parameter_dump(
115+
&self,
116+
request: Request<ParameterDumpRequest>,
117+
) -> Result<Response<ParameterDumpResponse>, Status> {
118+
let ids = request.into_inner().actuator_ids;
119+
120+
let results = self
121+
.actuator
122+
.get_parameters(ids)
123+
.await
124+
.map_err(|e| Status::internal(format!("Failed to dump parameters: {:?}", e)))?;
125+
126+
let entries = results
127+
.into_iter()
128+
.map(|(actuator_id, parameters)| ParameterDumpEntry {
129+
actuator_id,
130+
parameters: Some(parameters),
131+
})
132+
.collect();
133+
134+
Ok(Response::new(ParameterDumpResponse { entries }))
135+
}
113136
}

0 commit comments

Comments
 (0)