Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

CTR Project Documentation

This repository contains software to optimise concentric tube robots based on task and anatomical constraints. If you find this software useful, please cite our paper: C. Bergeles, A. Gosline, N. V. Vasilyev, P. Codd, P. J. del Nido, and P. E. Dupont, "Concentric tube robot design and optimization based on task and anatomical constraints", IEEE Trans. Robotics, vol. 33, no. 4, pp. 901-915, 2017.

##This file contains the documentation for the CTR project code. ##run_optimization.m

Loads all the data

anatomy.filename = ['../../data/' scenario '/anatomy.mat'];

define the optimization variables and optimization method i.e. fminsearchbnd

mopts.variables = {'lengths_curved', 'curvatures', 'base'};
mopts.method = 'fminsearchbnd';

to be confirmed targets = targets([2 3 4 5 6 7 1 8 9 10 11 12 13], :);

H is end-effector but need to understand line 53-56

Creates an array of CTR

ctr_ = [];

And add the below CTRs of Balance and Fixed type to ctr_ array

Creates concentric tube robots signature of Balance type.Balanced pair is 2 curved sgments and 2 straight segments

i = 1;
ctr_(i).type      = 'balanced';

Creates concentric tube robots signature of Fixed type. Fixed curvature tube is a straight segment and a curved segment.

i = 2;
ctr_(i).type      = 'fixed';

ctr_(i).u         = 45;
ctr_(i).u_min     = 0;

Attributes of CTR:

  • Id
  • U curvature
  • Length arclength
  • K stiffness
  • Diameter
  • Theta need to write
  • Phi need to write
  • Start arc start
  • End arc end
  • Curve holds the curve

The array ctr_ is passed to CTROptimize

[ctr_ err] = CTROptimize(ctr_, H, anatomy, targets, vector, base, mopts);

##CTRCreateStructure.m This file will receive CTR signature structure and populates all the parameters based on relationships between the tubes S: The potential curvature changing points that should be examined.Need to clarify

A balanced pair is created with 4 segments(2 curved segments and 2 straight segments). A fixed curvature tube is created with 2 segments(1 straight and 1 curved segment) and number of segment is set accordingly as below: length(ctr_) = 3 as being passed from run_optimization.m

for i = 1:length(ctr_)
    if strcmp(ctr_(i).type, 'balanced')
      n_segments = n_segments + 4;
    elseif strcmp(ctr_(i).type, 'fixed')
      n_segments = n_segments + 2;

A struct is created with all the attributes of CTR

ctr = CTRCreateSegment();

i is used to iterate new structure and j for old structure If n_segment = 4( 'Balanced' type) the below iterates 1 time and initialises the new struct as below: 3rd element in new struct = first element in the old struct 4th element in new struct = same as 3rd element in new struct except theta and k are overwritten

ctr(i+2).id       = i + 2;
      ctr(i+2).u        = ctr_(j).u;
      ctr(i+2).u_temp   = ctr_(j).u;
      ctr(i+2).length   = ctr_(j).c_len;
      ctr(i+2).k        = ctr_(j).k(1);
      ctr(i+2).k_temp   = ctr_(j).k(1);
      ctr(i+2).diameter = ctr_(j).diameter;
      ctr(i+2).theta    = ctr_(j).theta(1);
      ctr(i+2).phi      = max(0, min(ctr_(j).phi, ctr_(j).c_len));
      ctr(i+2).start    = max(0, ctr(i+2).phi + all_end - ctr(i+2).length);
      ctr(i+2).end      = ctr(i+2).phi + all_end;
      % Curved segment #2
      ctr(i+3)       = ctr(i+2);
      ctr(i+3).id    = i+3;
      ctr(i+3).theta = ctr_(j).theta(2);
      if length(ctr_(j).k) == 2
        ctr(i+3).k = ctr_(j).k(2);

The first element in new strcut has the stiffness, diameter and theta same as first element in old struct Length is set as diff between arc end and arc length for 3rd element

	ctr(i).id       = i;
	ctr(i).u        = 0;
	ctr(i).u_temp   = 0;
	ctr(i).length   = max(0, ctr(i+2).end - ctr(i+2).length);
	ctr(i).k        = ctr_(j).k(1);
	ctr(i).k_temp   = ctr_(j).k(1);
	ctr(i).diameter = ctr_(j).diameter;
	ctr(i).theta    = ctr_(j).theta(1);
	ctr(i).phi      = NaN;
	ctr(i).start    = 0;
	ctr(i).end      = ctr(i).length;

The second element is the same as first element except for the value of theta and k

** Why we are taking the unique s?**

s = unique(s);

##CTRCreateCTRFromFile CTRCREATECTRFROMFILE reads the data from DIREC for iteration IND and creates a simple concentric tube robot CTR_ and also return the base location.

The below code loads the file from direc, selects the ctr as per target_idx and pass it on to CTRCreateSimpleCTRFromFullCTR.

load([direc, files(ind).name]);
  ctr_selected = ctr{target_idx};
  HT = base;
  ctr_simple = CTRCreateSimpleCTRFromFullCTR(ctr_selected);

##CTRCreateSimpleCTRFromFullCTR.m This is invoked from CTRCreateCTRFromFile.m,which read the data file and loads the full ctr. The full ctr is passed to CTRCreateSimpleCTRFromFullCTR to get a compact version of CTR

while i <= n_segments
    if isnan(phis(i))
      if isnan(phis(i+1))
        simple_ctr_segments = simple_ctr_segments + 1;
        simpleCTR(simple_ctr_segments).type      = 'balanced';

        simpleCTR(simple_ctr_segments).u         = fullCTR(i+2).u;
        simpleCTR(simple_ctr_segments).c_len     = fullCTR(i+2).length;
        simpleCTR(simple_ctr_segments).k         = fullCTR(i+2).k;
        simpleCTR(simple_ctr_segments).diameter  = fullCTR(i+2).diameter;
        simpleCTR(simple_ctr_segments).theta     = [thetas(i+2) thetas(i+3)];
        simpleCTR(simple_ctr_segments).phi       = phis(i+2);
        i = i + 4;
        simple_ctr_segments = simple_ctr_segments + 1;
        simpleCTR(simple_ctr_segments).type      = 'fixed';

        simpleCTR(simple_ctr_segments).u         = fullCTR(i+1).u;
        simpleCTR(simple_ctr_segments).c_len     = fullCTR(i+1).length;
        simpleCTR(simple_ctr_segments).k         = fullCTR(i+1).k;
        simpleCTR(simple_ctr_segments).diameter  = fullCTR(i+1).diameter;
        simpleCTR(simple_ctr_segments).theta     = thetas(i+1);
        simpleCTR(simple_ctr_segments).phi       = phis(i+1);
        i = i + 2;

2 NaN phis means the full ctr is a balanced one. In case of 1 NaN phi it means the full ctr is of fixed type. __but is 3rd element of full_ctr is copied to the first element of simple ctr? as in line - simpleCTR(simple_ctr_segments).u = fullCTR(i+2).u;

##CTRCreateMinimizationVectorFromCTR CTRCREATEMINIMIZATIONVECTORFROMCTR(CTR, MOPTS) creates a minimization vector given a concentric tube robot CTR and directions on what to minimize for MOPTS. A simple CTR is input to this method.

Loops through mopts( array of string containing optimization parameters- length , lengths_curved, curvatures) and populates attributes of x_ with values from ctr e.g. x_.lengths_curved = [ctr(:).c_len]

for i = length(mopts):-1:1
    switch mopts{i}
      case 'lengths'
        x_.lengths = zeros(1, 2*length(ctr));
        for j = 1:length(ctr)
          x_.lengths(2*j-1:2*j) = [ctr(j).s_len; ctr(j).c_len];
      case 'lengths_curved'
        x_.lengths_curved = [ctr(:).c_len];
      case 'curvatures'
        x_.curvatures = zeros(1, length(ctr));
        for j = 1:length(ctr)
          x_.curvatures(j) = ctr(j).u;
      case 'base'
        x_.base = HG(:);
Issue - 
1. why is length is initialised with 1 X 2*length size?
2. x_.lengths(2*j-1:2*j) = [ctr(j).s_len; ctr(j).c_len]

The below code is vectorizing the optimization parameters. Question: As all the below isfield() may return true, in that case what will be the structure x look like, will the value be replaced with each isfield() check?

if isfield(x_, 'lengths')
    x = [x; x_.lengths(:)];
  if isfield(x_, 'lengths_curved')
    x = [x; x_.lengths_curved(:)];
  if isfield(x_, 'curvatures')
    x = [x; x_.curvatures(:)];

##CTRCreateCTRFromMinimizationVector The minimization vector return by the above method CTRCreateMinimizationVectorFromCTR is read by this method. A simple ctr and mopts(string array of optimization params)are also an input to this method.

mopts is updated with sorted value of mopts and ctr is initialised with simple ctr(ctr_)

mopts = sort(mopts); 
ctr = ctr_

Issue - Not able to understand the logic for updating ctr with ctr_


This repository contains our software for the computational design of flexible robots based on concentric tube technology.







No releases published


No packages published