Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions example_7/bringup/launch/r6bot_controller.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def generate_launch_description():
executable="ros2_control_node",
parameters=[robot_controllers],
output="both",
emulate_tty=True,
)
robot_state_pub_node = Node(
package="robot_state_publisher",
Expand Down
32 changes: 26 additions & 6 deletions example_7/controller/r6bot_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ controller_interface::CallbackReturn RobotController::on_configure(const rclcpp_
auto callback =
[this](const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> traj_msg) -> void
{
RCLCPP_INFO(get_node()->get_logger(), "Received new trajectory.");
traj_msg_external_point_ptr_.writeFromNonRT(traj_msg);
new_msg_ = true;
};
Expand Down Expand Up @@ -136,15 +137,18 @@ void interpolate_point(

void interpolate_trajectory_point(
const trajectory_msgs::msg::JointTrajectory & traj_msg, const rclcpp::Duration & cur_time,
trajectory_msgs::msg::JointTrajectoryPoint & point_interp)
trajectory_msgs::msg::JointTrajectoryPoint & point_interp, bool & reached_end)
{
double traj_len = static_cast<double>(traj_msg.points.size());
auto last_time = traj_msg.points.back().time_from_start;
double total_time = last_time.sec + last_time.nanosec * 1E-9;
double cur_time_sec = cur_time.seconds();
reached_end = (cur_time_sec >= total_time);

size_t ind = static_cast<size_t>(cur_time.seconds() * (traj_len / total_time));
size_t ind =
static_cast<size_t>(cur_time_sec * (traj_len / total_time)); // Assumes evenly spaced points.
ind = std::min(ind, static_cast<size_t>(traj_len) - 2);
double delta = cur_time.seconds() - static_cast<double>(ind) * (total_time / traj_len);
double delta = std::min(cur_time_sec - static_cast<double>(ind) * (total_time / traj_len), 1.0);
interpolate_point(traj_msg.points[ind], traj_msg.points[ind + 1], point_interp, delta);
}

Expand All @@ -160,14 +164,30 @@ controller_interface::return_type RobotController::update(

if (trajectory_msg_ != nullptr)
{
interpolate_trajectory_point(*trajectory_msg_, time - start_time_, point_interp_);
bool reached_end;
interpolate_trajectory_point(*trajectory_msg_, time - start_time_, point_interp_, reached_end);

// If we have reached the end of the trajectory, reset it and set velocities to zero.
if (reached_end)
{
RCLCPP_INFO(get_node()->get_logger(), "Trajectory execution complete.");
trajectory_msg_.reset();
std::fill(point_interp_.velocities.begin(), point_interp_.velocities.end(), 0.0);
}

for (size_t i = 0; i < joint_position_command_interface_.size(); i++)
{
joint_position_command_interface_[i].get().set_value(point_interp_.positions[i]);
if (!joint_position_command_interface_[i].get().set_value(point_interp_.positions[i]))
{
RCLCPP_ERROR(get_node()->get_logger(), "Failed to set position value for index %ld", i);
}
}
for (size_t i = 0; i < joint_velocity_command_interface_.size(); i++)
{
joint_velocity_command_interface_[i].get().set_value(point_interp_.velocities[i]);
if (!joint_velocity_command_interface_[i].get().set_value(point_interp_.velocities[i]))
{
RCLCPP_ERROR(get_node()->get_logger(), "Failed to set velocity value for index %ld", i);
}
}
}

Expand Down
28 changes: 11 additions & 17 deletions example_7/reference_generator/send_trajectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,14 @@ int main(int argc, char ** argv)

double total_time = 3.0;
int trajectory_len = 200;
int loop_rate = static_cast<int>(std::round(trajectory_len / total_time));
double dt = 1.0 / loop_rate;
double dt = total_time / static_cast<double>(trajectory_len - 1);

for (int i = 0; i < trajectory_len; i++)
{
// set endpoint twist
double t = i;
twist.vel.x(2 * 0.3 * cos(2 * M_PI * t / trajectory_len));
twist.vel.y(-0.3 * sin(2 * M_PI * t / trajectory_len));
double t = i / (static_cast<double>(trajectory_len - 1));
twist.vel.x(2 * 0.3 * cos(2 * M_PI * t));
twist.vel.y(-0.3 * sin(2 * M_PI * t));

// convert cart to joint velocities
ik_vel_solver_->CartToJnt(joint_positions, twist, joint_velocities);
Expand All @@ -88,22 +87,17 @@ int main(int argc, char ** argv)
joint_positions.data += joint_velocities.data * dt;

// set timing information
trajectory_point_msg.time_from_start.sec = i / loop_rate;
trajectory_point_msg.time_from_start.nanosec = static_cast<int>(
1E9 / loop_rate *
static_cast<double>(t - loop_rate * (i / loop_rate))); // implicit integer division

double time_point = total_time * t;
double time_point_sec = std::floor(time_point);
trajectory_point_msg.time_from_start.sec = static_cast<int>(time_point_sec);
trajectory_point_msg.time_from_start.nanosec =
static_cast<int>((time_point - time_point_sec) * 1E9);
trajectory_msg.points.push_back(trajectory_point_msg);
}

// send zero velocities in the end
std::fill(trajectory_point_msg.velocities.begin(), trajectory_point_msg.velocities.end(), 0.0);
trajectory_point_msg.time_from_start.sec = trajectory_len / loop_rate;
trajectory_point_msg.time_from_start.nanosec = static_cast<int>(
1E9 / loop_rate *
static_cast<double>(
trajectory_len - loop_rate * (trajectory_len / loop_rate))); // implicit integer division
trajectory_msg.points.push_back(trajectory_point_msg);
auto & last_point_msg = trajectory_msg.points.back();
std::fill(last_point_msg.velocities.begin(), last_point_msg.velocities.end(), 0.0);

pub->publish(trajectory_msg);
while (rclcpp::ok())
Expand Down