This is an old revision of the document!
Delta Roboter Tutorial - Build your own controller
Preamble
It took about three days to get to know EEROS and another two days to write this tutorial. If you find mistakes or have suggestion for improvement, please take a fraction of your time and edit this tutorial.
Delta's accessories
The package with the delta robot should include:
Ready to play?
You get your delta and of course you want to play with it and see what he can do. You can! But do as listed below:
- First of all: To turn off the delta, press the red stop button for 5 seconds or send a halt command to it and then switch the power off! Don't plug out the power of your computer before it has shut down either.
- The red stop button stops the delta, theoretically it should restart afterwards.
- Please read the safety instructions, chapter 1.2 under Delta Getting Started Tutorial
After that you can start:
- Plug in power and the USB Hub connected with mouse and XBox adapter. Turn the XBox controller on. USB Devices plugged in after the start will not be recognized.
- Switch the power on.
- Wait until the white led's have turned off, during this time the BeagleBoard is starting.
- Press start. Attention delta will be moving!!
- You can now steer with the mouse: Move will move, scroll up and down will change the Z-position and pressing the scroll wheel to left or right will turn the magnet.
- Press the blue mode button. From then on the XBox controller now controls the delta. Move with right stick, up and down with the left stick and LT / RT to turn the Magnet. If this mode is skipped, check if the XBox controller has battery.
- Press the blue mode button again. The delta shows automatic moves. If you press the blue button again it starts the mouse mode again.
Preparations
VM
- 64-bit
- 8GB RAM
- Hard disk VDI (VirtualBox Disk Image) dynamic allocated, 50GB ROM
Linux
- Any 64-Bit Linux Version.
- This tutorial works with Linux Mint 17.2 Rafaela 64Bit mint
- Remark for VM beginners: its easier to work if you allow copy/paste from host to target and vice versa. copy/paste.
- Set your computer name to delta. You can choose another name, but you have to adapt paths during this tutorial.
- Remember your password!
- Remember the snapshot function of Virtual Box? Make a snapshot after the clean Linux installation.
EEROS
- Download EEROS on your VM EEROS
- You don't need comedilib or flink for this tutorial.
- Download EEROS to /home/delta/eeros-framework (execute git clone command in the folder /home/delta). If you use a different location you have to adapt links and references during this tutorial on your own.
- Suggestion: make a snapshot of your VM after a successful download
- To test the EEROS installation, make the hello world tutorial: hello world. Note: your path to EEROS is: /home/delta/eeros-framework, use this path in the extra arguments.
EEDURO
- Download and install EEDURO on your VM from EEDURO and follow the README.md
- As described in README.md, build for Host and Target. Don't execute copy2robot, clean or distclean now!
Putty
- Download and install Putty on your host, not in your VM. putty
Credentials of delta
- Ask your responsible advisor for username, password and IP- Address of the delta.
Connect to delta
Plug in the power supply, the USB hub with mouse and XBox and the lan cable. Then start the delta with the ON button. Wait till the BeagleBoard has booted and the white light has turned off. The connection procedure depends the knowledge of the IP-Address. If you know it, you're lucky and you can proceed to Connect to console.
Remark to NTB students: with own laptop, you have to connect with VPN, otherwise it will not work.
Get delta's IP-Address
With TTL232 and mini USB
Turn off the power and remove all cables. Turn the delta upside down and open the bottom. Remove the BeagleBone Board and connect the mini USB and the TTL232
(see Delta's accessories) to a computer.
If your computer doesn't recognize the TTL232, you have to install a driver try this link.
Open your device manager and get the number of the COM, on which TTL232 is plugged in.
Then open Putty and connect with the following settings:
Press Open. Follow the instructions under login.
After that, you want to get the IP-Address of delta. type “ifconfig” and press enter. The IP-Address appears in the section: eth0, inetaddr.
Only with mini USB
Note: there is a way to get the delta's IP-Address without the TTL232, but over micro USB and the IP-Address of the USB-Adapter. If you have to do it because you don't have a TTL232, please make an instruction here.
- Connect the mini USB with the PC.
- Then open Putty and enter the IP address 192.168.7.2 and choose as Connection type SSH (see image). You will get a security warning, click yes. Then follow the instructions under login.
- Tip to black window the the following instruction. Under the point eth0 you can find the IP-Adresse.
"ifconfig"
. Note: If you are using Linux running on a VM, there could be some issues to connect the Delta-Roboter with the PC. Try to get remote control with Windows (driver needed) or get the serial connection done over TTL232.
Connect to console
From VM
Usually you want to connect the delta with the VM. To do so, open a console and type:
"ssh root@the.ip.of.delta"
. Then follow the instructions under login.
From Host
Login
The first time you do this you will see a security alert in the putty console - press “Yes”. Then the following appears on the putty console:
"login as:"
Write the username you got from your advisor and hit enter. Then enter the password and confirm with enter. Don't be alarmed if the console does not response while you type your password.
If you logged in successfully, the console will show up like this:
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.8.13-bone63 armv7l) * Documentation: https://help.ubuntu.com/ Last login: Wed Oct 7 11:34:45 2015 from 146.136.53.139 root@arm:~#
Test programms
The delta has test programms, which allow you to test several things. They are a perfect entry point. Open your VM and connect to the delta. Navigate to the folder /opt/eeduro/bin with:
$ cd /opt/eeduro/bin/
List the files in this folder with
$ ls
The following will be shown:
button eeduro-ctrl eeduro-delta encoder led magnet voltage
The green color means that the files are executable, see more under colors linux files.
To execute these test programms, you have to stop the actual program. Which starts every time you start delta.
- Type:
$ screen -r eeduro
- The console will write a lot of text. To stop it, press (Ctrl) + © for about 2-3 seconds.
- The programm is stopped if you can
screen is terminating] root@arm:/opt/eeduro/bin\# ^C
on your console.
Now load the button test program. Type:
$ ./button
If everything works fine, you can press the buttons and you get a log on the console:
button 1: down button 1: up
You can see the source code of the button test programm here: /home/delta/eeduro-project/eeduro/test/button.cpp
You can also try out the other programms too.
Remark: Its not possible anymore to halt delta by pressing the button for 5 seconds. Instead type “halt” in the console and then turn the power off.
Problems
If your testprogram does not work, check README.md.
Toolchain
Now you want to write you own programm. But first you have to set up the toolchain.
- Start KDevelop. If you still have the last session from "Hello World" open, click: Session, Start New Session.
- Now click: Project, Open / Import Project.
- Navigate to: /home/delta/eeduro-project and select CMakeLists.txt. Press Next.
- Name the new Project “eeduro-project”, click Finish.
- Change Build Directory to /home/delta/eeduro-project/build-armhf/
- Put the following to the extra arguments input field:-DCMAKE_TOOLCHAIN_FILE=/home/delta/eeduro-project/linaro-tc/toolchain.cmake -DADDITIONAL_INCLUDE_DIRS=“/home/delta/eeduro-project/eeduro/eeduro/include/;/home/delta/eeduro-project/eeros/includes/” -DADDITIONAL_LINK_DIRS=“/home/delta/eeduro-project/build-armhf/eeros/src/;/home/delta/eeduro-project/build-armhf/eeduro/eeduro/“ It's no typo, one folder is actually called include and the other includes.
ATTENTION: be sure to have the Linux Double Quotes, copy and paste can modify them! - Build.
- If you open the project view in KDevelop, you can unfold the eeduro-project and open copy2robot.sh.
- Change the setc remote_host “192.168.7.2” to your IP-Address and save.
- Execute the copy2robot script with the console.
- Now you have to go trough the chapter test programms again. If it works, you have done everything right.
Remark: Now is a good time to make another snapshot of your VM.
Problems
Be really careful with the additional includes, check if these files are where you expect them an check for typos.
Your own testprogramm
Now create a new testprogramm. The LED's inside the buttons should glow while they are pressed.
Go to the folder /home/delta/eeduro-project/eeduro/test and create a new file button_led.cpp.
Copy the following code into this file and program the missing fragment.
#include <iostream>
#include <unistd.h>
#include <eeduro/Board.hpp>
int main(int argc, char *argv[])
{
eeduro::Board board;
if (!board.open("/dev/spidev1.0")) {
std::cerr << "cannot open SPI device " << std::endl;
return 1;
}
bool button[3] = { };
while (true) {
board.run();
for (int i = 0; i < 3; i++) {
do it yourself!
}
usleep(30000);
}
board.close();
return 0;
}
Note: if you are not able to write the code in on your own, the source code is in the appendix.
Then open CMakeList which is in the same folder. Add the following code to the end of the file:
add_executable(button_led button_led.cpp) target_link_libraries(button_led eeduro eeros)
Now go to copy2robot.sh and past the following line under the line with voltage:
cp build-armhf/eeduro/test/button_led $tmpdir/bin
Execute copy2robot.sh. (Like here), connect to delta and check if button_led was successfully copied into /opt/eeduro/bin.
Now try to run the new test programm, as described here.
Hello Structure
Readers with experience in cmake can skip this chapter.
Bigger projects need to be well structured, so you have to organize your code in folders.
Lets create a project with this structure:
Create a new project in KDevelop, as usual, with Projects, Create New Project, Standard Terminal and enter the name structure_project in the location /home/delta/projects. Set the same Extra Arguments as before. The EEDURO include is useless now, but you may want to extend this project later.
Now navigate to the new folder structure. As you can see, KDevelop has already created CMakeLists.txt(structure), main.cpp and structure.kdev4.
Create two folders one called “src” and the other called “include”. Move main.cpp into src, then open src. Create the following empty files: CMakeLists.txt,
ControlSystem.cpp and SafetyProperties.cpp. Open the folder “include” and create another folder called “structure_project”. Here you create ControlSystem.hpp and SafetyProperties.hpp. The .cpp and .hpp (except main.cpp) have no functionality but are a good basis when you want to extend this project.
Open the CMakeLists.txt(src) and paste the following into it:
add_executable(structure main.cpp ControlSystem.cpp SafetyProperties.cpp) target_link_libraries(structure eeros eeduro)
ControlSystem.cpp and SafetyProperties.cpp in add_executable are just written here that you see how you add them when you need these classes. “structure” is the name of the executable that will be builded. Once again, the target_link_libraries eeduro is useless, you don't need it now. Open the CMakeLists.txt(structure_project) and paste the following into it:
cmake_minimum_required(VERSION 2.8)
project(structure)
include_directories(${ADDITIONAL_INCLUDE_DIRS})
link_directories(${ADDITIONAL_LINK_DIRS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_subdirectory(src)
With add_subdirectory, you specifiy which folders should be included. They need to have their own CMakeLists.txt.
Open the main.cpp and paste the same code as in Hello World into it:
#include <iostream>
#include <eeros/logger/Logger.hpp>
#include <eeros/logger/StreamLogWriter.hpp>
int main() {
using namespace eeros::logger;
StreamLogWriter w(std::cout);
Logger<LogWriter>::setDefaultWriter(&w);
Logger<LogWriter> log;
log.info() << "Hello, EEROS";
return 0;
}
Build and try to execute. Don't remember how? See hello world.
Motor Control
When you create your first controller, you will see the strength of EEROS - it's block schemes.
For that, remove the delta's arms, (3), see figure below
.
Controller
We want implement a P-Controller to control the velocity of the driving side. In the figure below, you can see a block diagram of the control system.

Important is, that the speed and position are measured on the motor side. If you want to control the speed/position of the axis, you have to the gear and its gear transmission ratio into account.
In the next figure, you see a scheme of the motors used in the delta.
,
We have the following components in the control system:
| Board Speedout Block | Reads the speed of the four motors of the delta. This is a eeros::math::Matrix<NOF_AXIS, 1, double> with NOF_AXIS = 4. You see on your delta, that the motors are enumerated. If you want to read the speed of motor 1, you have to read out the value at position 0 of this matrix. | |
| Board In Block | This is where you set the values of the voltage for each motor. Its a 4×1 Matrix again. | |
| Constant c | [CONSTANT] | This is the specified value of the rotation speed. In a later step you can exchange this fix value with a trajektorien generator. |
| demux | [DEMUX] | In the booster phase, you want to control one of the motors, the one with the number 1. To do so, you split the incoming board speed up with this demux. |
| mux | [MUX] | The inverse of the demux. |
| gear | [GAIN] | You can control the position/speed on the other side of the gear. |
| inverseGear | [GAIN] | You still have to set the values for the motor. |
| sum1 | [SUM] | Calculates the variance. |
| kv | [GAIN] | Cruise control system with a proportional controller. |
| inertia | [GAIN] | Mass moment of inertia, motor and system. |
| saturation | [SATURATION] | Limit the upper and lower bounds of the Voltage. |
| motormodel | [MOTORMODEL] | Calculates the needed voltage of the motor from given motor speed and torque. |
The Delta-Roboter is using a DC-Motor from Faulhaber (1524012SR) with the gear 15/8. He has the following physical Parameters:
| nominal voltage | UM1 | 12 VDC |
| ferrule resistor | RM | 19.8 Ω |
| motor constant | kM | 11.4 mN/A |
| moment of inertia | J | 0.65 gcm2 |
| gear Ratio | i | 76 |
Structure
Create a project with the following structure or extend one of your existing projects. You need this structure and these classes:
Try to specify the CMakeLists on your own or adapt an existing one. If you fail, the code is in the appendix.
Constants
In the file constants.hpp, we specify all constant values. All other classes use just the constant name to get the value. The advantage is, that you can change your value in a single file and don't need to search through all you code.
// values from: //http://www.glockenankermotor.com/pdf/01_DC-Kleinstmotoren/01_DC-Kleinstmotoren/EN_1524SR_DFF.pdf?XTCsid=b756fdbe0a224d9bf142067327118796 //https://fmcc.faulhaber.com/resources/img/DE_15-8_FMM.PDF //http://wiki.ntb.ch/stud/_media/omnimobot/masterthesis_stefan_landis.pdf // Controller parameters constexpr double dt = 0.001; // [s] constexpr double dOpt = 0.7; //optimalerDaemphungswert constexpr double omega0 = 357.0; //[rad/s]; constexpr double kvValue = 2.0*omega0*dOpt; // Electrical and mechanical parameters constexpr double i1524 = 387283.0/5103.0; // gear ratio for the 3 main axis --> 76 constexpr double kM1524 = 11.4e-3; // [NM/A]; constexpr double RA1524 = 19.8; // [Ohm] constexpr double stallTorqueMotor1524 = 6.76e-3;// [NM] constexpr double stallTorqueGear1524 = 100e-3;// [NM] constexpr double maxStallTorque1524 = stallTorqueMotor1524<i1524*stallTorqueGear1524?stallTorqueMotor1524:stallTorqueGear1524*i1524; constexpr double rotorInertia1524 = 0.65e-7;// [NM] constexpr double inertiaValue1524 = rotorInertia1524*i1524*i1524; constexpr double motorModelValue1524 = rotorInertia1524*i1524*i1524;
MotorModel
There is no EEROS block for a MotorModel, so you have to create it on your own.
The function of this block is to calculate the voltage when torque and actual speed are given. The calculation is based on Masterthesis Stefan Landis.
The MotorModel.hpp:
#include <eeros/control/Block1i1o.hpp>
class MotorModel : public eeros::control::Block {
public:
MotorModel(const double kM, const double RA);
virtual eeros::control::Input<double>& getTorqueIn();
virtual eeros::control::Input<double>& getSpeedIn();
virtual eeros::control::Output<double>& getOut();
virtual void run();
protected:
eeros::control::Input<double> torque;
eeros::control::Input<double> speed;
eeros::control::Output<double> voltage;
double kM, RA;
};
};
As you can see, you extend the block class here.
And the MotorModel.cpp:
#include "SimpleControlSystem/MotorModel.hpp"
MotorModel::MotorModel(const double kM, const double RA) : kM(kM), RA(RA) { }
eeros::control::Input<double>& MotorModel::getSpeedIn() {
return speed;
}
eeros::control::Input<double>& MotorModel::getTorqueIn() {
return torque;
}
eeros::control::Output<double>& MotorModel::getOut() {
return voltage;
}
void MotorModel::run() {
double u, M, w;
M = torque.getSignal().getValue();
w = speed.getSignal().getValue();
u = RA * M / kM + w * kM;
voltage.getSignal().setValue(u);
voltage.getSignal().setTimestamp(torque.getSignal().getTimestamp());
}
SimpleControlSystem
In SimpleControlSystem.hpp you define the instances, methods and the constructor. The public constructor gets the argument double ts, and there are three public void methods: start(), stop() and initBoard(). It has these public instances:
//Sum with 2 inputs, typename double eeros::control::Sum<2,double> sum1; eeros::control::Gain<> kv; eeros::control::Gain<> inertia; eeros::control::Gain<> gear; eeros::control::Gain<> inverseGear; eeros::control::Saturation<double> saturation; MotorModel motormodel; // typename double eeros::control::Constant<double> c; //define 4 outputs (double) and the inpout is a 4x1 Matrix (double) eeros::control::DeMux<4,double,eeros::math::Matrix<4,1,double>> demux; //define 4 inputs (double) and the output is a 4x1 Matrix (double) eeros::control::Mux<4,double,eeros::math::Matrix<4,1,double>> mux; // typename double eeros::control::Constant<double> voltage; // Blocks eeduro::Board board;
Additionally, it has a private instance of the TimeDomain. In the TimeDomain you have to specify the order of the calculation of your blocks.
eros::control::TimeDomain timedomain;
Can this code fragment be optimized? Did you hear about the namespace declarations?
In SimpleControlSystem.cpp you exactly specify the blocks from your controller scheme. Step 1 is to initialize all your blocks
... //init the blocks gear(i1524), saturation(upper-,and lower bound), do the same with inverseGear, kv, inertia, motormodel ...
Step 2 is to define the block properties:
... // Define blocks properties sum1.negateInput(1); c.setValue(0.5); ...
Step 3 is to define the block connections:
... demux.getIn().connect(board.getSpeedOut()); gear.getIn().connect(demux.getOut(0)); sum1.getIn(1).connect(gear.getOut()); sum1.getIn(0).connect(c.getOut()); kv.getIn().connect(sum1.getOut()); continue here with inertia --> inverseGear --> saturation --> motorModel (2 inputs/1 output) --> mux and finally board.getIn().connect(mux.getOut()); ...
Step 4 is to add the blocks to the run method. You do that by adding the blocks to the timeDomain. The order is really important, you can't get values from a block that is not calculated.
... // Add blocks to run method timedomain.addBlock(&board); timedomain.addBlock(&demux); ... more here .. timedomain.addBlock(&voltage); timedomain.addBlock(&mux); ...
As a last step you have to implement the three methods start() stop() and initBoard(). Cheat here and look how its done in eeduro-project/eeduro/delta/ControlSystem.cpp
The source code of the SimpleControlSystem.hpp and SimpleControlSystem.cpp are in the appendix, but you will understand nothing if you just copy and paste it…
main.cpp
First of all, you have to make sure, that the Linux command (Ctrl) + © can stop your program. To do so, create a boolean “running” then a signalHandler which sets running to false if it is called. Finally, you have to set this handler to the system with the call signal(SIGINT, signalHandler); This is the first step in your main method. In all your loops in the main.cpp you have to check this value.
The second step in the main method is to specify and start the loggers. The easiest way is to cheat and copy it from the delta.cpp file in the eeduro-project/eeduro/delta/ folder
Step three is to create an instance of SimpleControlSystem and initialize it. delta.cpp uses the ControlSystem. Instead of that, main.cpp should use the SimpleControlSystem created before. Call it controlSys. Initialize the hardware:
//initialize hardware controlSys.initBoard(); controlSys.start(); controlSys.board.setReset(false); controlSys.board.setEnable(true);
Then your program should run as long as you don't press (Ctrl) + ©. Do this with a while loop
while (running) {
//debug log here
sleep(1);
}
The debug output calls are in the appendix, they are really useful!
At the end of your main, you need to close the board.
// close hardware controlSys.board.setReset(true); controlSys.board.setEnable(false); controlSys.board.run(); controlSys.board.close();
The source code of the main.cpp isin the appendix, but you will understand nothing if you just copy and paste it…
That's it! Now you have realized your own motor controller.
Appendix
Code Appendix
button_led.cpp
#include <iostream>
#include <unistd.h>
#include <eeduro/Board.hpp>
int main(int argc, char *argv[])
{
eeduro::Board board;
if (!board.open("/dev/spidev1.0")) {
std::cerr << "cannot open SPI device " << std::endl;
return 1;
}
bool button[3] = { };
while (true) {
board.run();
for (int i = 0; i < 3; i++) {
if (button[i] != board.button[i]) {
if (board.button[i]) {
board.led[i] = 1;
} else {
board.led[i] = 0;
}
button[i] = board.button[i];
}
}
usleep(30000);
}
board.close();
return 0;
}
Motor Controll CMakeFiles
CMakeLists.txt(simpleproject)
cmake_minimum_required(VERSION 2.8)
project(simplesystem)
include_directories(${ADDITIONAL_INCLUDE_DIRS})
link_directories(${ADDITIONAL_LINK_DIRS} "${CMAKE_BINARY_DIR}/src/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(include)
add_subdirectory(src)
CMakeLists.txt(src)
add_library(simplesystem-lib MotorModel.cpp SimpleControlSystem.cpp ) add_executable(simplesystem main.cpp SimpleControlSystem.cpp MotorModel.cpp) target_link_libraries(simplesystem eeros eeduro simplesystem-lib)
SimpleControlSystem
SimpleControlSystem.hpp
#ifndef MYCONTROLSYSTEM_HPP_
#define MYCONTROLSYSTEM_HPP_
#include <eeros/control/Sum.hpp>
#include <eeros/control/D.hpp>
#include <eeros/control/Gain.hpp>
#include <eeros/control/Constant.hpp>
#include <eeros/control/PeripheralInput.hpp>
#include <eeros/control/PeripheralOutput.hpp>
#include <eeros/control/TimeDomain.hpp>
#include <eeros/control/Saturation.hpp>
#include <eeduro/Board.hpp>
#include <eeros/control/Constant.hpp>
#include <eeros/control/DeMux.hpp>
#include <eeros/control/Mux.hpp>
#include "MotorModel.hpp"
class SimpleControlSystem {
public:
SimpleControlSystem(double ts);
void start();
void stop();
void initBoard();
//Sum with 2 inputs, typename double
eeros::control::Sum<2,double> sum1;
eeros::control::Gain<> kv;
eeros::control::Gain<> inertia;
eeros::control::Gain<> gear;
eeros::control::Gain<> inverseGear;
eeros::control::Saturation<double> saturation;
MotorModel motormodel;
// typename double
eeros::control::Constant<double> c;
//define 4 outputs (double) and the inpout is a 4x1 Matrix (double)
eeros::control::DeMux<4,double,eeros::math::Matrix<4,1,double>> demux;
//define 4 inputs (double) and the output is a 4x1 Matrix (double)
eeros::control::Mux<4,double,eeros::math::Matrix<4,1,double>> mux;
// typename double
eeros::control::Constant<double> voltage;
// Blocks
eeduro::Board board;
protected:
private:
eeros::control::TimeDomain timedomain;
};
#endif // MYCONTROLSYSTEM_HPP_
SimpleControlSystem.cpp
#include "simplesystem/SimpleControlSystem.hpp"
#include "simplesystem/constants.hpp"
using namespace eeros::control;
SimpleControlSystem::SimpleControlSystem(double ts) :
//init the blocks
gear(i1524),
inverseGear(1.0/i1524),//TODO lw constanten verwenden
saturation(0.1,-0.1), //TODO abklaeren warum min, max und nicht wie in der doku max, min und warum trotzdem beides laeuft?
kv(2.0*0.7*357.0),
inertia(0.65*0.0000001*76.0*76.0),
motormodel(11.4*0.001, 19.8),
timedomain("Main time domain", ts, true) {
// Define blocks properties
sum1.negateInput(1);
c.setValue(0.5);
// Define block connections
demux.getIn().connect(board.getSpeedOut());
gear.getIn().connect(demux.getOut(0));
sum1.getIn(1).connect(gear.getOut());
sum1.getIn(0).connect(c.getOut());
kv.getIn().connect(sum1.getOut());
inertia.getIn().connect(kv.getOut());
inverseGear.getIn().connect(inertia.getOut());
saturation.getIn().connect(inverseGear.getOut());
motormodel.getSpeedIn().connect(demux.getOut(0));
motormodel.getTorqueIn().connect(saturation.getOut());
mux.getIn(0).connect(motormodel.getOut());
board.getIn().connect(mux.getOut());
// Add blocks to run method
timedomain.addBlock(&board);
timedomain.addBlock(&demux);
timedomain.addBlock(&gear);
timedomain.addBlock(&c);
timedomain.addBlock(&sum1);
timedomain.addBlock(&kv);
timedomain.addBlock(&inertia);
timedomain.addBlock(&inverseGear);
timedomain.addBlock(&saturation);
timedomain.addBlock(&motormodel);
timedomain.addBlock(&voltage);
timedomain.addBlock(&mux);
}
void SimpleControlSystem::start() {
timedomain.start();
}
void SimpleControlSystem::stop() {
timedomain.stop();
}
void SimpleControlSystem::initBoard() {
if(!board.open("/dev/spidev1.0"))
throw -1;
}
Debug Calls main.cpp
//read out the position of all motors eeros::math::Matrix<4,1,double> enc = controlSys.board.getPosOut().getSignal().getValue(); std::cout << "enc: " << enc(0) << "; " << enc(1) << "; " << enc(2) << "; " << enc(3) << std::endl; //get the value of the constant std::cout << "soll : " << controlSys.c.getOut().getSignal().getValue() << std::endl; //check the speed out from the board std::cout << "ist : " << controlSys.board.getSpeedOut().getSignal().getValue()[0] << "; " << controlSys.board.getSpeedOut().getSignal().getValue()[1] << "; " << controlSys.board.getSpeedOut().getSignal().getValue()[2] << "; " << controlSys.board.getSpeedOut() .getSignal().getValue()[3] << std::endl; //check the value of out of the demux std::cout << "demux out: " << controlSys.demux.getOut(0).getSignal().getValue() << "; " << controlSys.demux.getOut(1).getSignal().getValue() << "; " << controlSys.demux.getOut(2).getSignal().getValue() << "; " << controlSys.demux.getOut(3).getSignal().getValue() << std::endl; // checkt the values from gear std::cout << "gear in : " << controlSys.gear.getIn().getSignal().getValue() << std::endl; std::cout << "gear out : " << controlSys.gear.getOut().getSignal().getValue() << std::endl; // check the calculation inside sum1 block std::cout << "sum in 0 : " << controlSys.sum1.getIn(0).getSignal().getValue() << std::endl; std::cout << "sum in 1 : " << controlSys.sum1.getIn(1).getSignal().getValue() << std::endl; std::cout << "sum out : " << controlSys.sum1.getOut().getSignal().getValue() << std::endl; //check the calculation inside kv block std::cout << "kv in : " << controlSys.kv.getIn().getSignal().getValue() << std::endl; std::cout << "kv out: " << controlSys.kv.getOut().getSignal().getValue() << std::endl; //check the calculation inside gear block std::cout << "inertia in : " << controlSys.inertia.getIn().getSignal().getValue() << std::endl; std::cout << "inertia out: " << controlSys.inertia.getOut().getSignal().getValue() << std::endl; //checkt the values from inverseGear std::cout << "inverseGear in : " << controlSys.inverseGear.getIn().getSignal().getValue() << std::endl; std::cout << "inverseGear out : " << controlSys.inverseGear.getOut().getSignal().getValue() << std::endl; //checkt the values from saturation std::cout << "saturation in : " << controlSys.saturation.getIn().getSignal().getValue() << std::endl; std::cout << "saturation out : " << controlSys.saturation.getOut().getSignal().getValue() << std::endl; //check the calculation inside motormodel block std::cout << "motormodel in M : " << controlSys.motormodel.getTorqueIn().getSignal().getValue() << std::endl; std::cout << "motormodel in q': " << controlSys.motormodel.getSpeedIn().getSignal().getValue() << std::endl; std::cout << "motormodel out : " << controlSys.motormodel.getOut().getSignal().getValue() << std::endl;
main.cpp
#include <iostream>
#include <ostream>
#include <fstream>
#include <stdlib.h>
#include <unistd.h>
#include <eeros/hal/HAL.hpp>
#include <eeros/safety/SafetySystem.hpp>
#include <eeros/logger/StreamLogWriter.hpp>
#include "simplesystem/SimpleControlSystem.hpp"
#include <eeros/logger/SysLogWriter.hpp>
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace eeros;
using namespace eeros::hal;
using namespace eeros::control;
using namespace eeros::safety;
using namespace eeros::logger;
// enable to stop the program with ctrl c
volatile bool running = true;
// handler on press on ctrl c that will set running to false
void signalHandler(int signum) {
running = false;
}
int main() {
//set the interrupt handler
signal(SIGINT, signalHandler);
//start the loggers
StreamLogWriter w(std::cout);
SysLogWriter s("delta");
w.show();
s.show();
Logger<LogWriter>::setDefaultWriter(&w);
Logger<LogWriter> log('M');
log.trace() << "Application sismplesystem started...";
// create control system
//TODO lw 0.001 durch dt ersetzten und testen
SimpleControlSystem controlSys(0.001);
// initialize hardware
controlSys.initBoard();
controlSys.start();
controlSys.board.setReset(false);
controlSys.board.setEnable(true);
while (running) {
/* //read out the position of all motors
eeros::math::Matrix<4,1,double> enc = controlSys.board.getPosOut().getSignal().getValue();
std::cout << "enc: " << enc(0) << "; " << enc(1) << "; " << enc(2) << "; " << enc(3) << std::endl;
//get the value of the constant
std::cout << "soll : " << controlSys.c.getOut().getSignal().getValue() << std::endl;
//check the speed out from the board
std::cout << "ist : " << controlSys.board.getSpeedOut().getSignal().getValue()[0] << "; " << controlSys.board.getSpeedOut().getSignal().getValue()[1] << "; " << controlSys.board.getSpeedOut().getSignal().getValue()[2] << "; " << controlSys.board.getSpeedOut().getSignal().getValue()[3] << std::endl;
//check the value of out of the demux
std::cout << "demux out: " << controlSys.demux.getOut(0).getSignal().getValue() << "; " << controlSys.demux.getOut(1).getSignal().getValue() << "; " << controlSys.demux.getOut(2).getSignal().getValue() << "; " << controlSys.demux.getOut(3).getSignal().getValue() << std::endl;
// checkt the values from gear
std::cout << "gear in : " << controlSys.gear.getIn().getSignal().getValue() << std::endl;
std::cout << "gear out : " << controlSys.gear.getOut().getSignal().getValue() << std::endl;
// check the calculation inside sum1 block
std::cout << "sum in 0 : " << controlSys.sum1.getIn(0).getSignal().getValue() << std::endl;
std::cout << "sum in 1 : " << controlSys.sum1.getIn(1).getSignal().getValue() << std::endl;
std::cout << "sum out : " << controlSys.sum1.getOut().getSignal().getValue() << std::endl;
//check the calculation inside kv block
std::cout << "kv in : " << controlSys.kv.getIn().getSignal().getValue() << std::endl;
std::cout << "kv out: " << controlSys.kv.getOut().getSignal().getValue() << std::endl;
//check the calculation inside gear block
std::cout << "inertia in : " << controlSys.inertia.getIn().getSignal().getValue() << std::endl;
std::cout << "inertia out: " << controlSys.inertia.getOut().getSignal().getValue() << std::endl;
//checkt the values from inverseGear
std::cout << "inverseGear in : " << controlSys.inverseGear.getIn().getSignal().getValue() << std::endl;
std::cout << "inverseGear out : " << controlSys.inverseGear.getOut().getSignal().getValue() << std::endl;
//checkt the values from saturation
std::cout << "saturation in : " << controlSys.saturation.getIn().getSignal().getValue() << std::endl;
std::cout << "saturation out : " << controlSys.saturation.getOut().getSignal().getValue() << std::endl;
//
//check the calculation inside motormodel block
std::cout << "motormodel in M : " << controlSys.motormodel.getTorqueIn().getSignal().getValue() << std::endl;
std::cout << "motormodel in q': " << controlSys.motormodel.getSpeedIn().getSignal().getValue() << std::endl;
std::cout << "motormodel out : " << controlSys.motormodel.getOut().getSignal().getValue() << std::endl;
*/
sleep(1);
}
//close hardware
controlSys.board.setReset(true);
controlSys.board.setEnable(false);
controlSys.board.run();
controlSys.board.close();
return 0;
}










