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