Quick Start Guide#
This guide will help you get started with Qontrol quickly.
Basic Concepts#
Qontrol is built around three main concepts:
Model: Represents the robot kinematic/dynamic model
Problem: Defines the control problem (velocity, acceleration, or torque)
Tasks & Constraints: Define what you want the robot to do and what limits to respect
Simple Velocity Control Example#
Below are simple examples of velocity control in both Python and C++.
import qontrol
import numpy as np
# 1. Load robot model from URDF
# Ensure you have a valid URDF file
urdf_path = "path/to/robot.urdf"
model = qontrol.RobotModel.load_from_file(urdf_path)
# 2. Create a velocity control problem
# (Uses qpmad solver by default if available)
problem = qontrol.JointVelocityProblem(model)
# 3. Create and add a Cartesian velocity task
# Tasks are added via the problem's task_set
task = problem.task_set.add_cartesian_velocity("main_task", 1.0)
# 4. Add joint velocity limits as constraints
# Constraints are added via the problem's constraint_set
constraint = problem.constraint_set.add_joint_velocity("joint_limits")
# Define desired Cartesian velocity for end-effector
# Format: [vx, vy, vz, wx, wy, wz] (linear and angular velocities)
desired_twist = np.array([0.1, 0.0, 0.0, 0.0, 0.0, 0.0])
# Simulation / Control Loop
dt = 0.001
# Update robot state (pseudo-code)
# You would typically get q (positions) and dq (velocities) from your robot
state = qontrol.RobotState()
state.resize(model.get_nr_of_degrees_of_freedom())
# state.joint_position = ...
# state.joint_velocity = ...
model.set_robot_state(state)
# Set task target
task.set_target_velocity(desired_twist)
# Update the problem and solve it
problem.update(dt)
if problem.solution_found():
# Get computed joint velocities
dq_cmd = problem.get_joint_velocity_command()
print("Joint velocity command:", dq_cmd)
#include <Qontrol/Qontrol.hpp>
#include <iostream>
using namespace Qontrol;
int main() {
// 1. Load robot model from URDF
std::string urdf_path = "path/to/robot.urdf";
auto model = Model::RobotModel::loadModelFromFile(urdf_path);
// 2. Create a velocity control problem
auto problem = std::make_shared<JointVelocityProblem>(model);
// 3. Create and add a Cartesian velocity task
auto task = problem->task_set->add<Task::CartesianVelocity>("main_task");
// 4. Add joint velocity limits
auto constraint = problem->constraint_set->add<Constraint::JointVelocity>("joint_limits");
// Define desired Cartesian velocity
Eigen::VectorXd desired_twist(6);
desired_twist << 0.1, 0.0, 0.0, 0.0, 0.0, 0.0;
double dt = 0.001;
// Update robot state (pseudo-code)
RobotState state;
state.resize(model->getNrOfDegreesOfFreedom());
// state.joint_position = ...
model->setRobotState(state);
// Set task target
task->setTargetVelocity(desired_twist);
// Update the problem and solve it
problem->update(dt);
if (problem->solutionFound()) {
Eigen::VectorXd dq_cmd = problem->getJointVelocityCommand();
std::cout << "Joint velocity command: " << dq_cmd.transpose() << std::endl;
}
return 0;
}
Adding Constraints#
Constraints are hard limits that must always be satisfied:
# Joint position limits
pos_constraint = qontrol.JointPositionLimits(model)
pos_constraint.set_limits(q_min, q_max)
problem.add_constraint(pos_constraint)
# Joint velocity limits
vel_constraint = qontrol.JointVelocityLimits(model)
vel_constraint.set_limits(v_min, v_max)
problem.add_constraint(vel_constraint)
Acceleration Control#
For acceleration control:
# Create acceleration problem
problem = qontrol.AccelerationProblem(model)
# Add Cartesian acceleration task
task = qontrol.CartesianAccelerationTask(model)
task.set_desired_acceleration(desired_acc)
problem.add_task(task)
# Solve
solution = problem.update(dt)
joint_accelerations = solution.get_joint_velocity_command()
Torque Control#
For torque control (requires dynamic model):
# Create torque problem
problem = qontrol.TorqueProblem(model)
# Add joint torque task
task = qontrol.JointTorqueTask(model)
task.set_desired_torque(desired_torques)
problem.add_task(task)
# Add torque limits
constraint = qontrol.JointTorqueLimits(model)
constraint.set_limits(tau_min, tau_max)
problem.add_constraint(constraint)
# Solve
solution = problem.update(dt)
joint_torques = solution.get_joint_torque_command()
Next Steps#
Check out more Examples for advanced usage
Explore the API Reference for complete API reference