Add-ons

An add-on in CoppeliaSim is quite similar to a plugin: it is automatically loaded at program start-up, and allows CoppeliaSim's functionality to be extended by user-written functionality or functions. Add-ons are written in Lua. Two types of add-ons are supported:

  • Add-on functions: add-on functions appear first in the add-on menu. They can be seen as functions that will be executed once, when selected by the user. Importers and exporters can conveniently be implemented with them.
  • Add-on scripts: add-on scripts are persistent across all opened scenes, and are executed constantly, effectively running in the background. They should only execute minimalistic code everytime they are called, since the whole application would otherwise slow down. Add-on scripts are called frequently by the system, with a precise order. Add-on scripts share a lot of properties with the sandbox script.
  • Add-on functions and scripts should be written in a text file located in the same folder as the main application, with following naming convention:

  • simAddOnFunc_xxxx.lua, where xxxx can be any string representing the name of an add-on function.
  • simAddOnScript_xxxx.lua, where xxxx can be any string representing the name of the add-on script. The add-on script will be automatically started. Selecting it in the add-on menu allows pausing/unpausing its execution. The script can request termination by returning sim.syscb_cleanup.
  • simAddOnScript-xxxx.lua, where xxxx can be any string representing the name of the add-on script. The add-on script will not be automatically started. The user can start/pause/unpause it when required by selecting it in the add-on menu. The script can request termination by returning sim.syscb_cleanup.
  • Add-on scripts that do not follow above naming convention can still be loaded and run via command line options.

    An add-on script should be segmented into several system callback functions, as following skeleton script illustrates:

    -- Return sim.syscb_cleanup if you wish to stop the add-on script
    
    function sysCall_init() -- not optional!
        -- do some initialization here
    end
    
    function sysCall_cleanup()
        -- do some clean-up here
    end
    
    function sysCall_nonSimulation()
        -- is executed when simulation is not running
    end
    
    function sysCall_beforeSimulation()
        -- Simulation is about to start
    end
    
    function sysCall_beforeMainScript()
        -- Can be used to step a simulation in a custom manner.
        local outData={doNotRunMainScript=false} -- when true, then the main script won't be executed
        return outData
    end
    
    function sysCall_actuation()
        -- put some actuation code here.
    end
    
    function sysCall_sensing()
        -- put some sensing code here.
    end
    
    function sysCall_afterSimulation()
        -- Simulation has just ended
    end
    
    function sysCall_suspend()
        -- Simulation is about to be suspended
    end
    
    function sysCall_suspended()
        -- Simulation is suspended
    end
    
    function sysCall_resume()
        -- Simulation is about to resume
    end
    
    function sysCall_addOnScriptSuspend()
        -- Add-on script is about to be suspended
    end
    
    function sysCall_addOnScriptSuspended()
        -- Add-on script is suspended
    end
    
    function sysCall_addOnScriptResume()
        -- Add-on script is about to resume
    end
    
    function sysCall_beforeInstanceSwitch()
        -- About to switch to another scene
    end
    
    function sysCall_afterInstanceSwitch()
        -- Switched to another scene
    end
    
    function sysCall_beforeCopy(inData)
        for key,value in pairs(inData.objectHandles) do
            print("Object with handle "..key.." will be copied")
        end
    end
    
    function sysCall_afterCopy(inData)
        for key,value in pairs(inData.objectHandles) do
            print("Object with handle "..key.." was copied")
        end
    end
    
    function sysCall_beforeDelete(inData)
        for key,value in pairs(inData.objectHandles) do
            print("Object with handle "..key.." will be deleted")
        end
        -- inData.allObjects indicates if all objects in the scene will be deleted
    end
    
    function sysCall_afterDelete(inData)
        for key,value in pairs(inData.objectHandles) do
            print("Object with handle "..key.." was deleted")
        end
        -- inData.allObjects indicates if all objects in the scene were deleted
    end
    
    function sysCall_afterCreate(inData)
        for i=1,#inData.objectHandles,1 do
            print("Object with handle "..inData.objectHandles[i].." was created")
        end
    end

    Add-ons can call any of the regular API functions, as long as not stated otherwise in the documentation. They can even call custom Lua functions registered by plugins. They however have two restrictions:

  • Add-ons cannot call API functions that require the caller to run in a thread. This is because add-ons operate in a non-threaded fashion.
  • For more information on add-ons, make sure to inspect the content of the demo add-ons simAddOnScript-addOnScriptDemo.lua, simAddOnFunc-addOnFunctionDemo.lua and simAddOnScript-b0RemoteApiServer.lua, located in the installation folder.



    Recommended topics

  • Lua
  • Plugins
  • The sandbox script
  • Regular API functions