-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Inquiry: Motion Mode Control Command #9
Comments
Hi Stefan, |
Thank you! Stefan |
Hi @TheIndoorDad Things get much more involved and require API changes in case I allowed multiple commands to different actuators to be chained and synchronized. In this case I would have to redesign a fair amount of the code and split the generation of the commands and sending them similar to the snippet below: myactuator_rmd::CanDriver driver {"can0"};
myactuator_rmd::ActuatorInterface actuator_1 {driver, 1};
myactuator_rmd::ActuatorInterface actuator_2 {driver, 2};
myactuator_rmd::VersionDateRequest const version_date_request {actuator_1.versionDate()};
std::future<std::uint32_t> version_date_future {driver.queue(version_date_request)};
myactuator_rmd::PositionAbsoluteRequest const position_absolute_request {actuator_2.positionAbsoluteSetpoint(180.0, 500.0)};
std::future<myactuator_rmd::Feedback> feedback_future {driver.queue(position_absolute_request)};
driver.sendRecv();
std::cout << version_date_future.get() << std::endl;
std::cout << feedback_future.get() << std::endl; I am not sure if the latter is worth the effort as it makes the driver unintuitive to use. Potentially I could keep the current simple interface and add this as an advance way of interfacing the driver that likely only few people will use. I will try to implement the motion control mode over the course of the next weeks but as I am quite busy at the moment, so probably only during my holidays at the end of this month. If you want to have this feature quickly for testing, what you could do is create another namespace myactuator_rmd {
// Namespace it so that it does not collide with the existing one
namespace experimental {
class ActuatorInterface;
// Use the different send and receive offsets here:
class CanDriver: public CanNode<0x400,0x500> {
public:
CanDriver(std::string const& ifname)
: CanNode{ifname} {
return;
}
friend ActuatorInterface;
};
}
} create another // Please double check the data types, I did not check in detail if the following types make sense
void ActuatorInterface::motionModeControl(double const p_des, double const v_des, double const t_ff,
std::int16_t const kp, std::int16_t kd) {
MotionModeControlRequest const request {p_des, v_des, t_ff, kp, kd};
[[maybe_unused]] MotionModeControlResponse const response {driver_.sendRecv(request, actuator_id_)};
return;
} implement the parsing of |
Excellent, thank you. I should be able to get started with motion mode control as you've described - I'll keep you posted. I'll also take the opportunity now to put my vote in for the addition of multi-motor commands ( I agree also that the simple interface is likely sufficient for my needs for now. |
Hi Tobit, The data frame for motion mode commands is structured differently from others, with most parameters taking up 12-bit ranges and Also note that data is ordered high -> low rather than Low byte -> high byte as in other commands. I was in the process of working out the parsing of |
Hi Stefan, // Start with a 16-bit unsigned integer
constexpr std::uint16_t v_des {1000};
// Extract the lower 12 bits
std::bitset<12> const v_des_bit {v_des};
// Create a bitset for the entire message
std::bitset<64> bit_data {};
// Copy over the upper 8 and the lower 4 bits
for (std::size_t i = 0; i < 8; ++i) {
bit_data.set(i + 16, v_des_bit.test(i + 4));
}
for (std::size_t i = 0; i < 4; ++i) {
bit_data.set(i + 24, v_des_bit.test(i + 0));
}
// Copy the bitset to the array
std::array<std::uint8_t, 8> data {};
// Taken from https://stackoverflow.com/a/58979953
std::bitset<64> const mask {0xff};
for (std::size_t i = 0; i < bit_data.size()/8; ++i) {
data.at(data.size() - 1 - i) = static_cast<std::uint8_t>(((bit_data >> (8*i)) & mask).to_ulong());
} Hope this helps! |
Thank you very much for your help Tobit. I greatly appreciate how generous you've been with your time, especially as you've said you're very busy. My kludged attempt at implementing motion control is building as a python package without error now, but when I try to import
Given that the package at least appears to be compiling and the error is at package import I wonder if it is something to do with the python bindings, but I don't know how to fix it. I also am not confident in the rest of my implementation. Here's what I've done step-by-step: To can_driver.hpp, line 20, added (as provided):
To actuator_interface.hpp, line 29, added:
and to actuator_interface.cpp, line 21, added:
I wasn't certain whether these (above) also should be in the To requests.hpp, line 24, added:
and to requests.cpp, added
Thank you for the advice on Finally, python bindings added to /bindings/myactuator_rmd.cpp, line 72 (just after
Most of this I did just by trying to copy what you had done in other examples, so I'm sure some of it is wrong in addition to the unresolved error importing. You've already helped a great deal, but if you could take another glance at this I would appreciate it. |
Hi again, myactuator_rmd/src/actuator_interface.cpp Lines 22 to 26 in 3fb228a
Other than that the structure looks alright on first glance but I did not have a look at the message parsing in detail. Re-using the Message should work fine, yes.I hope this helps! Let me know how the tests with the actuator go then! |
Yes, that has worked. Thank you! I also had to add
in the src/actuator_interface.cpp |
Nice, really happy to hear that! |
Hi Tobit, I'm about to go away for a couple weeks, so I figured I would give you a brief update on my motion mode control testing. So far, results have been mixed. As I mentioned in my previous post, the code is working for sending individual motion mode commands. However, the motors seem to behave more unreliably under motion mode control: it varies by motor, but some start to make a buzzing sound when even very small external torques are applied then trigger a stall error and shutdown. In some cases this even caused the rest of the motors on the bus to shutdown at the same time - though I hypothesize this may be caused by some protection in my power distribution system tripping from an increased current draw by the stalling motor (still investigating - its strange because this does not occur when using closed-loop position control and the external torque required to trigger this is very low). In other cases the motors don't stall but do buzz loudly when commanded to hold a position (i.e., desired position command with desired velocity = 0) under small load. I've tried using a variety of gain values (including e.g., setting Also FYI: the motors do not allow motion mode commands and closed-loop (position or velocity) commands to be mixed. Using one will lock the motor into that control mode, requiring shutdown before the other may be used. Cheers, |
Hi Stefan, A few remarks:
|
Hi Tobit, I forked the repository and added my changes as a new branch You may be able to test on a single motor, but the behaviour noted in my last comment seems to occur on some of my motors and not on others, so it may be a toss-up whether any motor you test will do the same. This also causes me to suspect it is something to do with the motors, rather than our software. For a test, I would recommend sending a single command to some position
And see if your motor exhibits the same buzzing or stall when a small (much smaller than expected) external torque is applied. My motors are either RMD-X8-Pro-H 1:6 (V3) or RMD-X8-Pro 1:9 (V2) - I've tried adjusting the gains and the buzzing/stall behaviour occurs regardless on certain motors, just with varying stiffness, but might be that different models will require different gains. Syntax example:
Per your remarks:
|
Hi Stefan, |
A quick update with good news: the stalling problem was resolved with a firmware update. The problem occurred on firmware version 2023041301, and not with firmware version 2022101701 (on the same motors). |
Awesome Stefan, thanks for letting me know! |
No problem. I'm still working on troubleshooting the other issues we discussed. |
Hi Tobit,
I'm looking into ways to implement Motion Mode Control (i.e., send desired position and velocity with kp and kd and feedforward torque - 0x400 + ID in the control protocol). I've installed your repo as a python package and used it for position and velocity closed loop control, but unless I'm missing something the motion mode control command is not yet implemented. I've tried to puzzle out how I might modify your source to add the feature, but I'm a C++ novice so I haven't been able to figure it out (yet). Do you have any interest in developing this feature, or do you have any advice as to how I might get started doing so?
I'm aware this would at least require:
Thank you,
Stefan
The text was updated successfully, but these errors were encountered: