Data-driven dynamic modeling and control of a two-segment, tendon-driven continuum robotic arm — B.Sc. thesis project, K. N. Toosi University of Technology (Spring 2024).
Continuum robots exhibit infinite degrees of freedom, making first-principles dynamic modeling extremely challenging. This project takes a data-driven identification approach: rather than deriving equations of motion from first principles, we collect input–output data from the physical robot and fit black-box / grey-box dynamic models to it. Three model families are compared — linear (ARX/ARMAX), quadratic-in-parameters with GA-selected regressors, and NARX neural networks — for two roles: simulator (open-loop multi-step prediction) and predictor (one-step-ahead prediction suitable for real-time MPC).
| Component | Details |
|---|---|
| Robot | Two-segment tendon-driven continuum arm, 6 DOF |
| Backbone | Nitinol (NiTi), 1.3 mm diameter, 525 mm total length |
| Disks | 18 epoxy glass disks, 20 mm diameter, 3 mm thick |
| Motors | 6 × Dynamixel AX-12A (IDs 1–6), 25.69 mm pulleys |
| Load cells | 6 × ZEMIC L6D (one per tendon) |
| Cameras | 2 × USB webcams (XZ-plane and YZ-plane) for end-effector tracking via LED detection |
| Controller | Force feedback PID with low-pass filtering, 0.1 s sample time |
Each tendon's force is regulated by a discrete PID controller (Implementation/Controllers/@DiscretePIDController/DiscretePIDController.m) that closes the loop around its load cell. The controller converts force error (reference minus filtered load cell reading) into a motor position command via Tustin-discretized state-space equations. A low-pass filter (Implementation/Controllers/@NumericFilter/NumericFilter.m) conditions the raw load cell signal before feedback.
Linear regression of 10-bit digital load cell readings against known weights (0–2267 g). Produces per-cell slope/intercept coefficients stored in Data/calibrationData/loadcell/regressionCoeficient.mat.
Scripts/load_cell_calibration/loadCellCalibration.m— interactive data collectionScripts/load_cell_calibration/coefficientCalculation.m— fits linear model viafitlmScripts/load_cell_calibration/plotGenerator.m— plots calibration curves
Equilibrium force points are a uniform 3×3×3×3×3×3 grid over the normalized [0,1] workspace (27 operating points). At each, a band-limited random signal (idinput, RGS, 0–0.4 Hz, ±0.2 amplitude) is applied for 20 s at 0.1 s sample time. Inputs are saturated to [0,1] for motor safety.
Implementation/Procedures/dataGathering/systemIdentification/— main experiment script (main.m→initialization.m→setup.m→loop.m)Implementation/Procedures/dataGathering/methods/signalgenerator/generateInputs.m— creates excitation signalsImplementation/Procedures/dataGathering/methods/signalgenerator/getOperationPoint.m— generates equilibrium grid
Data is logged via the Logger class and saved as .mat files (Data/identificationData/log1.mat, log2.mat).
Data is split sequentially (no shuffling): 70% training, 20% validation, 10% test. Each output channel (x, y, z end-effector position) is modeled independently, with the other two position channels and 6 force channels as inputs.
Models are identified in two roles:
- Predictor (one-step-ahead): uses
compare(data, model, 1)— suitable for real-time model predictive control. - Simulator (open-loop multi-step): uses
compare(data, model)— tests ability to reproduce full trajectories without feedback.
Hyperparameters are optimized via Genetic Algorithm (ga) with parallel computing, typically 40–100 generations, 9–12 hour time limits.
| Model | Role | Script Location | Method |
|---|---|---|---|
| ARMAX | Predictor | Scripts/hyperparam_optimization/Predictors/Armax/ |
MATLAB armax(), 18 integer hyperparameters (na, nb, nc, nk) |
| Quadratic polynomial | Predictor | Scripts/hyperparam_optimization/Predictors/deg 2 poly model/ |
idnlarx with polynomialRegressor (order 2), GA regressor selection (55 binary vars) |
| NARX neural network | Predictor | Scripts/hyperparam_optimization/Predictors/NN model/ |
idnlarx with idNeuralNetwork, GA over lags + layer sizes + activation + regressor usage |
| Quadratic polynomial | Simulator | Scripts/hyperparam_optimization/Simulators/deg 2 polynamial of lag 1 model/ |
Same architecture as predictor, optimized for multi-step simulation |
| NARX neural network | Simulator | Scripts/hyperparam_optimization/Simulators/NN Model/ |
Same as predictor NARX, with Focus = 'simulation' |
Unused/experimental models are in Scripts/hyperparam_optimization/Simulators/unsused Simulator/.
The following test-set fit percentages are from the thesis (ArmanGholibeikian, 2024) and have not been regenerated from this exact codebase:
Simulators (open-loop, multi-step)
| Model | x (%) | y (%) | z (%) |
|---|---|---|---|
| ARX | -4.95 | 50.19 | 45.95 |
| Quadratic | 59.93 | 59.36 | 68.42 |
| NARX | 79.02 | 78.36 | 81.15 |
Predictors (one-step-ahead)
| Model | x (%) | y (%) | z (%) |
|---|---|---|---|
| ARMAX | 85.00 | 89.90 | 91.47 |
| Quadratic | 83.74 | 80.94 | 83.41 |
| NARX | 86.36 | 89.17 | 91.32 |
NARX gives the best simulation accuracy. ARMAX achieves nearly identical one-step prediction performance at much lower computational cost, making it a strong candidate for real-time model predictive control.
Continuum-RoboArm/
├── initializer.m # Adds Data/, Implementation/, Models/ to MATLAB path
├── TODO.m # Known issues and cleanup notes
│
├── Data/
│ ├── +constants/@BackBone/BackBone.m # Backbone physical properties (Nitinol)
│ ├── +constants/@Disks/Disks.m # Disk properties (epoxy glass)
│ ├── +constants/@Motor/Motor.m # Motor/pulley properties
│ ├── calibrationData/loadcell/ # Load cell calibration data & coefficients
│ ├── identificationData/ # Experiment logs (log1.mat, log2.mat)
│ ├── motors/ # Motor identification & step response data
│ ├── camera/ # Camera calibration data
│ └── forceRegulator/ # Force regulator data
│
├── Implementation/
│ ├── Interface/
│ │ ├── @Interface/ # Low-level serial interface (250 kbaud)
│ │ ├── @HighLevelApi/ # Normalized position/force API
│ │ ├── @CameraInterface/ # Dual-camera end-effector tracking
│ │ └── @Logger/ # Data logging class
│ ├── Controllers/
│ │ ├── @DiscretePIDController/ # Discrete PID (Tustin discretization)
│ │ └── @NumericFilter/ # Generic discrete filter
│ └── Procedures/
│ ├── dataGathering/
│ │ ├── systemIdentification/ # Main sys-ID experiment (main/setup/loop)
│ │ ├── methods/signalgenerator/ # Input signal generation & visualization
│ │ ├── methods/logger/ # Logger config for sys-ID
│ │ ├── methods/plotRobot/ # Real-time trajectory plotting
│ │ ├── methods/utils/ # Saturation function
│ │ ├── loadCellIdent.m # Load cell identification experiment
│ │ └── controllerTest.m # PID controller test
│ ├── motorDataGathering/ # Motor position data collection
│ ├── cameraTesting/ # Camera calibration & tracking test
│ └── template/ # Template for new procedures
│
├── Models/
│ └── KInematics/
│ ├── forwardKinematics.m # FK: (phi, theta, r) → (x, y, z) via screw theory
│ ├── inverseKinematics.m # IK: (x, y, z) → (phi, theta, r)
│ ├── CableLengths.m # Tendon lengths from configuration
│ └── invCableLength.m # Configuration from tendon lengths
│
├── Scripts/
│ ├── load_cell_calibration/ # Load cell calibration pipeline
│ ├── motor_speed_controller_optimal_pid/ # PID tuning via particle swarm
│ └── hyperparam_optimization/
│ ├── Predictors/
│ │ ├── Armax/ # ARMAX predictor + GA optimization
│ │ ├── deg 2 poly model/ # Quadratic polynomial predictor + GA
│ │ ├── NN model/ # NARX neural network predictor + GA
│ │ └── unused predictor/ # Sparse regressor (experimental)
│ └── Simulators/
│ ├── NN Model/ # NARX neural network simulator + GA
│ ├── deg 2 polynamial of lag 1 model/ # Quadratic polynomial simulator + GA
│ └── unsused Simulator/ # Experimental simulator variants
│
├── Documents/
│ ├── ArmanGholibeikian_BscThesis.pdf # Bachelor thesis report
│ ├── finalPresent.pptx # Thesis defense presentation
│ ├── dynamixel_ax-12a.pdf # Motor datasheet
│ ├── L6D_Datasheet.pdf # Load cell datasheet
│ └── img/ # Diagrams, GIFs, and plots for README
│
└── Simulation/ # (placeholder, not yet populated)
- MATLAB R2020b+
- Instrument Control Toolbox — for
serialportcommunication with motors/load cells - System Identification Toolbox — for
armax,nlarx,iddata,idnlarx,idNeuralNetwork,linearRegressor,polynomialRegressor - Optimization Toolbox — for
ga(genetic algorithm) andparticleswarm - Control System Toolbox — for
tf,c2d,ss,feedback,lsim - Image Acquisition Toolbox — for
videoinputcamera access (camera testing only)
No requirements.txt or package.json — this is a pure MATLAB project.
% 1. Initialize paths (must run first)
run('initializer.m');
% 2. Connect to hardware (replace COM port)
api = HighLevelApi('COM3');
% 3. Read normalized positions [0,1]
pos = api.readNormalPosition();
% 4. Set position (normalized [0,1])
api.setNormalPositionSync([0.5, 0.5, 0.5, 0.5, 0.5, 0.5]);
% 5. Read normalized forces [0,1]
force = api.readNormalForce();run('initializer.m');
% Step 1: Collect calibration data (interactive — requires hardware)
run('Scripts/load_cell_calibration/loadCellCalibration.m');
% Step 2: Compute regression coefficients
run('Scripts/load_cell_calibration/coefficientCalculation.m');
% Step 3: Visualize calibration curves
run('Scripts/load_cell_calibration/plotGenerator.m');run('initializer.m');
% Run the full experiment — generates excitation signals, logs data
run('Implementation/Procedures/dataGathering/systemIdentification/main.m');
% Saves log to Data/identificationData/log2.matEach model type has a main.m entry point that loads data via getSplitData.m, then runs GA optimization. Run from the model's directory:
% Example: NARX predictor
cd('Scripts/hyperparam_optimization/Predictors/NN model');
main; % Loads data, starts GA with parallel computing
% Example: ARMAX predictor
cd('Scripts/hyperparam_optimization/Predictors/Armax/optimization codes');
main;
% Example: Quadratic polynomial simulator
cd('Scripts/hyperparam_optimization/Simulators/deg 2 polynamial of lag 1 model');
main;Each main.m will prompt whether to initialize from a previous result. Results are saved to results/param.mat and results/iterresults.mat in each model directory.
run('Scripts/motor_speed_controller_optimal_pid/main.m');
% Uses particle swarm optimization to tune PID gains| Document | Path |
|---|---|
| Bachelor thesis report | Documents/ArmanGholibeikian_BscThesis.pdf |
| Defense presentation | Documents/finalPresent.pptx |
Author: Arman Gholibeikian Supervisor: Prof. S. Ali A. Moosavian Institution: K. N. Toosi University of Technology, Faculty of Mechanical Engineering Date: Spring 2024
This project is licensed under the MIT License — see the LICENSE file for details.




