Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better support for mjcb callbacks #12

Open
colinxs opened this issue Jan 30, 2020 · 0 comments
Open

better support for mjcb callbacks #12

colinxs opened this issue Jan 30, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@colinxs
Copy link
Contributor

colinxs commented Jan 30, 2020

From some earlier experiments its pretty straightforward to install mjcb's:

using MuJoCo
using MuJoCo.MJCore

function cb1(pm::Ptr{mjModel}, pd::Ptr{mjData})
    d = Base.unsafe_load(pd)
    println(d.time)
    nothing
end

function cb2(m::mjModel, d::mjData)
    println(d.time)
    nothing
end

struct mjfGeneric
    jm::jlModel
    jd::jlData
end

function (cb::mjfGeneric)(m::Ptr{mjModel}, d::Ptr{mjData})
    println(cb.jd.cptr == d)
    nothing
end

function test1()
    MJCore.mjcb_control[] = C_NULL

    m = jlModel(MuJoCo.TESTMODELXML)
    d = jlData(m)
    mp = m.cptr
    dp = d.cptr

    f = @cfunction cb1 Cvoid (Ptr{mjModel}, Ptr{mjData})
    MJCore.mjcb_control[] = f

    mj_step(mp, dp)
    mj_step(mp, dp)
    mj_step(mp, dp)
end

function test2()
    MJCore.mjcb_control[] = C_NULL

    m = jlModel(MuJoCo.TESTMODELXML)
    d = jlData(m)
    mp = m.cptr
    dp = d.cptr

    f = @cfunction cb2 Cvoid (Ref{mjModel}, Ref{mjData})
    MJCore.mjcb_control[] = f

    mj_step(mp, dp)
    mj_step(mp, dp)
    mj_step(mp, dp)
end

function test3()
    MJCore.mjcb_control[] = C_NULL

    m = jlModel(MuJoCo.TESTMODELXML)
    d = jlData(m)
    mp = m.cptr
    dp = d.cptr

    cb = mjfGeneric(m, d)

    f = @cfunction $cb Cvoid (Ptr{mjModel}, Ptr{mjData})
    MJCore.mjcb_control[] = f

    mj_step(mp, dp)
    mj_step(mp, dp)
    mj_step(mp, dp)
end

test3 is the most useful since it provides access to the underlying jlModel/jlData, but is a little funky because we install a global callback that's bound to single instances to jlModel/jlData. This would break parallel computation.

As far as I can see, full support would require redesigning/getting rid of jlModel/jlData so that the pointers to mjModel and mjData are manipulated directly. CBindings.jl and Blobs.jl may be useful.

The only reason the jl types are needed is to wrap Ptr fields/arrays, which requires knowing the size. You could shove all the size information into the type definition for the mj types like:

struct mjData{nq, nv, ...}
# ...
end

which I've tested and works, but seems like an abuse of the type system?

@colinxs colinxs added the enhancement New feature or request label Jan 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant