The robotic platform Robotino is a nice omnidirectional Robot manufactured by the company Festo. It was surprising for me to find out that the Robot Simulator VREP doesn’t have a working model of this robot, even though there exist an opensource model of this robot for the simulator Gazebo.
Just like I did before for a Quadcopter, now I implemented a model of the Robotino for Vrep based on the URDF model from Gazebo. The simulation of the omnidirectional wheels was based on the Kuka Youbot available in Vrep. Additionally I programmed a control script using velocity Twist reference messages from ROS, so just like the quadrotor it is possible to control this robot from ROS using a Joystick (or your custom Node).
Robotino Model in Vrep
This is the control script that I programmed in the Robotino Model:
-- DO NOT WRITE CODE OUTSIDE OF THE if-then-end SECTIONS BELOW!! (unless the code is a function definition)
if (sim_call_type==sim_childscriptcall_initialization) then
-------- START OF ROS INITIALIZATION --------------------------------
-- Check if the required plugin is there (libv_repExtRos.so or libv_repExtRos.dylib):
local moduleName=0
local moduleVersion=0
local index=0
local pluginNotFound=true
while moduleName do
moduleName,moduleVersion=simGetModuleName(index)
if (moduleName=='Ros') then
pluginNotFound=false
end
index=index+1
end
if (pluginNotFound) then
-- Display an error message if the plugin was not found:
simDisplayDialog('Error','ROS plugin was not found.&&nSimulation will not run properly',sim_dlgstyle_ok,false,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
else
-- Enable topic subscription:
simExtROS_enableSubscriber("/robotino_cmd_twist",1,simros_strmcmd_set_twist_command,-1,-1,'Command_Twist')
end
-------- END OF ROS INITIALIZATION --------------------------------
-- Put some initialization code here
-- Make sure we have version 2.4.12 or above (the omni-wheels are not supported otherwise)
v=simGetIntegerParameter(sim_intparam_program_version)
if (v<20412) then
simDisplayDialog('Warning','The YouBot model is only fully supported from V-REP version 2.4.12 and above.&&nThis simulation will not run as expected!',sim_dlgstyle_ok,false,'',nil,{0.8,0,0,0,0,0})
end
wheelJoints={-1,-1,-1}
wheelJoints[1]=simGetObjectHandle('wheel0_joint')
wheelJoints[2]=simGetObjectHandle('wheel1_joint')
wheelJoints[3]=simGetObjectHandle('wheel2_joint')
robotino_handle = simGetObjectHandle('robotino')
-- Make sure you read the section on "Accessing general-type objects programmatically"
-- For instance, if you wish to retrieve the handle of a scene object, use following instruction:
--
-- handle=simGetObjectHandle('sceneObjectName')
--
-- Above instruction retrieves the handle of 'sceneObjectName' if this script's name has no '#' in it
--
-- If this script's name contains a '#' (e.g. 'someName#4'), then above instruction retrieves the handle of object 'sceneObjectName#4'
-- This mechanism of handle retrieval is very convenient, since you don't need to adjust any code when a model is duplicated!
-- So if the script's name (or rather the name of the object associated with this script) is:
--
-- 'someName', then the handle of 'sceneObjectName' is retrieved
-- 'someName#0', then the handle of 'sceneObjectName#0' is retrieved
-- 'someName#1', then the handle of 'sceneObjectName#1' is retrieved
-- ...
--
-- If you always want to retrieve the same object's handle, no matter what, specify its full name, including a '#':
--
-- handle=simGetObjectHandle('sceneObjectName#') always retrieves the handle of object 'sceneObjectName'
-- handle=simGetObjectHandle('sceneObjectName#0') always retrieves the handle of object 'sceneObjectName#0'
-- handle=simGetObjectHandle('sceneObjectName#1') always retrieves the handle of object 'sceneObjectName#1'
-- ...
--
-- Refer also to simGetCollisionhandle, simGetDistanceHandle, simGetIkGroupHandle, etc.
--
-- Following 2 instructions might also be useful: simGetNameSuffix and simSetNameSuffix
old_velx = 0
old_vely = 0
old_vel_angz = 0
acc_x = 0
acc_y = 0
acc_omega = 0
end
if (sim_call_type==sim_childscriptcall_actuation) then
-- Put your main ACTUATION code here
-- From CMDVEL
-- Signals from ROS
local packedData=simGetStringSignal('Command_Twist')
if (packedData) then
local ref_twist=simUnpackFloats(packedData)
-- Process the twist data
-- X and Y velocities (related to the heading of the robotino)
ref_velx = ref_twist[1]*0.18 --reference values between 0 and 1, Max Vel = 0.18 m/s
ref_vely = ref_twist[2]*0.18
-- Angular velocity in Z (this changes the heading of the robotino)
ref_angz = ref_twist[6]
end
-- Robotino Model (Open Loop control)
omega = ref_angz
vx = ref_velx
vy = ref_vely
-- Sets the distance from robot center to wheel center.
rb = 0.13
-- Sets the radius of the wheels.
rw = 0.040
-- Sets the gear.
gear = 0.11 --revisar este numero
-- Projection matrix
v0 = { -0.5 * math.sqrt(3), 0.5 }
v1 = { 0.0 , -1.0 }
v2 = { 0.5 * math.sqrt( 3.0 ), 0.5 }
-- Scale omega with the radius of the robot
vOmegaScaled = rb * omega
--Convert from m/s to RPM
k = 60.0 * gear / ( 2.0 * math.pi * rw )
--Compute the desired velocity
m1 = (v0[1] * vx + v0[2] * vy + vOmegaScaled ) * k
m2 = (v1[1] * vx + v1[2] * vy + vOmegaScaled ) * k
m3 = (v2[1] * vx + v2[2] * vy + vOmegaScaled ) * k
-- Transformation to obtain velocities related to the quadrotor heading
--------------------------------------------------------------------------
-- Orientation of the quadcopter related to the World
euler_robotino = simGetObjectOrientation(robotino_handle,-1)
-- We create a Transformation Matrix from this orientation
pos_robotino=simGetObjectPosition(robotino_handle,-1)
m_heading = simBuildMatrix(pos_robotino,euler_robotino)
-- We create a Transformation Matrix for converting the global referenced velocities
-- to a reference frame based on the heading of the quadrotor
global_pos = {0,0,0}
m_global = simBuildMatrix(global_pos,euler_robotino)
m = simGetInvertedMatrix(m_global)
vel_global, vel_angz = simGetObjectVelocity(robotino_handle)
vel_local=simMultiplyVector(m,vel_global)
-- Velx Control
error_x = ref_velx - vel_local[1]
velxControl = error_x*0.1 +acc_x*0.01 + (vel_local[1]-old_velx)*0.001
old_velx = vel_local[1]
acc_x = error_x+acc_x
-- Vely Control
error_y = ref_vely - vel_local[2]
velyControl = error_y*0.1 +acc_y*0.01 + (vel_local[2]-old_vely)*0.001
old_vely = vel_local[2]
acc_y = error_y+acc_y
-- Omega Velocity Control
error_omega = ref_angz - vel_angz[3]
rotControl = error_omega*0.05 +acc_omega*0.01 -- (vel_local[3]-old_vel_angz)*1.1
old_vel_angz = vel_angz[3]
acc_omega = error_omega+acc_omega
-- Robotino Model (Closed Loop control)
-- Sets the distance from robot center to wheel center.
rb = 0.13
-- Sets the radius of the wheels.
rw = 0.040
-- Sets the gear.
gear = 1.0 --revisar este numero
-- Projection matrix
v0 = { -0.5 * math.sqrt(3), 0.5 }
v1 = { 0.0 , -1.0 }
v2 = { 0.5 * math.sqrt( 3.0 ), 0.5 }
-- Scale omega with the radius of the robot
vOmegaScaled = rb * rotControl
--Convert from m/s to RPM
k = 60.0 * gear / ( 2.0 * math.pi * rw )
--Compute the desired velocity
m1 = (v0[1] * velxControl + v0[2] * velyControl + vOmegaScaled ) * k
m2 = (v1[1] * velxControl + v1[2] * velyControl + vOmegaScaled ) * k
m3 = (v2[1] * velxControl + v2[2] * velyControl + vOmegaScaled ) * k
--m1 = 1000
--m2 = 000
--m3 = -1000
--vel_global, vel_ang = simGetObjectVelocity(robotino_handle)
--print(vel_global[1],vel_global[2],vel_global[3],vel_ang[3])
print('Global',vel_global[1],vel_global[2],vel_global[3],vel_angz[3])
print('Ref',ref_velx,ref_vely,ref_angz)
print('Local',vel_local[1],vel_local[2],vel_angz[3])
print('Motors',m1,m2,m3)
-- For example:
--
-- local position=simGetObjectPosition(handle,-1)
-- position[1]=position[1]+0.001
-- simSetObjectPosition(handle,-1,position)
simSetJointTargetVelocity(wheelJoints[1],m1)
simSetJointTargetVelocity(wheelJoints[2],m2)
simSetJointTargetVelocity(wheelJoints[3],m3)
end
if (sim_call_type==sim_childscriptcall_sensing) then
-- Put your main SENSING code here
end
if (sim_call_type==sim_childscriptcall_cleanup) then
-- Put some restoration code here
end
Here you can download the model. Any feedback will be greatly appreciated.

thank you for sharing the robotino model
it is really helpfull
You are welcome!. Please tell me if you do something interesting to link it back from my website :D. Cheers!