johnkok / ros_odrive Goto Github PK
View Code? Open in Web Editor NEWOdrive motor controller C++ driver for ROS
License: MIT License
Odrive motor controller C++ driver for ROS
License: MIT License
The following are the error code that I have been encountering:
Device 0x205539725453 Found
"Error opening configuration file!"
Starting idle loop
"Error in reading data from USB!"
My setup:
Laptop
ROS ODrive v3.6 56V (Firmware Version: 0.5.5 and Odrivetool Version: 0.6.3)
BLDC Hub Motors
I wrote a very basic Python class to accept cmd_vel messages and translate them into odrive_ctrl messages. Upon initialization, the class sends CMD_AXIS_CLOSED_LOOP commands to both axis0, and axis1, without errors. But when I start processing cmd_vel messages, I attempt to send CMD_AXIS_SET_VELOCITY_DUAL commands, and get the following errors:
[ERROR] [1615602592.918275557]: * Error: invalid write access for axis0.controller.vel_setpoint
[ERROR] [1615602592.924280103]: * Error: invalid write access for axis1.controller.vel_setpoint
I added some logging into the odrive.cpp source, to print the values in the odrive_ctrl messages before being submitted to the motor controller.
[ INFO] [1615602599.898911961]: =====
[ INFO] [1615602599.899177059]: msg->axis [0]
[ INFO] [1615602599.899554961]: msg->target [0]
[ INFO] [1615602599.899742424]: msg->command [4]
[ INFO] [1615602599.900849218]: msg->fval [0.500000]
[ INFO] [1615602599.900964039]: msg->fval2 [0.500000]
[ INFO] [1615602599.901057866]: =====
Here's the source for my Python class. Is there something in the process of setting things up that I have missed?
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
from ros_odrive.msg import odrive_ctrl
class WheelDriver:
### Constructor ###
def __init__(self):
self.pub = rospy.Publisher(
"/ros_odrive/odrive_ctrl_0x20793868304E",
odrive_ctrl,
queue_size=1)
rospy.Subscriber("cmd_vel", Twist, self.callback)
# cmd_vel Topic Subscriber Callback
# Processes Twist messages, sending velocity commands
# to the ODrive
def callback(self, data):
rospy.loginfo("Received Twist Message")
msg = odrive_ctrl()
msg.target = 0
msg.command = 4 # CMD_AXIS_SET_VELOCITY_DUAL
msg.fval = data.linear.x
msg.fval2 = data.linear.x
rospy.loginfo("Sending odrive message...")
self.pub.publish(msg)
# Setup method, sending CMD_AXIS_CLOSED_LOOP commands
# to each axis.
def sendCACL(self):
a0_msg = odrive_ctrl()
a1_msg = odrive_ctrl()
# Send CMD_AXIS_CLOSED_LOOP to axis0
# Had to add this sleep call to get both messages to send.
rospy.sleep(2)
rospy.loginfo("Sending CMD_AXIS_CLOSED_LOOP to axis0")
a0_msg.target = 0
a0_msg.command = 2
a0_msg.axis = 0
a0_msg.fval = 0.0
a0_msg.fval2 = 0.0
self.pub.publish(a0_msg)
rospy.sleep(2)
# Send CMD_AXIS_CLOSED_LOOP to axis1
rospy.loginfo("Sending CMD_AXIS_CLOSED_LOOP to axis1")
a1_msg.target = 0
a1_msg.command = 2
a1_msg.axis = 1
a1_msg.fval = 0.0
a1_msg.fval2 = 0.0
self.pub.publish(a1_msg)
rospy.sleep(2)
if __name__ == '__main__':
rospy.init_node("wheel_driver", anonymous=True)
drvr = WheelDriver()
drvr.sendCACL()
rospy.spin()
Are the units of fval [count/s]? And is this the same for the vel being published?
Also, is it possible to send a velocity command to both motors at the same time? As the control message only sends 1 axis at a time.
Even though, as far as I can see, within the package.xml
and the cmake file std_msgs in included as a dependency, I cannot seem to be able to import "std_msgs\Float64.h"
in my odrive.h
file. Any suggestions ?
Sorry to bug you again. I've started working on adapting your repo so I can control 4 motors at the same time whilst using ros control (so no topic subcribing/publishing). The part I'm still trying to figure out is how to send commands to two separate odrive boards.
I'm thinking of something along the lines of:
endpoint0 = new odrive_endpoint();
endpoint1 = new odrive_endpoint();
odrive_endpoint *endpoint[2] = {endpoint0, endpoint1}; //Not sure if this will work
for (i = 0; i < 2; ++i) {
// Enumerate Odrive target
if (endpoint[i]->init(stoull(od_sn[i], 0, 16))) //od_sn will contain two serial numbers
{
ROS_ERROR("Device not found!");
return 1;
}
// Read JSON from target - Do I need to json files?
if (getJson(endpoint[i], &odrive_json)) {
return 1;
}
targetJsonValid = true;
}
But I'm not sure how to deal with the odrive_json stuff. Do you think something like this would work or am I doing it completely wrong? Will setting endpoint[i] be enough to target the right odrive? or also need to save two different odrive_json?
When I write the speed to the motor it would then look like:
uint8_t motor_to_odrive_map[4] = {0, 0, 1, 1};
int ODriveDriver::setMotorSpeed(int motor_index, float motor_speed) {
std::string cmd;
//Get which odrive board depending on index
i = motor_to_odrive_map[motor_index]
//Get which axis depending on index
cmd = "axis"
cmd.append(std::to_string(motor_index_map_[motor_index]))
//Will setting endpoint[i] be enough to target the right odrive? or also need to save two diff odrive_json?
writeOdriveData(endpoint[i], odrive_json, cmd.append(".controller.vel_setpoint"), motor_speed);
}
You can find the changes I've made here. I think the only thing left to figure out is how to deal with the endpoint/json stuff.
Hi!
Nice work on the driver! Looking forward to testing it at some point. Do you have any plans for implementing ros_control/robot_hardware_interface?
I'm having difficulty getting your ROS driver up and running for my ODrive device. I've upgraded the firmware to the latest version available, and have built a configuration file for your driver that corresponds to the brushless motors I am using. But I keep getting "Error in reading data from USB" errors when the driver attempts to take values from my configuration file.
My environment is a Jetson Xavier AGX running Ubuntu 18.04, with the ROS Melodic distribution.
Here's the console output from attempting to run the driver. Is there something basic that I am missing?
robot@robot:~/echobot/src/ros_odrive/cfg$ rosrun ros_odrive ros_odrive _od_sn:="0x20793868304E" _od_cfg:="/home/robot/echobot/src/ros_odrive/cfg/odrive_15pole.json"
[ INFO] [1615160207.836033751]: Starting ODrive...
[ INFO] [1615160207.853576110]: 1 odrive instances:
[ INFO] [1615160207.855488309]: Instance 0: SN 0x20793868304E - cfg /home/robot/echobot/src/ros_odrive/cfg/odrive_15pole.json
[ INFO] [1615160207.878449509]: Device 0x20793868304E Found
/home/robot/echobot/src/ros_odrive/cfg/odrive_15pole.json[ INFO] [1615160208.223289145]: Setting config.brake_resistance config value
[ERROR] [1615160208.430103709]: * Error in reading data from USB!
[ INFO] [1615160208.431449138]: Setting axis0.motor.config.pole_pairs config value
[ERROR] [1615160208.639965577]: * Error in reading data from USB!
[ INFO] [1615160208.641430889]: Setting axis0.motor.config.resistance_calib_max_voltage config value
[ERROR] [1615160208.850340739]: * Error in reading data from USB!
[ INFO] [1615160208.852292812]: Setting axis0.motor.config.calibration_current config value
[ERROR] [1615160209.060455191]: * Error in reading data from USB!
[ INFO] [1615160209.062538348]: Setting axis0.motor.config.requested_current_range config value
[ERROR] [1615160209.270971940]: * Error in reading data from USB!
[ INFO] [1615160209.272920525]: Setting axis0.motor.config.current_control_bandwidth config value
[ERROR] [1615160209.481454030]: * Error in reading data from USB!
[ INFO] [1615160209.483429273]: Setting axis0.encoder.config.mode config value
[ERROR] [1615160209.490033365]: Error value for axis0.encoder.config.mode is not int
[ INFO] [1615160209.490870109]: Setting axis0.encoder.config.cpr config value
[ERROR] [1615160209.699083395]: * Error in reading data from USB!
[ INFO] [1615160209.700920994]: Setting axis0.motor.config.current_lim config value
[ERROR] [1615160209.909447714]: * Error in reading data from USB!
[ INFO] [1615160209.911773484]: Setting axis0.encoder.config.bandwidth config value
[ERROR] [1615160210.119944817]: * Error in reading data from USB!
[ INFO] [1615160210.122149359]: Setting axis0.controller.config.pos_gain config value
[ERROR] [1615160210.330863593]: * Error in reading data from USB!
[ INFO] [1615160210.333186609]: Setting axis0.controller.config.vel_gain config value
[ERROR] [1615160210.541198478]: * Error in reading data from USB!
[ INFO] [1615160210.543412397]: Setting axis0.controller.config.vel_integrator_gain config value
[ERROR] [1615160210.752319896]: * Error in reading data from USB!
[ INFO] [1615160210.754663202]: Setting axis0.controller.config.vel_limit config value
[ERROR] [1615160210.963045535]: * Error in reading data from USB!
[ INFO] [1615160210.965538838]: Setting axis0.controller.config.control_mode config value
[ERROR] [1615160210.972245337]: Error value for axis0.controller.config.control_mode is not int
[ INFO] [1615160210.973168072]: Setting axis0.encoder.config.calib_range config value
[ERROR] [1615160211.179116676]: * Error in reading data from USB!
[ INFO] [1615160211.181885682]: Setting axis1.motor.config.pole_pairs config value
[ERROR] [1615160211.390151406]: * Error in reading data from USB!
[ INFO] [1615160211.392601633]: Setting axis1.motor.config.resistance_calib_max_voltage config value
[ERROR] [1615160211.602441508]: * Error in reading data from USB!
[ INFO] [1615160211.605069607]: Setting axis1.motor.config.calibration_current config value
[ERROR] [1615160211.813062475]: * Error in reading data from USB!
[ INFO] [1615160211.815455001]: Setting axis1.motor.config.requested_current_range config value
[ERROR] [1615160212.023849148]: * Error in reading data from USB!
[ INFO] [1615160212.026118334]: Setting axis1.motor.config.current_control_bandwidth config value
[ERROR] [1615160212.234682237]: * Error in reading data from USB!
[ INFO] [1615160212.237353282]: Setting axis1.encoder.config.mode config value
[ERROR] [1615160212.243928950]: Error value for axis1.encoder.config.mode is not int
[ INFO] [1615160212.244790176]: Setting axis1.encoder.config.cpr config value
[ERROR] [1615160212.450756703]: * Error in reading data from USB!
[ INFO] [1615160212.453396482]: Setting axis1.motor.config.current_lim config value
[ERROR] [1615160212.661290439]: * Error in reading data from USB!
[ INFO] [1615160212.665451372]: Setting axis1.encoder.config.bandwidth config value
[ERROR] [1615160212.873871902]: * Error in reading data from USB!
[ INFO] [1615160212.876137632]: Setting axis1.controller.config.pos_gain config value
[ERROR] [1615160213.083520355]: * Error in reading data from USB!
[ INFO] [1615160213.085792486]: Setting axis1.controller.config.vel_gain config value
[ERROR] [1615160213.297220322]: * Error in reading data from USB!
[ INFO] [1615160213.299695349]: Setting axis1.controller.config.vel_integrator_gain config value
[ERROR] [1615160213.508536404]: * Error in reading data from USB!
[ INFO] [1615160213.510968420]: Setting axis1.controller.config.vel_limit config value
[ERROR] [1615160213.719437123]: * Error in reading data from USB!
[ INFO] [1615160213.722248020]: Setting axis1.controller.config.control_mode config value
[ERROR] [1615160213.728114537]: Error value for axis1.controller.config.control_mode is not int
[ INFO] [1615160213.729065178]: Setting axis1.encoder.config.calib_range config value
[ERROR] [1615160213.935267160]: * Error in reading data from USB!
[ERROR] [1615160213.945266063]: Error value for axis0.requested_state is not int
I have a skid steer robot using two odrives for 4 BLDC motors. Is there a way I could use this package to drive my 4 motors?Basically the two motors on one odrive are meant to spin at the same speed and the same on the other side of the robot.
The current rate at which the feedback from odrive is set to 1 Hz, but I want to increase it to at least 10 Hz. Removing the sleep in main function is still giving me about 5 Hz only. What is the issue and can I increase the feedback rate?
I am not able to read/write with odrive firmware 5.1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.