commit
7122cf9deb
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="C:\ProgramData\anaconda3" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="C:\ProgramData\anaconda3" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/teleoperator.iml" filepath="$PROJECT_DIR$/.idea/teleoperator.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,7 @@
|
|||||||
|
from rmd_dx8.rmd_x8 import RMD_X8
|
||||||
|
|
||||||
|
# Setup a new RMD_X8 motor with its identifier.
|
||||||
|
robot = RMD_X8(0x141)
|
||||||
|
|
||||||
|
# Read the motor's current PID parameters.
|
||||||
|
robot.read_pid()
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,481 @@
|
|||||||
|
# RMD-X8 Python Library
|
||||||
|
# Copyright 2022 Sanjay Sunil
|
||||||
|
|
||||||
|
import can
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class RMD_X8:
|
||||||
|
"""
|
||||||
|
A class to read and write on the RMD-X8 motor.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
bus : type
|
||||||
|
the can bus channel used to communicate with the motor
|
||||||
|
identifier : type
|
||||||
|
the motor's identifier on the can bus
|
||||||
|
|
||||||
|
Methods
|
||||||
|
-------
|
||||||
|
setup():
|
||||||
|
Setup the can bus connection.
|
||||||
|
send_cmd(data, delay):
|
||||||
|
Send a frame data to the motor.
|
||||||
|
read_pid():
|
||||||
|
Read the motor's current PID parameters.
|
||||||
|
write_pid_ram(data):
|
||||||
|
Write PID parameters to the RAM.
|
||||||
|
write_pid_rom(data):
|
||||||
|
Write PID parameters to the ROM.
|
||||||
|
read_acceleration():
|
||||||
|
Read the motor's acceleration data.
|
||||||
|
write_acceleration_ram(data):
|
||||||
|
Write the acceleration to the RAM of the motor.
|
||||||
|
read_encoder():
|
||||||
|
Read the current position of the encoder.
|
||||||
|
write_encoder_offset(data):
|
||||||
|
Set the motor's encoder offset.
|
||||||
|
write_motor_zero_rom():
|
||||||
|
Write the current position of the motor to the ROM
|
||||||
|
as the motor zero position.
|
||||||
|
read_multi_turns_angle():
|
||||||
|
Read the multi-turn angle of the motor.
|
||||||
|
read_single_turn_angle():
|
||||||
|
Read the single circle angle of the motor.
|
||||||
|
motor_off():
|
||||||
|
Turn off the motor, while clearing the motor operating
|
||||||
|
status and previously received control commands.
|
||||||
|
motor_stop():
|
||||||
|
Stop the motor, but do not clear the operating state and
|
||||||
|
previously received control commands.
|
||||||
|
motor_running():
|
||||||
|
Resume motor operation from the motor stop command.
|
||||||
|
read_motor_status_1():
|
||||||
|
Reads the motor's error status, voltage, temperature and
|
||||||
|
other information.
|
||||||
|
read_motor_status_2():
|
||||||
|
Reads the motor temperature, voltage, speed and encoder
|
||||||
|
position.
|
||||||
|
read_motor_status_3():
|
||||||
|
Reads the phase current status data of the motor.
|
||||||
|
clear_motor_error_flag():
|
||||||
|
Clears the error status of the currrent motor.
|
||||||
|
torque_closed_loop(data):
|
||||||
|
Control torque current output of the motor.
|
||||||
|
speed_closed_loop(data):
|
||||||
|
Control the speed of the motor.
|
||||||
|
position_closed_loop_1(data):
|
||||||
|
Control the position of the motor (multi-turn angle).
|
||||||
|
position_closed_loop_2(data):
|
||||||
|
Control the position of the motor (multi-turn angle).
|
||||||
|
position_closed_loop_3(data):
|
||||||
|
Control the position of the motor (single-turn angle).
|
||||||
|
position_closed_loop_4(data):
|
||||||
|
Control the position of the motor (single-turn angle).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, identifier):
|
||||||
|
"""
|
||||||
|
Constructs all the necessary attributes for the RMDX8 object.
|
||||||
|
"""
|
||||||
|
self.bus = None
|
||||||
|
self.identifier = identifier
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
"""
|
||||||
|
Setup the can bus connection.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
self.bus : type
|
||||||
|
The bus used to communicate with the motor.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
os.system("sudo /sbin/ip link set can0 up type can bitrate 1000000")
|
||||||
|
time.sleep(0.1)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
try:
|
||||||
|
bus = can.interface.Bus(bustype='socketcan_native', channel='can0')
|
||||||
|
except OSError:
|
||||||
|
print('err: PiCAN board was not found.')
|
||||||
|
exit()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
self.bus = bus
|
||||||
|
return self.bus
|
||||||
|
|
||||||
|
def send_cmd(self, data, delay):
|
||||||
|
"""
|
||||||
|
Send frame data to the motor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
delay : int/float
|
||||||
|
The time to wait after sending data to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = can.Message(arbitration_id=self.identifier,
|
||||||
|
data=data, extended_id=False)
|
||||||
|
self.bus.send(message)
|
||||||
|
time.sleep(delay)
|
||||||
|
received_message = self.bus.recv()
|
||||||
|
return received_message
|
||||||
|
|
||||||
|
def read_pid(self):
|
||||||
|
"""
|
||||||
|
Read the motor's current PID parameters.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def write_pid_ram(self, data):
|
||||||
|
"""
|
||||||
|
Write PID parameters to the RAM.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x31, 0x00, data[0], data[1],
|
||||||
|
data[2], data[3], data[4], data[5]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def write_pid_rom(self, data):
|
||||||
|
"""
|
||||||
|
Write PID parameters to the ROM.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x32, 0x00, data[0], data[1],
|
||||||
|
data[2], data[3], data[4], data[5]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_acceleration(self):
|
||||||
|
"""
|
||||||
|
Read the motor's acceleration data.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def write_acceleration_ram(self, data):
|
||||||
|
"""
|
||||||
|
Write the acceleration to the RAM of the motor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x34, 0x00, 0x00, 0x00,
|
||||||
|
data[0], data[1], data[2], data[3]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_encoder(self):
|
||||||
|
"""
|
||||||
|
Read the current position of the encoder.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def write_encoder_offset(self, data):
|
||||||
|
"""
|
||||||
|
Set the motor's encoder offset.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x91, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, data[0], data[1]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def write_motor_zero_rom(self):
|
||||||
|
"""
|
||||||
|
Write the current position of the motor to the ROM as the motor zero position.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x19, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_multi_turns_angle(self):
|
||||||
|
"""
|
||||||
|
Read the multi-turn angle of the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x92, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_single_turn_angle(self):
|
||||||
|
"""
|
||||||
|
Read the single circle angle of the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x94, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def motor_off(self):
|
||||||
|
"""
|
||||||
|
Turn off the motor, while clearing the motor operating status and previously received control commands.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x80, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def motor_stop(self):
|
||||||
|
"""
|
||||||
|
Stop the motor, but do not clear the operating state and previously received control commands.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x81, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def motor_run(self):
|
||||||
|
"""
|
||||||
|
Resume motor operation from the motor stop command.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x88, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_motor_status_1(self):
|
||||||
|
"""
|
||||||
|
Reads the motor's error status, voltage, temperature and other information.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x9A, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_motor_status_2(self):
|
||||||
|
"""
|
||||||
|
Reads the motor temperature, voltage, speed and encoder position.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x9C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def read_motor_status_3(self):
|
||||||
|
"""
|
||||||
|
Reads the phase current status data of the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x9D, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def clear_motor_error_flag(self):
|
||||||
|
"""
|
||||||
|
Clears the error status of the currrent motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0x9B, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def torque_closed_loop(self, data):
|
||||||
|
"""
|
||||||
|
Control torque current output of the motor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA1, 0x00, 0x00, 0x00,
|
||||||
|
data[0], data[1], 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def speed_closed_loop(self, data):
|
||||||
|
"""
|
||||||
|
Control the speed of the motor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA2, 0x00, 0x00, 0x00,
|
||||||
|
data[0], data[1], data[2], data[3]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def position_closed_loop_1(self, data):
|
||||||
|
"""
|
||||||
|
Control the position of the motor (multi-turn angle).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA3, 0x00, 0x00, 0x00,
|
||||||
|
data[0], data[1], data[2], data[3]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def position_closed_loop_2(self, data):
|
||||||
|
"""
|
||||||
|
Control the position of the motor (multi-turn angle).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA4, 0x00, data[0], data[1],
|
||||||
|
data[2], data[3], data[4], data[5]]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def position_closed_loop_3(self, data):
|
||||||
|
"""
|
||||||
|
Control the position of the motor (single-turn angle).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA5, data[0], 0x00, 0x00,
|
||||||
|
data[1], data[2], 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
||||||
|
|
||||||
|
def position_closed_loop_4(self, data):
|
||||||
|
"""
|
||||||
|
Control the position of the motor (single-turn angle).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : list
|
||||||
|
The frame data to be sent to the motor.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
received_message : list
|
||||||
|
Frame data received from the motor after receiving the command.
|
||||||
|
"""
|
||||||
|
message = [0xA6, data[0], data[1], data[2],
|
||||||
|
data[3], data[4], 0x00, 0x00]
|
||||||
|
return self.send_cmd(message, 0.01)
|
Loading…
Reference in new issue