Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
510709e
Complete impedance control example with documentation
GogiPuttar Jul 19, 2024
4fe2ad7
Complete gimbal example
GogiPuttar Jul 19, 2024
8cce890
Complete cartesian impedance controller example
GogiPuttar Jul 19, 2024
cdd7e9a
Created floor and variable damping examples.
GogiPuttar Jul 24, 2024
f72675e
All examples are complete now
GogiPuttar Jul 24, 2024
f015b5f
Properly used ki and i_clamp terms for fixed example
GogiPuttar Jul 25, 2024
b586b2f
Correctly demonstrated how to use i_terms across all examples
GogiPuttar Jul 25, 2024
d63877f
Changed prevmode back to -1 also, for consistency
GogiPuttar Jul 25, 2024
88cece2
Added check for mode validity
GogiPuttar Jul 25, 2024
cf5717e
- CPP examples now follow config file convention
GogiPuttar Aug 9, 2024
6443fa5
All impedance control examples work
GogiPuttar Aug 13, 2024
89dc779
mobile_io_control example integrated with config files
GogiPuttar Aug 13, 2024
3afe1bf
Refactored repo according to new layout
GogiPuttar Aug 14, 2024
6317ab3
Renamed file paths to acoomaodate new config file layout
GogiPuttar Aug 14, 2024
c35092c
gravcomp and new gravcomp_toggle examples also integrated with config
GogiPuttar Aug 14, 2024
c6ec868
ex_AR_kit integrated
GogiPuttar Aug 14, 2024
b988f08
teach repeat fully integrated
GogiPuttar Aug 14, 2024
551e6ce
Ironed a few things out
GogiPuttar Aug 14, 2024
dd264b1
removed instructions from all examples
GogiPuttar Aug 20, 2024
2110d4f
Re-added initial update for reset
GogiPuttar Aug 20, 2024
75a1cd3
standardized namespace declarations
GogiPuttar Aug 20, 2024
e5dd48e
removed all sleeps
GogiPuttar Aug 20, 2024
046a221
changed getpluginbyname to getpluginbytype
GogiPuttar Aug 20, 2024
6c75cd8
UserData's getters have been incorporated
GogiPuttar Aug 20, 2024
0e69956
Checked every single example one last time
GogiPuttar Aug 20, 2024
153d9d5
Compatible with config.location_
GogiPuttar Aug 22, 2024
ba70958
examples repo compatible with newest API
GogiPuttar Sep 11, 2024
f843fbd
removed unnecessary file
GogiPuttar Sep 11, 2024
e3c6c74
reflects changes that will be made into config directory
GogiPuttar Sep 11, 2024
fe4a230
Introduced latency in AR kit, python also has this now
GogiPuttar Sep 11, 2024
e0782fc
Updated the C++ library reference
iamtesch Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 187 additions & 0 deletions kits/arm/example_impedance_control_cartesian.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
In these examples we will implement various hybrid motion-force controllers using the impedance control plugin, which can be used for a wide variety of
applications.
Impedance control is BEST SUITED for assigning free, rigid and springy behaviour, along/about each different axis.
While this is perfectly useful for:
- Having a selectively compliant end-effector,
- Switching between fixed and free behaviour to simulate (mostly) rigid constraints, and
- Allowing human intervention for automated operations by separating controls across different axes,
any applications involving more salient control of the forces (as more complex functions with flexible inputs) should use our force control plugin. See ex_force_control_demoname.cpp.

This comprises the following demos:
- Fixed: A task-space pose controller implemented entirely using force control via the (PID) impedance controller.
- Cartesian: Locks onto a particular end-effector position while having some compliant orientation.
- Gimbal: A gimbal that locks a specific end-effector orientation, while keeping the rest of the arm compliant.
- Floor: The end-effector is free to move but can't travel below a virtual floor. To further simulate sliding on the floor, see force_control example.
- Damping: The end-effector behaves as 3-different damped systems (overdamped, critically damped, and underdamped), at 3 different heights.

The following example is for the "Cartesian" demo:
*/

// #include "lookup.hpp"
// #include "group.hpp"
Comment thread
GogiPuttar marked this conversation as resolved.
Outdated
#include "group_command.hpp"
#include "group_feedback.hpp"
#include "robot_model.hpp"
#include "arm/arm.hpp"
#include "util/mobile_io.hpp"
#include <chrono>

using namespace hebi;
using namespace experimental;

int main(int argc, char* argv[])
{
//////////////////////////
///// Arm Setup //////////
//////////////////////////

arm::Arm::Params params;

// Setup Module Family and Module Names
params.families_ = {"HEBIArm-T"};
Comment thread
GogiPuttar marked this conversation as resolved.
Outdated
params.names_ = {"J1_base", "J2_shoulder", "J3_elbow", "J4_wrist1", "J5_wrist2", "J6_wrist3"};

// Read HRDF file to seutp a RobotModel object for the 6-DoF Arm
// Make sure you are running this from the correct directory!
params.hrdf_file_ = "kits/arm/hrdf/T-arm.hrdf";
Comment thread
GogiPuttar marked this conversation as resolved.
Outdated

// Create the Arm Object
auto arm = arm::Arm::create(params);
while (!arm) {
arm = arm::Arm::create(params);
}

// Load the gains file that is approriate to the arm
arm -> loadGains("kits/arm/gains/T-arm.xml");

// Create and configure the ImpedanceController plugin

// NOTE: Angle wraparound is an unresolved issue which can lead to unstable behaviour for any case involving rotational positional control.
// Make sure that the rotational gains are high enough to prevent large angular errors (greater than pi/2). The gains provided in these examples are well behaved.
// Interacting with the end-effector in these examples is perfectly safe.
// However, ensure that nothing prevents the wrist's actuators from moving, and DO NOT place your fingers between them.

hebi::experimental::arm::PluginConfig impedance_config("ImpedanceController", "ImpedanceController");
impedance_config.float_lists_["kp"] = {300.0, 300.0, 300.0, 0.0, 0.0, 0.0};
impedance_config.float_lists_["kd"] = {5.0, 5.0, 5.0, 0.0, 0.0, 0.0};
impedance_config.float_lists_["ki"] = {20.0, 20.0, 20.0, 0.0, 0.0, 0.0};
impedance_config.float_lists_["i_clamp"] = {10.0, 10.0, 10.0, 0.0, 0.0, 0.0}; // Clamp on the end-effector wrench and NOT on the integral error
impedance_config.bools_["gains_in_end_effector_frame"] = true;

auto impedance_plugin = hebi::experimental::arm::plugin::ImpedanceController::create(impedance_config);
if (!impedance_plugin) {
std::cerr << "Failed to create ImpedanceController plugin." << std::endl;
return -1;
}

// Initialize variables used to clear the commanded position and velocity in every cycle
hebi::GroupCommand& command = arm->pendingCommand();

auto num_joints = arm->robotModel().getDoFCount();
Eigen::VectorXd pos_nan(num_joints), vel_nan(num_joints);
pos_nan.fill(std::numeric_limits<double>::quiet_NaN());
vel_nan.fill(std::numeric_limits<double>::quiet_NaN());

// Add the plugin to the arm
if (!arm->addPlugin(std::move(impedance_plugin))) {
std::cerr << "Failed to add ImpedanceController plugin to arm." << std::endl;
return -1;
}

//////////////////////////
//// MobileIO Setup //////
//////////////////////////

// Set up MobileIO
std::unique_ptr<util::MobileIO> mobile = util::MobileIO::create(params.families_[0], "mobileIO");
if (!mobile)
{
std::cout << "couldn't find mobile IO device!\n";
return 1;
}
mobile->setButtonMode(1, util::MobileIO::ButtonMode::Momentary);
mobile->setButtonLabel(1, "❌");
mobile->setButtonMode(2, util::MobileIO::ButtonMode::Toggle);
mobile->setButtonLabel(2, "💪");

std::string instructions;
instructions = " Cartesian demo";

// Clear any garbage on screen
mobile->clearText();
Comment thread
GogiPuttar marked this conversation as resolved.
Outdated

// Display instructions on screen
mobile->appendText(instructions);

// Setup instructions
auto last_state = mobile->update();

std::cout << "Commanded gravity-compensated zero force to the arm.\n"
<< " 💪 (B2) - Toggles an impedance controller on/off:\n"
<< " ON - Apply controller based on current position\n"
<< " OFF - Go back to gravity-compensated mode\n"
<< " ❌ (B1) - Exits the demo.\n";

/////////////////////////////
// Control Variables Setup //
/////////////////////////////

// Flag to indicate when impedance controller is on
bool controller_on = false;

//////////////////////////
//// Main Control Loop ///
//////////////////////////

while(arm->update())
{
auto updated_mobile = mobile->update(0);

if (updated_mobile)
{
/////////////////
// Button Presses
/////////////////

// Buttton B1 - End demo
if (mobile->getButtonDiff(1) == util::MobileIO::ButtonState::ToOn) {
// Clear MobileIO text
mobile->resetUI();
return 1;
}

// Button B2 - Set and unset impedance mode when button is pressed and released, respectively
if (mobile->getButtonDiff(2) == util::MobileIO::ButtonState::ToOn) {

controller_on = true;

arm->setGoal(arm::Goal::createFromPosition(arm->lastFeedback().getPosition()));
}
else if (mobile->getButtonDiff(2) == util::MobileIO::ButtonState::ToOff){

controller_on = false;
}
}

if (!controller_on)
{
arm->cancelGoal();
}

// Clear all position and velocity commands
command.setPosition(pos_nan);
command.setVelocity(vel_nan);

// Send latest commands to the arm
arm->send();
}

// Clear MobileIO text
mobile->clearText();
Comment thread
GogiPuttar marked this conversation as resolved.
Outdated

return 0;
}



Loading