JuliaPOMDP / POMDPModels.jl

Problem models for testing POMDPs.jl
Other
31 stars 28 forks source link

Error Matching Method actions() despite definition #55

Closed clburks9 closed 5 years ago

clburks9 commented 5 years ago

Recreating the LightDark1D problem in a 2D toy problem called D2Diffs. When the simulate command is run with arguments for rollout_sim, pomdp, planner, filter, and belief, the following error is thrown with respect to the function actions(::D2Diffs):

ERROR: LoadError: MethodError: no method matching actions(::D2Diffs)
Closest candidates are:
  actions(::POMDP, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/space.jl:51
  actions(::Union{MDP, POMDP}, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/space.jl:43
  actions(!Matched::TigerPOMDP) at /home/cohrint/.julia/packages/POMDPModels/oR8C3/src/TigerPOMDPs.jl:76
  ...
Stacktrace:
 [1] BasicPOMCP.POMCPTree(::D2Diffs, ::Int64) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/BasicPOMCP.jl:131
 [2] #action_info#4(::Bool, ::Function, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::ParticleCollection{Array{Float64,1}}) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:5
 [3] action_info at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:2 [inlined]
 [4] action at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:19 [inlined]
 [5] simulate at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:100 [inlined]
 [6] simulate(::RolloutSimulator{MersenneTwister}, ::D2Diffs, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::BasicParticleFilter{D2Diffs,D2Diffs,LowVarianceResampler,MersenneTwister,Array{Array,1}}, ::MvNormal{Float64,PDMats.PDiagMat{Float64,Array{Float64,1}},Distributions.ZeroVector{Float64}}) at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:61
 [7] top-level scope at none:0
 [8] include at ./boot.jl:317 [inlined]
 [9] include_relative(::Module, ::String) at ./loading.jl:1044
 [10] include(::Module, ::String) at ./sysimg.jl:29
 [11] exec_options(::Base.JLOptions) at ./client.jl:231
 [12] _start() at ./client.jl:425
in expression starting at /home/cohrint/juliaPOMCP/D2DiffsTest.jl:170

This is despite the function being defined prior to the simulate call, show in the code posted below. Changes to the LightDark1D example which may affect something include the use of a 2D state and the lack of a defined struct for D2DiffsState and D2DiffsStateDist, passing a Multivariate normal to simulate instead.

import Base: ==, +, *, -

using POMDPs
using POMDPModels
using BasicPOMCP
using POMDPPolicies
using POMDPSimulators
using ParticleFilters
using Distributions
using Random

mutable struct D2Diffs <: POMDPs.POMDP{Array,Int,Int}
    discount_factor::Float64
    found_r::Float64
    lost_r::Float64
    step_size::Float64
    movement_cost::Float64
end

D2Diffs() = D2Diffs(0.9, 5.0, 0.0, 1.0, 0.0)

discount(p::D2Diffs) = p.discount_factor

initialstate_distribution(pomdp::D2Diffs) = MvNormal([10,10])

function observation(p::D2Diffs, sp::Array)
    if sqrt(s[1]*s[1] + s[2]*s[2]) < 1
        return 4
    elseif abs(s[1]) > abs(s[2])
        if s[1] < 0
            return 0
        else
            return 1
        end
    else
        if s[2] > 0
            return 2
        else
            return 3
        end
    end
end

function transition(p::D2Diffs, s::Array, a::Int)
    sig_0 = [1,1,0.00001,0.00001]
    #sig_stationary = [sqrt(0.00001),sqrt(0.00001),sqrt(0.00001),sqrt(0.00001)]
    d= MvNormal(sig_0)
    noise = rand(d::MvNormal) 

    if a == 0
        s= s + [-1,0,0,0] + noise
    elseif a == 1
        s= s + [1,0,0,0] + noise
    elseif a == 2
        s= s + [0,1,0,0] + noise
    elseif a == 3
        s= s + [0,-1,0,0] + noise
    else 
        s= s + noise
    end

    s[1] = max(-10,s[1])
    s[1] = min(10,s[1]); 
    s[2] = max(-10,s[2])
    s[2] = min(10,s[2]);
    s[3] = max(0,s[3])
    s[3] = min(0,s[3]);
    s[4] = max(0,s[4])
    s[4] = min(0,s[4])

    return s   

end

function reward(p::D2Diffs, s::Array, a::Int)
    if sqrt(s[1]*s[1] + s[2]*s[2]) < 1
        #return p.found_r
    else
        #return p.lost_r
    end
end;

convert_s(::Type{A}, s::Array, p::D2Diffs) where A<:AbstractArray = eltype(A)[s.status, s.y]
convert_s(::Type{Array}, s::A, p::D2Diffs) where A<:AbstractArray = Array(Int64(s[1]), s[2])

mutable struct DummyHeuristic1DPolicy <: POMDPs.Policy
    thres::Float64
end
DummyHeuristic1DPolicy() = DummyHeuristic1DPolicy(0.1)

mutable struct SmartHeuristic1DPolicy <: POMDPs.Policy
    thres::Float64
end
SmartHeuristic1DPolicy() = SmartHeuristic1DPolicy(0.1)

function action(p::SmartHeuristic1DPolicy, b::B) where {B}
    if sqrt(s[1]*s[1] + s[2]*s[2]) < 1
        return 4
    elseif abs(s[1]) > abs(s[2])
        if s[1] < 0
            return 0
        else
            return 1
        end
    else
        if s[2] > 0
            return 2
        else
            return 3
        end
    end
end

actions(::D2Diffs) = [0,1,2,3,4]
n_actions(p::D2Diffs) = length(actions(p))

println("Loaded Imports"); 

pomdp = D2Diffs()

println("Loaded Problem"); 

solver = POMCPSolver(); 

println("Loaded Solver"); 

planner = solve(solver, pomdp); 
rand_policy = RandomPolicy(pomdp);

println("Loaded Planner"); 

pf = SIRParticleFilter(pomdp,1000); 

println("Loaded Filter"); 

rollout_sim = RolloutSimulator(max_steps=10); 

println("Loaded Sim"); 

rollout_sim = RolloutSimulator(max_steps=10);
r_pomcp = simulate(rollout_sim, pomdp, planner, pf, MvNormal([10.,10.]));

@show r_pomcp;
zsunberg commented 5 years ago

Hi @clburks9 ,

The error results because you have created a new function actions (or Main.actions) instead of creating a new method of POMDPs.actions.

Observe that the output of methods(actions) has only 1 method, while the output of methods(POMDPs.actions) has many methods, but none for D2Diffs

In order to create new methods of the interface functions in the POMDPs module, you need to import them with the import keyword instead of using, or qualify each new definition with POMDPs, e.g. POMDPs.actions(::D2Diffs) = [0,1,2,3,4].

More documentation can be found here: https://docs.julialang.org/en/v1/manual/modules/

You may also want to use this package: https://github.com/NTimmons/ImportAll.jl

Hope that all makes sense!

clburks9 commented 5 years ago

@zsunberg , Thanks for the quick response!

Your suggestion fixed the error related to the actions function, but now I'm getting a similar, but slightly different error with the observation function. The methods(POMDPs.observation) returns a result with observation(::D2Diffs, s::Array). The error given below seems to be looking for a ::Float64 instead of an array.


ERROR: LoadError: MethodError: no method matching observation(::D2Diffs, ::Float64)
Closest candidates are:
  observation(::POMDP, ::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:81
  observation(::POMDP, ::Any, !Matched::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:90
  observation(!Matched::POMDPModelTools.FullyObservablePOMDP, ::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPModelTools/eHEjm/src/fully_observable_pomdp.jl:23
  ...
Stacktrace:
 [1] observation(::D2Diffs, ::Int64, ::Float64) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:81
 [2] observation(::D2Diffs, ::Array{Float64,1}, ::Int64, ::Float64) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:90
 [3] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:92 [inlined]
 [4] generate_o(::D2Diffs, ::Array{Float64,1}, ::Int64, ::Float64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:91
 [5] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:129 [inlined]
 [6] generate_so(::D2Diffs, ::Array{Float64,1}, ::Int64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:127
 [7] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:168 [inlined]
 [8] generate_sor(::D2Diffs, ::Array{Float64,1}, ::Int64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:167
 [9] simulate(::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::Array{Float64,1}, ::BasicPOMCP.POMCPObsNode{Int64,Int64}, ::Int64) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:90
 [10] search(::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::ParticleCollection{Array{Float64,1}}, ::BasicPOMCP.POMCPTree{Int64,Int64}, ::Dict{Symbol,Any}) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:32
 [11] #action_info#4(::Bool, ::Function, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::ParticleCollection{Array{Float64,1}}) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:6
 [12] action_info at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:2 [inlined]
 [13] action at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:19 [inlined]
 [14] simulate at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:100 [inlined]
 [15] simulate(::RolloutSimulator{MersenneTwister}, ::D2Diffs, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::BasicParticleFilter{D2Diffs,D2Diffs,LowVarianceResampler,MersenneTwister,Array{Array,1}}, ::MvNormal{Float64,PDMats.PDiagMat{Float64,Array{Float64,1}},Distributions.ZeroVector{Float64}}) at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:61
 [16] top-level scope at none:0
 [17] include at ./boot.jl:317 [inlined]
 [18] include_relative(::Module, ::String) at ./loading.jl:1044
 [19] include(::Module, ::String) at ./sysimg.jl:29
 [20] exec_options(::Base.JLOptions) at ./client.jl:231
 [21] _start() at ./client.jl:425
in expression starting at /home/cohrint/juliaPOMCP/D2DiffsTest.jl:160
'''
zsunberg commented 5 years ago

This error is caused because transition is returning a state instead of a distribution over states

Note the difference between the explicit and generative model interfaces: http://juliapomdp.github.io/POMDPs.jl/latest/def_pomdp/

(sent from phone)

On Wed, Dec 12, 2018, 11:56 Luke Burks <notifications@github.com wrote:

@zsunberg https://github.com/zsunberg , Thanks for the quick response!

Your suggestion fixed the error related to the actions function, but now I'm getting a similar, but slightly different error with the observation function. The methods(POMDPs.observation) returns a result with observation(::D2Diffs, s::Array). The error given below seems to be looking for a ::Float64 instead of an array.

ERROR: LoadError: MethodError: no method matching observation(::D2Diffs, ::Float64) Closest candidates are: observation(::POMDP, ::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:81 observation(::POMDP, ::Any, !Matched::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:90 observation(!Matched::POMDPModelTools.FullyObservablePOMDP, ::Any, !Matched::Any) at /home/cohrint/.julia/packages/POMDPModelTools/eHEjm/src/fully_observable_pomdp.jl:23 ... Stacktrace: [1] observation(::D2Diffs, ::Int64, ::Float64) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:81 [2] observation(::D2Diffs, ::Array{Float64,1}, ::Int64, ::Float64) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/pomdp.jl:90 [3] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:92 [inlined] [4] generate_o(::D2Diffs, ::Array{Float64,1}, ::Int64, ::Float64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:91 [5] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:129 [inlined] [6] generate_so(::D2Diffs, ::Array{Float64,1}, ::Int64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:127 [7] macro expansion at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:168 [inlined] [8] generate_sor(::D2Diffs, ::Array{Float64,1}, ::Int64, ::MersenneTwister) at /home/cohrint/.julia/packages/POMDPs/JiYXY/src/generative_impl.jl:167 [9] simulate(::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::Array{Float64,1}, ::BasicPOMCP.POMCPObsNode{Int64,Int64}, ::Int64) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:90 [10] search(::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::ParticleCollection{Array{Float64,1}}, ::BasicPOMCP.POMCPTree{Int64,Int64}, ::Dict{Symbol,Any}) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:32 [11] #action_info#4(::Bool, ::Function, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::ParticleCollection{Array{Float64,1}}) at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:6 [12] action_info at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:2 [inlined] [13] action at /home/cohrint/.julia/packages/BasicPOMCP/01DOC/src/solver.jl:19 [inlined] [14] simulate at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:100 [inlined] [15] simulate(::RolloutSimulator{MersenneTwister}, ::D2Diffs, ::POMCPPlanner{D2Diffs,BasicPOMCP.SolvedPORollout{RandomPolicy{MersenneTwister,D2Diffs,BeliefUpdaters.NothingUpdater},BeliefUpdaters.NothingUpdater,MersenneTwister},MersenneTwister}, ::BasicParticleFilter{D2Diffs,D2Diffs,LowVarianceResampler,MersenneTwister,Array{Array,1}}, ::MvNormal{Float64,PDMats.PDiagMat{Float64,Array{Float64,1}},Distributions.ZeroVector{Float64}}) at /home/cohrint/.julia/packages/POMDPSimulators/xyfJM/src/rollout.jl:61 [16] top-level scope at none:0 [17] include at ./boot.jl:317 [inlined] [18] include_relative(::Module, ::String) at ./loading.jl:1044 [19] include(::Module, ::String) at ./sysimg.jl:29 [20] exec_options(::Base.JLOptions) at ./client.jl:231 [21] _start() at ./client.jl:425 in expression starting at /home/cohrint/juliaPOMCP/D2DiffsTest.jl:160 '''

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JuliaPOMDP/POMDPModels.jl/issues/55#issuecomment-446722545, or mute the thread https://github.com/notifications/unsubscribe-auth/AEC0a-5-ZhMv4rQqad7S_j7CX7CVykjsks5u4V93gaJpZM4ZQLQh .

clburks9 commented 5 years ago

Thank you! The error has been resolved

zsunberg commented 5 years ago

Cool. Also, something to be aware of - having an abstract type or UnionAll like Arrayas your state type may result in very poor performance. Consider using a concrete type like Vector{Float64} or check out StaticArrays.jl for even better performance if the size is static.

I'm going to close this issue now since it appears to have been resolved.