Mixed controller, C and lua

Typically: "How do I... ", "How can I... " questions
Post Reply
RobAtLab
Posts: 74
Joined: 10 Jan 2018, 17:49

Mixed controller, C and lua

Post by RobAtLab » 01 Jun 2019, 20:45

My real robots use C for their controllers. I write C code, compile it with gcc alongside a special h file full of my low level functions, then run it on the robot.

In my V-REP sims I've built up some rather complex lua scripts to simulate things like sensor behaviour and actuator responses to commands so that these behave like the real robots do. I've made a lot of use of custom datablocks and signals within my "low level" lua scripts to transfer data between the main body object of the simulated robot, where the controller code is run, and the sub-objects which run the "lower level" lua scripts to simulate sensors.

Until now I've run my simulated controllers in lua and used them to call low level lua functions of mine, my simulated controllers mostly just call lua functions of MINE, these lua functions then THEMSELVES call the actual VREP sim.XXX() functions. But I'd like to change this. I'd like to have the same C code able to run on the real robot as in my sims. There is no way to have lua run on the real robot so as to let simulations' lua code call the real world C hardware control functions.

I'd hope for a way for my C controller code to be able to call C functions, these C functions of mine would have the same names and interfaces, input and return values (and data types int/float/uint8_t...) in both the real world robot and the sim. In the real world robot the insides of those functions handle compressing data in special ways to send over I2C and other GPIO methods so as to control actuators and read sensors. In the sim I'd hope to have different insides to these C functions, insides which can then call the lua functions within the scripts of lower level objects in the model hierarchy. In such a wau an identical controlelr can run in V-REP and on my physical hardware.

Is there a guide anywhere to how to combine C and lua for V-REP in the wasy I hope to? I understand there is a C API for V-REP but, not only can I not quite get how you are supposed to run your C program alongisde V-REP I also can't see, given the existance of C equivalents to lua functions, how I would do this without having to rewrite all the low level lua functions again in C, which could be pretty tricky especially where I use lua's "table" features of arrays to handle things like simulations of how sensors behave. I don't need to use table stuff in my controllers themselves, I can ensure that everything the C controller feeds in to my lua functions and everything it expects to read out of them is feasible in C, but can't ensure that everything going on as intermediates inside my lua functions is C compatible.

One point that should ease doing this is that my real world robot runs code in such a way that the sensor data read by the code comes in before the behaviour code is run, then the behaviour code runs, and after that the actuator commands go out. My behaviour code is run quickly enough that the time for it is insignificant compared to the time spent in the hardware processing part of the code. This is just like V-REP's method of having actuation, sensing and user code routines run as child scripts after each other. If in V-REP I, within a single run of the sysCall_actuation() , set a motor speed to 50, then set it to 100, I only get it set to 100 in terms of what physically happens. I don't see the motor go to speed 50 as the sim.setJointTargetVelocity(MotorOne,50) runs , then moments later jerk up to 100 as sim.setJointTargetVelocity(MotorOne,100) runs. My real robots act the same way, I spend the code's loop reading sensor values (all of which were actually calculated from the hardware's state before the loop began) and writing actuator commands (the actuator commands only run when the loop ends, and if within the single run of the loop I've told a motor to go to 50 then to go to 100, the later cmmmand will be the only one executed by the hardware). This should atleast mean that the same code in V-REP and the real world is feasible, far more so than were I using a platform where sensor readings and actuator commands occured in the physical world exactly as the code reached them.

Any suggestions or links to tutorials?

Something that would let my copy and paste sections of C code into my V-REP child scripts then wrap them in some special tags saying "this bit between here should be read as C not as lua" would be ideal, so long as there was a way to pass values into it at its start and out of it at its end to be used in the lua elements of my code.

Thank You

coppelia
Site Admin
Posts: 7445
Joined: 14 Dec 2012, 00:25

Re: Mixed controller, C and lua

Post by coppelia » 03 Jun 2019, 08:27

Hello,

it is difficult to reply to your question, if the question and description is so long.
Anyway, from my understanding you want to be able to have the same code run either the real robot, or the simulated robot.

I would use a remote API client on the robot (you can use the newer B0-based remote API, or the legacy remote API).

Next, for each actuator or sensor, you would need a second routine that, instead of sending data to / receiving data from an actuator/sensor, it would do it with a simulated actuator/sensor. E.g. to set the velocity of a motor for instance:

Code: Select all

if (simulated)
{
    client.simxSetJointTargetVelocity(motorHandle,speed,client.simxDefaultPublisher());
}
else
{
    setMotorSpeed(motorIndex,speed);
}
This means that in simulation mode, the controller would still run on your robot, but all actuations/sensor readings would go to / come from V-REP. You will have to make sure that the V-REP simulation runs with the real-time mode enabled.

Cheers

RobAtLab
Posts: 74
Joined: 10 Jan 2018, 17:49

Re: Mixed controller, C and lua

Post by RobAtLab » 04 Jun 2019, 01:36

When running the sims I don't want to run them on my actual robot and have it try to connect to a computer which has V-REP on it, the robot's hardware isn't too fast and wouldn't cope with this. Furthermore my work is with swarms of robots, so I need each to be able to run a V-REP child script of it's own. I think the remote API might be complexity overkill, I just need a simple way to let lumps of C code get inputs and outputs, as far as V-REP's simulator is concerned, as if they were normal lua child scripts. The regular API documentation shwos that C functions exist for everything the lua functions do, but is there a way in which C code can be used for some child scripts instead of lua? We're not really talking pointers and stack stuff here, we're talking mathematical operations, logical if s and while s, arrays (C and lua are quite different here especially with what valeus indices start at).

As far as your mention of putting if statements "if(in simulator==true){..." in my C libraries go, I'd rather just use a different h file to compile in each case, my robot has an ARM core and my V-REP PC is an x86 so compiling ocne for both isn't practical anyway. What I'm mainly after is being able to copy and paste C source code from the real robot, into "some special place???" from which it can call some other special (and unique for this purpose, not used on the real robot) routines (either bits of C or lua), and these special routines can then somehow manipulate V-REP's API like sim.getObjectOrientation(number objectHandle,number relativeToObjectHandle) or "sim.setJointTargetVelocity(number objectHandle,number targetVelocity)" do. Or if V-REP supports any way of "interpreting C" rather than compiling it then I'd be very happy to paste my source code into a special type of child script which supports this? I can put, at the top of that child script, simulation equivalents of my hardware's functions and then just run without my actual hardware C library at all.

Also I really don't want the communication lag which the remote API comes with. In my use case I have multiple robots, each presently having their controllers represented with a lua child script inside V-REP, and I nedd to run large numbers of simulations with different randomised starting parameters so as to collect statistical data about my robots' behaviour. Sims already don't manage to run at anything like realtime speed, I really don't want them to get slower due to time taken for each robots' code to communicate with V-REP's remote API every time the code wants to read a sensor value or set an actuator.

I'm effectively after a way to act just like a normal associated non-threaded child script, but in C instead of lua. That way I can use my real robot's source code and just fill the top of the child script with functions which would convert my C code's calls to what on the real robot are hardware devices into calls to "sim.set..." functions. So if my main C function on the real robot contains say:
uint8_t LeftSpeed=50;
uint8_t RightSpeed=200;
SetMotorSpeeds(LeftSpeed,RightSpeed);

Then in my sim when that main function ran it would, instead of looking in an h file where (on the real robot) void SetMotorSpeeds(uint8_t Spe1, uint8_t Spe2){...} exists and deals with I2C, GPIOS and all manner of other electronics, look at the top of the child script and find
void SetMotorSpeeds(uint8_t Spe1, uint8_t Spe2){
//somehow we magically become lua here???
--and somehow those specific Spe1 and Spe2 value get brough across to lua, in this function no other variables need to cross the language barrier
sim.setJointTargetVelocity(LeftMotorHandle,Spe1)
sim.setJointTargetVelocity(RightMotorHandle,Spe2)
--we stop being lua
//and back to C
}

I must admit I'm quite confused about this whole situation, perhaps I didn't explain it too well?

Thanks

fferri
Posts: 432
Joined: 09 Sep 2013, 19:28

Re: Mixed controller, C and lua

Post by fferri » 04 Jun 2019, 08:53

RobAtLab wrote:
04 Jun 2019, 01:36
I think the remote API might be complexity overkill, I just need a simple way to let lumps of C code get inputs and outputs, as far as V-REP's simulator is concerned, as if they were normal lua child scripts. The regular API documentation shwos that C functions exist for everything the lua functions do, but is there a way in which C code can be used for some child scripts instead of lua? We're not really talking pointers and stack stuff here, we're talking mathematical operations, logical if s and while s, arrays (C and lua are quite different here especially with what valeus indices start at).
Sure there is.
Make a plugin with a callback function (see simRegisterScriptCallbackFunction), and call that function from the Lua child script.

RobAtLab
Posts: 74
Joined: 10 Jan 2018, 17:49

Re: Mixed controller, C and lua

Post by RobAtLab » 04 Jun 2019, 16:22

Thanks for the plugins tip, can you point me to a clear example where this method is used to allow a segment (the bit that handles the logic and "thinking") of a child script to use C while the rest (the bits of script dealing with reading sensors and writing to actuators and custom datablocks) uses lua. And as to how one ensures that in such circumstances certain C variables can be static and global in the way that lua variables tend to be in the usual child scripts, I would hope that they can either be somehow defined before the "main" function, as they can in C usualluy or something else equivalent done.

fferri
Posts: 432
Joined: 09 Sep 2013, 19:28

Re: Mixed controller, C and lua

Post by fferri » 04 Jun 2019, 19:35

RobAtLab wrote:
04 Jun 2019, 16:22
Thanks for the plugins tip, can you point me to a clear example where this method is used to allow a segment (the bit that handles the logic and "thinking") of a child script to use C while the rest (the bits of script dealing with reading sensors and writing to actuators and custom datablocks) uses lua.
It is really as simple as this: the child script is Lua code. Plugin code is C/C++ code.

Calling a plugin function from a child script is what allows you to run C/C++ code from within a Lua script.

v_repExtPluginSkeleton is an example of defining a callback function in a plugin. The function is available in Lua as simSkeleton.getData().

RobAtLab
Posts: 74
Joined: 10 Jan 2018, 17:49

Re: Mixed controller, C and lua

Post by RobAtLab » 06 Jun 2019, 20:24

That would let me call a C function from lua then, but when my C function is acting as the main part of a robot's controller code, and needs things like static variables which preserve across subsequent times the code is run, would I have problems? Does using this plugin method effectively start a whle new instance of C with freshly define variabels every time it is caleld? or can data in the plugin be static?

fferri
Posts: 432
Joined: 09 Sep 2013, 19:28

Re: Mixed controller, C and lua

Post by fferri » 06 Jun 2019, 23:08

Storing the robot state in static variable is a simple way to solve the problem, however it is limited to having just ONE instance of such variables.

If you want to be more flexible than that, manage the lifetime of your state variables manually, in a object-oriented fashion, e.g. define:
  • a command to create an instance of such variables, which returns a handle to the data
  • a command to delete the instance given the handle
  • as many commands as you need to work with the data
Very simple example of how a Lua child script would look like:

Code: Select all

function sysCall_init()
    myDataHandle = simMyPlugin.createData('foo', 'bar', 123, {10, 0, -1})
    -- this would allocate and fill a struct of data in C++
    -- and would return a handle to that data
end

function sysCall_sensing()
    simMyPlugin.setMagicParameter(myDataHandle, 456)
    -- this would work with data in the struct
end

function sysCall_actuation()
    simMyPlugin.runSomeFunction(myDataHandle)
end

function sysCall_cleanup()
    simMyPlugin.deleteData(myDataHandle)
    -- this would delete the struct in C++
end

Post Reply