Skip to content

Commit c79239a

Browse files
Merge pull request #106 from pollen-robotics/105-add-factory-reset-option
Add factory reset instr.
2 parents bcbd38f + fdadb5a commit c79239a

File tree

7 files changed

+112
-3
lines changed

7 files changed

+112
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustypot"
3-
version = "1.3.0"
3+
version = "1.4.0"
44
edition = "2021"
55
license = "Apache-2.0"
66
authors = ["Pollen Robotics"]

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Version 1.4.0
2+
3+
- Add support for factory reset in core library and python bindings.
4+
15
## Version 1.3.0
26

37
- Add reboot support in core library.

src/dynamixel_protocol/mod.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,30 @@ impl DynamixelProtocolHandler {
129129
}
130130
}
131131

132+
/// Factory reset instruction.
133+
///
134+
/// Reset the Control Table of DYNAMIXEL to the factory default values.
135+
/// Please note that conserving ID and/or Baudrate is only supported on protocol v2.
136+
pub fn factory_reset(
137+
&self,
138+
serial_port: &mut dyn serialport::SerialPort,
139+
id: u8,
140+
conserve_id_only: bool,
141+
conserve_id_and_baudrate: bool,
142+
) -> Result<()> {
143+
match &self.protocol {
144+
ProtocolKind::V1(p) => {
145+
if conserve_id_only || conserve_id_and_baudrate {
146+
return Err(Box::new(CommunicationErrorKind::Unsupported));
147+
}
148+
p.factory_reset(serial_port, id, conserve_id_only, conserve_id_and_baudrate)
149+
}
150+
ProtocolKind::V2(p) => {
151+
p.factory_reset(serial_port, id, conserve_id_only, conserve_id_and_baudrate)
152+
}
153+
}
154+
}
155+
132156
/// Reads raw register bytes.
133157
///
134158
/// Sends a read instruction to the motor and wait for the status packet in response.
@@ -350,6 +374,20 @@ trait Protocol<P: Packet> {
350374
Ok(self.read_status_packet(port, id).is_ok())
351375
}
352376

377+
fn factory_reset(
378+
&self,
379+
port: &mut dyn SerialPort,
380+
id: u8,
381+
conserve_id_only: bool,
382+
conserve_id_and_baudrate: bool,
383+
) -> Result<()> {
384+
self.send_instruction_packet(
385+
port,
386+
P::factory_reset_packet(id, conserve_id_only, conserve_id_and_baudrate).as_ref(),
387+
)?;
388+
self.read_status_packet(port, id).map(|_| ())
389+
}
390+
353391
fn read(&self, port: &mut dyn SerialPort, id: u8, addr: u8, length: u8) -> Result<Vec<u8>> {
354392
self.send_instruction_packet(port, P::read_packet(id, addr, length).as_ref())?;
355393
self.read_status_packet(port, id)

src/dynamixel_protocol/packet.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ pub trait Packet {
1111

1212
fn ping_packet(id: u8) -> Box<dyn InstructionPacket<Self>>;
1313
fn reboot_packet(id: u8) -> Box<dyn InstructionPacket<Self>>;
14+
fn factory_reset_packet(
15+
id: u8,
16+
conserve_id_only: bool,
17+
conserve_id_and_baudrate: bool,
18+
) -> Box<dyn InstructionPacket<Self>>;
1419

1520
fn read_packet(id: u8, addr: u8, length: u8) -> Box<dyn InstructionPacket<Self>>;
1621
fn write_packet(id: u8, addr: u8, data: &[u8]) -> Box<dyn InstructionPacket<Self>>;

src/dynamixel_protocol/v1.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ impl Packet for PacketV1 {
3131
})
3232
}
3333

34+
fn factory_reset_packet(
35+
id: u8,
36+
_conserve_id_only: bool,
37+
_conserve_id_and_baudrate: bool,
38+
) -> Box<dyn InstructionPacket<Self>> {
39+
Box::new(InstructionPacketV1 {
40+
id,
41+
instruction: InstructionKindV1::FactoryReset,
42+
params: vec![],
43+
})
44+
}
45+
3446
fn read_packet(id: u8, addr: u8, length: u8) -> Box<dyn InstructionPacket<Self>> {
3547
Box::new(InstructionPacketV1 {
3648
id,
@@ -230,6 +242,7 @@ pub(crate) enum InstructionKindV1 {
230242
Ping,
231243
Read,
232244
Write,
245+
FactoryReset,
233246
Reboot,
234247
SyncWrite,
235248
SyncRead,
@@ -241,6 +254,7 @@ impl InstructionKindV1 {
241254
InstructionKindV1::Ping => 0x01,
242255
InstructionKindV1::Read => 0x02,
243256
InstructionKindV1::Write => 0x03,
257+
InstructionKindV1::FactoryReset => 0x06,
244258
InstructionKindV1::Reboot => 0x08,
245259
InstructionKindV1::SyncRead => 0x82,
246260
InstructionKindV1::SyncWrite => 0x83,

src/dynamixel_protocol/v2.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,26 @@ impl Packet for PacketV2 {
4747
})
4848
}
4949

50+
fn factory_reset_packet(
51+
id: u8,
52+
conserve_id_only: bool,
53+
conserve_id_and_baudrate: bool,
54+
) -> Box<dyn InstructionPacket<Self>> {
55+
// See https://emanual.robotis.com/docs/en/dxl/protocol2/
56+
let param = match (conserve_id_only, conserve_id_and_baudrate) {
57+
(false, false) => 0xFF,
58+
(true, false) => 0x01,
59+
(true, true) => 0x02,
60+
(false, true) => 0x02, // Same as (true, true)
61+
};
62+
63+
Box::new(InstructionPacketV2 {
64+
id,
65+
instruction: InstructionKindV2::FactoryReset,
66+
params: vec![param],
67+
})
68+
}
69+
5070
fn read_packet(id: u8, addr: u8, length: u8) -> Box<dyn InstructionPacket<Self>> {
5171
Box::new(InstructionPacketV2 {
5272
id,
@@ -222,6 +242,7 @@ pub(crate) enum InstructionKindV2 {
222242
Ping,
223243
Read,
224244
Write,
245+
FactoryReset,
225246
Reboot,
226247
SyncRead,
227248
SyncWrite,
@@ -233,6 +254,7 @@ impl InstructionKindV2 {
233254
InstructionKindV2::Ping => 0x01,
234255
InstructionKindV2::Read => 0x02,
235256
InstructionKindV2::Write => 0x03,
257+
InstructionKindV2::FactoryReset => 0x06,
236258
InstructionKindV2::Reboot => 0x08,
237259
InstructionKindV2::SyncRead => 0x82,
238260
InstructionKindV2::SyncWrite => 0x83,

src/servo/servo_macro.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ macro_rules! generate_servo {
4141
use pyo3_stub_gen::derive::*;
4242

4343
$crate::generate_protocol_constructor!($servo_name, $protocol);
44-
$crate::generate_ping_reboot!($servo_name);
44+
$crate::generate_special_instructions!($servo_name);
4545
$crate::generate_addr_read_write!($servo_name);
4646

4747
$(
@@ -119,7 +119,7 @@ macro_rules! generate_protocol_constructor {
119119
}
120120

121121
#[macro_export]
122-
macro_rules! generate_ping_reboot {
122+
macro_rules! generate_special_instructions {
123123
($servo_macro:ident) => {
124124
paste::paste! {
125125
impl [<$servo_macro:camel Controller>] {
@@ -134,6 +134,17 @@ macro_rules! generate_ping_reboot {
134134
let serial_port = self.serial_port.as_mut().unwrap().as_mut();
135135
dph.reboot(serial_port, id)
136136
}
137+
138+
pub fn factory_reset(
139+
&mut self,
140+
id: u8,
141+
conserve_id_only: bool,
142+
conserve_id_and_baudrate: bool,
143+
) -> $crate::Result<()> {
144+
let dph = self.dph.as_ref().unwrap();
145+
let serial_port = self.serial_port.as_mut().unwrap().as_mut();
146+
dph.factory_reset(serial_port, id, conserve_id_only, conserve_id_and_baudrate)
147+
}
137148
}
138149
}
139150
};
@@ -262,6 +273,21 @@ macro_rules! generate_addr_read_write {
262273
self.0.lock().unwrap().reboot(id)
263274
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))
264275
}
276+
277+
#[pyo3(signature = (
278+
id,
279+
conserve_id_only = true,
280+
conserve_id_and_baudrate = true
281+
))]
282+
pub fn factory_reset(
283+
&self,
284+
id: u8,
285+
conserve_id_only: bool,
286+
conserve_id_and_baudrate: bool,
287+
) -> PyResult<()> {
288+
self.0.lock().unwrap().factory_reset(id, conserve_id_only, conserve_id_and_baudrate)
289+
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))
290+
}
265291
}
266292
}
267293
};

0 commit comments

Comments
 (0)