From 8c8a7f963ff1949f8be05a35e22c841afd98479b Mon Sep 17 00:00:00 2001 From: dehann Date: Tue, 27 Sep 2022 20:08:42 -0700 Subject: [PATCH 1/5] better organizing transform code --- .../services/ConsolidateRigidTransform.jl | 37 ++----------------- src/Caesar.jl | 16 ++++---- .../BearingRangeTrackingServer.jl | 0 src/{ => services}/DataUtils.jl | 0 src/{ => services}/SlamServer.jl | 0 src/{ => services}/UserFunctions.jl | 0 src/transforms/entities/TransformTypes.jl | 3 ++ .../services/HomographyTransforms.jl | 32 ++++++++++++++++ .../services/_FastTransform3D.jl | 0 9 files changed, 47 insertions(+), 41 deletions(-) rename src/{ => services}/BearingRangeTrackingServer.jl (100%) rename src/{ => services}/DataUtils.jl (100%) rename src/{ => services}/SlamServer.jl (100%) rename src/{ => services}/UserFunctions.jl (100%) create mode 100644 src/transforms/entities/TransformTypes.jl create mode 100644 src/transforms/services/HomographyTransforms.jl rename src/{ => transforms}/services/_FastTransform3D.jl (100%) diff --git a/src/3rdParty/_PCL/services/ConsolidateRigidTransform.jl b/src/3rdParty/_PCL/services/ConsolidateRigidTransform.jl index ccb025962..e8be3cc66 100644 --- a/src/3rdParty/_PCL/services/ConsolidateRigidTransform.jl +++ b/src/3rdParty/_PCL/services/ConsolidateRigidTransform.jl @@ -41,43 +41,14 @@ function apply( M_::Union{<:typeof(SpecialEuclidean(2)),<:typeof(SpecialEuclidea return _pc end - ## ============================================================ ## FIXME, not-yet-consolidated rigid transform code that must be deprecated below ## ============================================================ -const _SO3_MANI = SpecialOrthogonal(3) -const _SE3_MANI = SpecialEuclidean(3) - -# name euler here is very ambiguous, these are Lie algebra elements -# used to manipulate cartesian coordinates in a TranslationGroup(3) space. -function euler_angles_to_linearized_rotation_matrix(α1, α2, α3, rigid::Bool=true) - dR = if rigid - # TODO likely faster performance by using a retraction instead of expmap - exp_lie(_SO3_MANI, hat(_SO3_MANI, SMatrix{3,3, Float64}(I), SA[α1, α2, α3])) - else - SMatrix{3,3,Float64}(1.0,0,0,0,1,0,0,0,1) + - hat(_SO3_MANI, Identity(_SO3_MANI), SA[α1, α2, α3]) - # [ 1 -α3 α2 - # α3 1 -α1 - # -α2 α1 1] - end -end - -function create_homogeneous_transformation_matrix(R, t) - H = affine_matrix(_SE3_MANI, ArrayPartition(t, R)) - # H = [R t - # zeros(1,3) 1] -end -function euler_coord_to_homogeneous_coord(XE) - no_points = size(XE, 1) - XH = [XE ones(no_points,1)] -end -function homogeneous_coord_to_euler_coord(XH) - XE = XH[:,1:3]./XH[:,4] -end - -function transform!(pc, H) +function transform!( + pc, + H::AbstractMatrix +) XInH = euler_coord_to_homogeneous_coord([pc.x pc.y pc.z]) XOutH = transpose(H*XInH') XOut = homogeneous_coord_to_euler_coord(XOutH) diff --git a/src/Caesar.jl b/src/Caesar.jl index 596604138..8e4cf8563 100644 --- a/src/Caesar.jl +++ b/src/Caesar.jl @@ -56,21 +56,21 @@ include("ExportAPI.jl") ## =============================================================================================== # and source files -include("BearingRangeTrackingServer.jl") +include("services/BearingRangeTrackingServer.jl") -include("services/_FastTransform3D.jl") -include("SlamServer.jl") -include("DataUtils.jl") -include("UserFunctions.jl") +include("transforms/entities/TransformTypes.jl") +include("transforms/services/HomographyTransforms.jl") +include("transforms/services/_FastTransform3D.jl") + +include("services/SlamServer.jl") +include("services/DataUtils.jl") +include("services/UserFunctions.jl") # Configuration include("config/CaesarConfig.jl") include("Deprecated.jl") -# Multisession operation -# include("attic/multisession/Multisession.jl") - # SAS-SLAM include("beamforming/czt.jl") include("beamforming/CBF.jl") diff --git a/src/BearingRangeTrackingServer.jl b/src/services/BearingRangeTrackingServer.jl similarity index 100% rename from src/BearingRangeTrackingServer.jl rename to src/services/BearingRangeTrackingServer.jl diff --git a/src/DataUtils.jl b/src/services/DataUtils.jl similarity index 100% rename from src/DataUtils.jl rename to src/services/DataUtils.jl diff --git a/src/SlamServer.jl b/src/services/SlamServer.jl similarity index 100% rename from src/SlamServer.jl rename to src/services/SlamServer.jl diff --git a/src/UserFunctions.jl b/src/services/UserFunctions.jl similarity index 100% rename from src/UserFunctions.jl rename to src/services/UserFunctions.jl diff --git a/src/transforms/entities/TransformTypes.jl b/src/transforms/entities/TransformTypes.jl new file mode 100644 index 000000000..9beff8dc2 --- /dev/null +++ b/src/transforms/entities/TransformTypes.jl @@ -0,0 +1,3 @@ + +const _SO3_MANI = SpecialOrthogonal(3) +const _SE3_MANI = SpecialEuclidean(3) diff --git a/src/transforms/services/HomographyTransforms.jl b/src/transforms/services/HomographyTransforms.jl new file mode 100644 index 000000000..a4f10b3c4 --- /dev/null +++ b/src/transforms/services/HomographyTransforms.jl @@ -0,0 +1,32 @@ + +## ============================================================ +## FIXME, not-yet-consolidated rigid transform code that must be deprecated below +## ============================================================ + +# name euler here is very ambiguous, these are Lie algebra elements +# used to manipulate cartesian coordinates in a TranslationGroup(3) space. +function euler_angles_to_linearized_rotation_matrix(α1, α2, α3, rigid::Bool=true) + dR = if rigid + # TODO likely faster performance by using a retraction instead of expmap + exp_lie(_SO3_MANI, hat(_SO3_MANI, SMatrix{3,3, Float64}(I), SA[α1, α2, α3])) + else + SMatrix{3,3,Float64}(1.0,0,0,0,1,0,0,0,1) + + hat(_SO3_MANI, Identity(_SO3_MANI), SA[α1, α2, α3]) + # [ 1 -α3 α2 + # α3 1 -α1 + # -α2 α1 1] + end +end + +function create_homogeneous_transformation_matrix(R, t) + H = affine_matrix(_SE3_MANI, ArrayPartition(t, R)) + # H = [R t + # zeros(1,3) 1] +end +function euler_coord_to_homogeneous_coord(XE) + no_points = size(XE, 1) + XH = [XE ones(no_points,1)] +end +function homogeneous_coord_to_euler_coord(XH) + XE = XH[:,1:3]./XH[:,4] +end diff --git a/src/services/_FastTransform3D.jl b/src/transforms/services/_FastTransform3D.jl similarity index 100% rename from src/services/_FastTransform3D.jl rename to src/transforms/services/_FastTransform3D.jl From f60e321e3ad39a0fda92d48021eb87c1f106091e Mon Sep 17 00:00:00 2001 From: dehann Date: Tue, 27 Sep 2022 20:10:51 -0700 Subject: [PATCH 2/5] move legacy code to attic --- src/{ => attic}/SlamConvenienceFunctions.jl | 0 src/{ => attic}/SlamInterfaceTCP.jl | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => attic}/SlamConvenienceFunctions.jl (100%) rename src/{ => attic}/SlamInterfaceTCP.jl (100%) diff --git a/src/SlamConvenienceFunctions.jl b/src/attic/SlamConvenienceFunctions.jl similarity index 100% rename from src/SlamConvenienceFunctions.jl rename to src/attic/SlamConvenienceFunctions.jl diff --git a/src/SlamInterfaceTCP.jl b/src/attic/SlamInterfaceTCP.jl similarity index 100% rename from src/SlamInterfaceTCP.jl rename to src/attic/SlamInterfaceTCP.jl From 7f3fd8a343c0878511328289f373a718be6323e4 Mon Sep 17 00:00:00 2001 From: dehann Date: Tue, 27 Sep 2022 20:19:23 -0700 Subject: [PATCH 3/5] more attic files --- src/Caesar.jl | 1 - src/{services => attic}/SlamServer.jl | 0 2 files changed, 1 deletion(-) rename src/{services => attic}/SlamServer.jl (100%) diff --git a/src/Caesar.jl b/src/Caesar.jl index 8e4cf8563..8554bd3d8 100644 --- a/src/Caesar.jl +++ b/src/Caesar.jl @@ -62,7 +62,6 @@ include("transforms/entities/TransformTypes.jl") include("transforms/services/HomographyTransforms.jl") include("transforms/services/_FastTransform3D.jl") -include("services/SlamServer.jl") include("services/DataUtils.jl") include("services/UserFunctions.jl") diff --git a/src/services/SlamServer.jl b/src/attic/SlamServer.jl similarity index 100% rename from src/services/SlamServer.jl rename to src/attic/SlamServer.jl From 609f178848dfca9a28dd79393835c41e363137da Mon Sep 17 00:00:00 2001 From: dehann Date: Tue, 27 Sep 2022 20:25:01 -0700 Subject: [PATCH 4/5] rm legacy code --- src/attic/SlamConvenienceFunctions.jl | 242 ---- src/attic/SlamInterfaceTCP.jl | 50 - src/attic/SlamServer.jl | 30 - src/attic/cloudgraphs/CGExports.jl | 46 - .../cloudgraphs/CloudGraphIntegration.jl | 1185 ----------------- .../cloudgraphs/ConvertGeneralSlaminDB.jl | 394 ------ src/attic/cloudgraphs/FoveationUtils.jl | 145 -- src/attic/cloudgraphs/IterationStatistics.jl | 16 - src/attic/cloudgraphs/MultisessionUtils.jl | 253 ---- src/attic/cloudgraphs/SolverStatus.jl | 26 - src/attic/cloudgraphs/slamindb.jl | 276 ---- src/attic/multisession/Multisession.jl | 312 ----- 12 files changed, 2975 deletions(-) delete mode 100644 src/attic/SlamConvenienceFunctions.jl delete mode 100644 src/attic/SlamInterfaceTCP.jl delete mode 100644 src/attic/SlamServer.jl delete mode 100644 src/attic/cloudgraphs/CGExports.jl delete mode 100644 src/attic/cloudgraphs/CloudGraphIntegration.jl delete mode 100644 src/attic/cloudgraphs/ConvertGeneralSlaminDB.jl delete mode 100644 src/attic/cloudgraphs/FoveationUtils.jl delete mode 100644 src/attic/cloudgraphs/IterationStatistics.jl delete mode 100644 src/attic/cloudgraphs/MultisessionUtils.jl delete mode 100644 src/attic/cloudgraphs/SolverStatus.jl delete mode 100644 src/attic/cloudgraphs/slamindb.jl delete mode 100644 src/attic/multisession/Multisession.jl diff --git a/src/attic/SlamConvenienceFunctions.jl b/src/attic/SlamConvenienceFunctions.jl deleted file mode 100644 index 3bc8b1c97..000000000 --- a/src/attic/SlamConvenienceFunctions.jl +++ /dev/null @@ -1,242 +0,0 @@ - - - -function prepString(arr::Array{Float64,2}) - s = string(arr) - ss = split(s,'\n') - ss[length(ss)] = ss[length(ss)][1:(end-1)] - fs = "" - for i in 1:length(ss) - ss[i]=replace(ss[i]," ",",") - if ss[i][1] == ',' || ss[i][1] == '[' - ss[i] = ss[i][2:end] - end - ss[i] = string(ss[i],";") - fs = string(fs,ss[i]) - end - fs[1:(end-1)] -end - - -function parseInit!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - if length(sp2) == 3 - println("parseInit! -- received initialization point $(sp2) NOT CURRENTLY USED") - x0 = parse(Float64,sp2[1]) - y0 = parse(Float64,sp2[2]) - th0 = parse(Float64,sp2[2]) - end - prevn = initFactorGraph!(slam.fg, solvable=USESOLVABLE) - println("init done") - nothing -end - -posecount = 1 -function parseOdo!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - global posecount - # println("parseOdo -- ") - posecount += 1 - n = string("x", posecount) - DX = [parse(Float64,sp2[3]);parse(Float64,sp2[4]);parse(Float64,sp2[5])] - cov = diagm([parse(Float64,sp2[6]);parse(Float64,sp2[9]);parse(Float64,sp2[11])]) - cov[1,2] = parse(Float64,sp2[7]) - cov[1,3] = parse(Float64,sp2[8]) - cov[2,3] = parse(Float64,sp2[10]) - cov[2,1] = parse(Float64,sp2[7]) - cov[3,1] = parse(Float64,sp2[8]) - cov[3,2] = parse(Float64,sp2[10]) - addOdoFG!(slam.fg, Symbol(n), DX, cov, solvable=USESOLVABLE) - return n -end - -function parseAddLandmBR!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - poseid = floor(Int,parse(Float64, sp2[1])) - pose = string(getVert(slam.fg,poseid).label) - lmid = floor(Int,parse(Float64, sp2[2])) - zbr = [parse(Float64,sp2[3]);parse(Float64,sp2[4])] - cov = diagm([parse(Float64,sp2[5]);parse(Float64,sp2[7])]) - cov[1,2] = parse(Float64,sp2[6]) - cov[2,1] = parse(Float64,sp2[6]) - lm = string("") - if !haskey(slam.fg.v, lmid) - slam.lndmidx += 1 - lm = string(string('l',slam.lndmidx)) - projNewLandm!(slam.fg, pose, lm, zbr, cov, solvable=USESOLVABLE) - else - lm = string(getVert(slam.fg,lmid).label) - addBRFG!(slam.fg, pose, lm, zbr, cov, solvable=USESOLVABLE) - end - return lm -end - -function parseLandmBRMM!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - poseid = floor(Int,parse(Float64, sp2[1])) - pose = string(getVert(slam.fg, poseid).label) - lm1id = floor(Int,parse(Float64, sp2[2])) - w1 = parse(Float64, sp2[3]) - lm2id = floor(Int,parse(Float64, sp2[4])) - w2 = parse(Float64, sp2[5]) - zbr = [parse(Float64,sp2[6]);parse(Float64,sp2[7])] - cov = diagm([parse(Float64,sp2[8]);parse(Float64,sp2[10])]) - cov[1,2] = parse(Float64,sp2[9]) - cov[2,1] = parse(Float64,sp2[9]) - # TODO --do the tests here - lm1 = string(getVert(slam.fg,lm1id).label) - lm2 = string(getVert(slam.fg,lm2id).label) - addMMBRFG!(slam.fg, pose, [lm1;lm2], zbr, cov, w=[w1;w2], solvable=USESOLVABLE) - # function addMMBRFG!(fg::G, pose::AbstractString, - # lm::Array{AbstractString,1}, br::Array{Float64,1}, - # cov::Array{Float64,2}; w=[0.5;0.5]) where G <: AbstractDFG - return "$(lm1), $(lm2)" -end - -function parseLandmBRAuto!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - poseid = floor(Int,parse(Float64, sp2[1])) - pose = string(getVert(slam.fg,poseid).label) - lmid = sp2[2] != "*" ? floor(Int,parse(Float64, sp2[2])) : -1 - zbr = [parse(Float64,sp2[3]);parse(Float64,sp2[4])] - cov = diagm([parse(Float64,sp2[5]);parse(Float64,sp2[7])]) - cov[1,2] = parse(Float64,sp2[6]) - cov[2,1] = parse(Float64,sp2[6]) - lm = string("") - - vlm, flm, slam.lndmidx = addAutoLandmBR!(slam.fg, pose, lmid, zbr, cov, slam.lndmidx, solvable=USESOLVABLE) - - println("parseLandmBRAuto! -- added $(vlm.label)") - - return vlm.label -end - - -function parseLandmarkXY!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - pose = getVert(slam.fg, map(Int, sp2[1]) ).label - lmid = map(Int, sp2[2]) - zxy = [map(Float64,sp[3]);map(Float64,sp[4])] - cov = diagm([map(Float64,sp[5]);map(Float64,sp[7])]) - cov[1,2] = map(Float64,sp[6]) - cov[2,1] = map(Float64,sp[6]) - error("parseLandmarkXY! -- not finished implementing yet") - nothing -end -# -# see solveTree!(::SLAMWrapper) -# function batchSolve!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) -# println("batchSolve -- wiping tree and solving") -# slam.tree = wipeBuildNewTree!(slam.fg) -# @time inferOverTree!(slam.fg, slam.tree, N=100) -# nothing -# end - -function parseGetparticles(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - val = getVal(slam.fg, string(sp2[1])) - retstr = prepString(val) - return retstr -end - -function parseLS(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - xx,ll = ls(slam.fg) - str = string("") - [str = string(str, x, ",") for x in xx] - if length(str) > 0 - str = string(str[1:(end-1)], ';') - end - [str = string(str, x, ",") for x in ll] - @show "LS", str - return length(str) > 0 ? str : nothing -end - -function parseGetID(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - id = slam.fg.IDs[sp2[1]] - return "$(id)" -end - -function parseGetNextID(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - id = slam.fg.id + 1 - return "$(id)" -end - -function parseReset(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - @warn "parseReset -- resetting factor graph" - slam = SLAMWrapper(emptyFactorGraph(), Union{}, 0) - nothing -end - -function parseDotFG(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - writeGraphPdf(slam.fg) - nothing -end - - -function parseSetReady!(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - setAllDBSolvable!(slam.fg) - nothing -end - -function parseMongoFileSave(slam::SLAMWrapper, sp2::Array{SubString{AbstractString},1}) - id = slam.fg.IDs[sp2[1]] - cgid = slam.fg.cgIDs[id] - cv = CloudGraphs.get_vertex(slam.fg.cg, cgid) - # for f in sp2[2:end] - fid = open(sp2[2],"r") - imageData = readbytes(fid) # imageData::Vector{UInt8} - close(fid) - bdei = CloudGraphs.BigDataElement("keyframe-image", imageData) - push!(cv.bigData.dataElements, bdei); - - fid = open(sp2[3],"r") - imageData = readbytes(fid) # imageData::Vector{UInt8} - close(fid) - bdei = CloudGraphs.BigDataElement("depthframe-image", imageData) - push!(cv.bigData.dataElements, bdei); - - CloudGraphs.save_BigData!(slam.fg.cg, cv) - println("Finished writing to Mongo.") - - nothing -end - -function parseTCP!(slam::SLAMWrapper, line::AbstractString) - sp = split(line,' ') - f = + - cmd = sp[1] - goahead = true - if cmd == "INIT" - f = parseInit! - elseif cmd == "ODOMETRY" - f = parseOdo! - elseif cmd == "LANDMBR" - f = parseAddLandmBR! - elseif cmd == "LANDMARK" - f = parseLandmarkXY! - elseif cmd == "LANDMBRMM" - f = parseLandmBRMM! - elseif cmd == "LANDMBRAUTO" - f = parseLandmBRAuto! - elseif cmd == "SETALLREADY" - f = parseSetReady! - elseif cmd == "SOLVETREE" # do not call batch when using DB solver - f = solveTree! - elseif cmd == "GETPARTICLES" - f = parseGetparticles - elseif cmd == "LS" - f = parseLS - elseif cmd == "GETID" - f = parseGetID - elseif cmd == "GETNEXTID" - f = parseGetNextID - elseif cmd == "DRAWFGPDF" - f = parseDotFG - elseif cmd == "MONGOFILE" - f = parseMongoFileSave - elseif cmd == "RESET" - f = parseReset - elseif cmd == "QUIT" - println("parseTCP -- should quit now") - return false, string("") - else - @warn "parseTCP -- I don't know what $(cmd) means" - goahead = false - end - retstr = nothing - goahead ? retstr = f(slam, sp[2:end]) : nothing - return true, retstr -end diff --git a/src/attic/SlamInterfaceTCP.jl b/src/attic/SlamInterfaceTCP.jl deleted file mode 100644 index 718db68ab..000000000 --- a/src/attic/SlamInterfaceTCP.jl +++ /dev/null @@ -1,50 +0,0 @@ -# using Caesar -# using IncrementalInference -# using RoME -# using CloudGraphs - -@show dbaddress = ARGS[1] -configuration = CloudGraphs.CloudGraphConfiguration(dbaddress, 7474, "", "", dbaddress, 27017, false, "", ""); -cloudGraph = connect(configuration, encodePackedType, getpackedtype, decodePackedType); - -# register types of interest in CloudGraphs -registerGeneralVariableTypes!(cloudGraph) -IncrementalInference.setCloudDataLayerAPI!() - -nprocs() > 1 ? thxl = 2 : nothing - -mutable struct SLAMWrapper{G} - fg::G - tree - lndmidx::Int -end - -USESOLVABLE=0 -include("SlamConvenienceFunctions.jl") - - -function tcpStringSLAMServer(;slamdata=Union{},port::Int=60001) - println("Empty slam object created") - if slamdata == Union{} - # this is being replaced by cloudGraph, added here for development period - fg = emptyFactorGraph() - fg.cg = cloudGraph - slamdata = SLAMWrapper(fg, Union{}, 0) - end - - println("Listenting on $(port)") - server = listen(port) - loop = true - while loop - sock = accept(server) - while isopen(sock) - loop, retstr = parseTCP!(slamdata, readline(sock)[1:(end-1)]) - loop ? (isopen(sock) ? println(sock, retstr) : nothing) : close(sock) - end - println("connection lost") - end - !loop ? close(server) : nothing - return slamdata -end - -tcpStringSLAMServer() diff --git a/src/attic/SlamServer.jl b/src/attic/SlamServer.jl deleted file mode 100644 index 67ae36663..000000000 --- a/src/attic/SlamServer.jl +++ /dev/null @@ -1,30 +0,0 @@ - -# look at SimpleExample.jl for TCP based usage example - -nprocs() > 1 ? thxl = 2 : nothing - - -USESOLVABLE=1 -include("SlamConvenienceFunctions.jl") - - -function tcpStringSLAMServer(;slamdata=nothing,port::Int=60001) - println("Empty slam object created") - if slamdata == nothing - slamdata = SLAMWrapper(emptyFactorGraph(), nothing, 0) - end - - println("Listenting on $(port)") - server = listen(port) - loop = true - while loop - sock = accept(server) - while isopen(sock) - loop, retstr = parseTCP!(slamdata, readline(sock)[1:(end-1)]) - loop ? (isopen(sock) ? println(sock, retstr) : nothing) : close(sock) - end - println("connection lost") - end - !loop ? close(server) : nothing - return slamdata -end diff --git a/src/attic/cloudgraphs/CGExports.jl b/src/attic/cloudgraphs/CGExports.jl deleted file mode 100644 index 37a4334f6..000000000 --- a/src/attic/cloudgraphs/CGExports.jl +++ /dev/null @@ -1,46 +0,0 @@ -export - # CloudGraphs helper functions - insertnodefromcv!, - checkandinsertedges!, - getbinarraymongo, - gettopoint, - getdotwothree, - bin2arr, - fetchsubgraph!, - getVertNeoIDs!, - insertrobotdatafirstpose!, - tryunpackalltypes!, - fetchrobotdatafirstpose, - getExVertexNeoIDs, - db2jld, - - # solver service SLAMinDB - getcredentials, - startSlamInDb, - runSlamInDbOnSession, - slamindb, - convertdb, - resetconvertdb, - getmaxfactorid, - # would be CloudGraphs calls - hasBigDataElement, - getBigDataElement, - removeNeo4jID, - - # webserver - SolverStatus, - CaesarConfig, - IterationStatistics, - VisualizationConfig - - - # # multisession utils - # multisessionquery, - # parsemultisessionqueryresult!, - # getLandmOtherSessNeoIDs, - # getAllLandmarkNeoIDs, - # getLocalSubGraphMultisession, - # findExistingMSConstraints, - # getprpt2kde, - # rmInstMultisessionPriors!, - # removeMultisessions!, \ No newline at end of file diff --git a/src/attic/cloudgraphs/CloudGraphIntegration.jl b/src/attic/cloudgraphs/CloudGraphIntegration.jl deleted file mode 100644 index 875df84be..000000000 --- a/src/attic/cloudgraphs/CloudGraphIntegration.jl +++ /dev/null @@ -1,1185 +0,0 @@ -# integration code for database usage via CloudGraphs.jl - -export - executeQuery, - listAllVariables, - getCloudVert, - getfnctype, - usecloudgraphsdatalayer!, - uselocalmemoryonly!, - standardcloudgraphsetup, - consoleaskuserfordb, - registerGeneralVariableTypes!, - fullLocalGraphCopy!, - subLocalGraphCopy!, - removeGenericMarginals!, - setBackendWorkingSet!, - setAllDBSolvable!, - getExVertFromCloud, - getAllExVertexNeoIDs, - getPoseExVertexNeoIDs, - getFirstPose, - getfirstpose, - getLastPose, - copyAllNodes!, - copyAllEdges!, - registerCallback!, - updateFullCloudVertData!, - #loading frtend generated fg - getnewvertdict, - mergeValuesIntoCloudVert!, - recoverConstraintType, - populatenewvariablenodes!, - populatenewfactornodes!, - updatenewverts!, - resetentireremotesession, - appendvertbigdata!, - # visualization exports - getPointCloudFromKinect, - getPointCloudFromBSON, - deleteServerSession! - - -""" - $(SIGNATURES) - -Run Neo4j Cypher queries on the cloudGraph database, and return Tuple with the -unparsed (results, loadresponse). -Throws an error if the query fails. -""" -function executeQuery(connection::Neo4j.Connection, - query::AS ) where {AS <: AbstractString} - # - loadtx = transaction(connection) - cph = loadtx(query, submit=true) - if length(cph.errors) > 0 #Uh oh, return legible error - err = "" - for er in cph.errors - err*="-\r\n" - for (k,v) in er - err*=" $k: $v\r\n" - end - end - error("Unable to perform Neo4j query:\r\n$err") - end - loadresult = commit(loadtx) - return cph, loadresult -end -executeQuery(cg::CloudGraph, query::AS) where {AS <:AbstractString} = executeQuery(cg.neo4j.connection, query) - -""" - $(SIGNATURES) - -Get cloud vertex from Neo4j using CloudGraphs.jl as identified by `session`, `robot`, `user`, and vertex label `vsym::Symbol`. -""" -function getCloudVert(cg::CloudGraph, - session::AbstractString, - robot::AbstractString, - user::AbstractString, - vsym::Symbol; - bigdata::Bool=false ) - # - @warn "getCloudVert(cg, sess, sym) will be deprecated, use getCloudVert(cg, sess, sym=sym) instead." - # query = " and n.solvable=$(ready) and n.label=$(vsym) " - # query = reqbackendset ? query*" and n.backendset=$(backendset)" : query - query = "match (n:$(session):$robot:$user) where n.label='$(vsym)' return id(n)" - - cph, = executeQuery(cg, query) - # loadtx = transaction(cg.neo4j.connection) - # cph = loadtx(query, submit=true) - neoid = cph.results[1]["data"][1]["row"][1] - CloudGraphs.get_vertex(cg, neoid, bigdata) -end - -function getCloudVert(cgl::CloudGraph, - session::AbstractString, - robot::AbstractString, - user::AbstractString; - exvid::NothingUnion{Int}=nothing, - neoid::NothingUnion{Int}=nothing, - sym::NothingUnion{Symbol}=nothing, - bigdata=false ) - # - query = "match (n:$(session):$robot:$user) " - - if sym != nothing - query = query*" where n.label='$(sym)' " - elseif exvid != nothing - query = query*" where n.exVertexId=$(exvid) " - elseif neoid != nothing - return CloudGraphs.get_vertex(cgl, neoid, bigdata) - else - @show sym, neoid,exvid - error("Cannot list neighbors if no input reference is given") - end - query = query*" return id(n)" - - cph, = executeQuery(cgl.neo4j.connection, query) - neoid = cph.results[1]["data"][1]["row"][1] - CloudGraphs.get_vertex(cgl, neoid, bigdata) -end - - -function listAllVariables(cgl::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - # - query = "match (n:$(session):$robot:$user) where not (n:FACTOR) and exists(n.exVertexId) and n.solvable=1 return n.label, n.exVertexId, id(n), labels(n)" - cph, = executeQuery(cgl.neo4j.connection, query) - - dd = Dict{Symbol, Tuple{Int, Int, Vector{Symbol}}}() - for metarows in cph.results[1]["data"] - data = metarows["row"] - lbls = setdiff(data[4],String[session]) - enl = (data[2], data[3], Symbol.(lbls)) - dd[Symbol(data[1])] = enl - end - return dd -end - - -function getCloudNeighbors(cgl::CloudGraph, cv::CloudVertex; needdata=false, returntype=false) - neis = get_neighbors(cgl, cv, needdata=false) -end - -""" - $(SIGNATURES) - -List neighbors to node in cgl::CloudGraph by returning Dict{Sym}=(exvid, neoid, Symbol[labels]), and can take -any of the three as input node identifier. Not specifying an identifier will result in all Variable nodes -being returned. -""" -function ls(cgl::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString; - sym::NothingUnion{Symbol}=nothing, - neoid::NothingUnion{Int64}=nothing, - exvid::NothingUnion{Int64}=nothing ) - # - - if sym == nothing && exvid == nothing && neoid == nothing - # interrupt and just return all variable nodes - return listAllVariables(cgl, session, robot, user) - end - cv = getCloudVert(cgl, session, robot, user, sym=sym, neoid=neoid, exvid=exvid, bigdata=false ) - - neis = get_neighbors(cgl, cv, needdata=false) - dd = Dict{Symbol, Tuple{Int, Int, Vector{Symbol}}}() - for nei in neis - lbls = setdiff(nei.labels, String[session]) - dd[Symbol(nei.properties["label"])] = (nei.exVertexId, nei.neo4jNodeId, Symbol.(lbls) ) - end - return dd -end - -# deprecated -function getfnctype(cvl::CloudGraphs.CloudVertex) - vert = cloudVertex2ExVertex(cvl) - return getfnctype(vert) -end - -function addCloudVert!(fgl::G, - exvert::Graphs.ExVertex; - labels::Vector{T}=String[] ) where {G <: AbstractDFG, T <: AbstractString} - # - cv = CloudGraphs.exVertex2CloudVertex(exvert); - cv.labels = labels - CloudGraphs.add_vertex!(fgl.cg, cv); - fgl.cgIDs[exvert.index] = cv.neo4jNodeId - IncrementalInference.addGraphsVert!(fgl, exvert) -end - -# Return Graphs.ExVertex type containing data according to id -function getExVertFromCloud(fgl::G, - fgid::Int64; - bigdata::Bool=false ) where G <: AbstractDFG - # - neoID = fgl.cgIDs[fgid] - cvr = CloudGraphs.get_vertex(fgl.cg, neoID, false) - CloudGraphs.cloudVertex2ExVertex(cvr) -end - -function getExVertFromCloud(fgl::G, - lbl::Symbol; - nt::Symbol=:var, - bigdata::Bool=false ) where G <: AbstractDFG - # getExVertFromCloud(fgl, fgl.IDs[lbl], bigdata=bigdata) - getExVertFromCloud(fgl, (nt==:var ? fgl.IDs[lbl] : fgl.fIDs[lbl]), bigdata=bigdata) -end - -function updateFullCloudVertData!(fgl::G, - nv::Graphs.ExVertex; - updateMAPest::Bool=false, - bigdata::Bool=false ) where G <: AbstractDFG - # - # TODO -- this get_vertex seems excessive, but we need the CloudVertex - - if(!haskey(fgl.cgIDs, nv.index)) - error("Cannot find $(nv.index) in $(fgl.cgIDs)...") - end - neoID = fgl.cgIDs[nv.index] - # println("updateFullCloudVertData! -- trying to get $(neoID)") - vert = CloudGraphs.get_vertex(fgl.cg, neoID, false) - if typeof(getData(nv)) == VariableNodeData && updateMAPest - mv = getKDEMax(getBelief(nv)) - nv.attributes["MAP_est"] = mv - # @show nv.attributes["MAP_est"] - end - - # TODO -- ignoring other properties - vert.packed = getData(nv) #.attributes["data"] - for pair in nv.attributes - if pair[1] != "data" - vert.properties[pair[1]] = pair[2] - end - end - - # also make sure our local copy is updated, need much better refactoring here - fgl.stateless ? nothing : fgl.g.vertices[nv.index].attributes["data"] = nv.attributes["data"] - - CloudGraphs.update_vertex!(fgl.cg, vert, bigdata) -end - -function makeAddCloudEdge!(fgl::G, v1::Graphs.ExVertex, v2::Graphs.ExVertex) where G <: AbstractDFG - cv1 = CloudGraphs.get_vertex(fgl.cg, fgl.cgIDs[v1.index], false) - cv2 = CloudGraphs.get_vertex(fgl.cg, fgl.cgIDs[v2.index], false) - ce = CloudGraphs.CloudEdge(cv1, cv2, "DEPENDENCE"); - retrel = CloudGraphs.add_edge!(fgl.cg, ce); - - # TODO -- keep this edge id in function node data, must refactor - push!(v2.attributes["data"].edgeIDs, retrel.id) # TODO -- not good way to do this - updateFullCloudVertData!(fgl, v2) - - IncrementalInference.makeAddEdge!(fgl, v1, v2, saveedgeID=false) - retrel.id -end - - -# TODO -- fetching of CloudVertex propably not required, make faster request to @GearsAD -function getCloudOutNeighbors(fgl::G, - exVertId::Int64; - solvable::Int=1, - backendset::Int=1, - needdata::Bool=false ) where G <: AbstractDFG - # - # println("Looking for cloud out neighbors") - cgid = fgl.cgIDs[exVertId] - cv = CloudGraphs.get_vertex(fgl.cg, cgid, false) - neighs = CloudGraphs.get_neighbors(fgl.cg, cv) - neExV = Graphs.ExVertex[] - for n in neighs - cgn = CloudGraphs.cloudVertex2ExVertex(n) - if ( - #cgn.attributes["solvable"] == solvable && - #cgn.attributes["backendset"] == backendset && - (!needdata || haskey(cgn.attributes, "data") ) ) - push!(neExV, cgn ) - end - end - return neExV -end - -# return list of neighbors as Graphs.ExVertex type -function getCloudOutNeighbors(fgl::G, - vert::Graphs.ExVertex; - solvable::Int=1, - backendset::Int=1, - needdata::Bool=false ) where G <: AbstractDFG - # TODO -- test for solvable and backendset here - getCloudOutNeighbors(fgl, vert.index, solvable=solvable,backendset=backendset, needdata=needdata ) -end - - -function getEdgeFromCloud(fgl::G, id::Int64) where G <: AbstractDFG - println("getting id=$(id)") - CloudGraphs.get_edge(fgl.cg, id) -end - -function deleteCloudVertex!(fgl::G, vert::Graphs.ExVertex) where G <: AbstractDFG - neoID = fgl.cgIDs[vert.index] - cvr = CloudGraphs.get_vertex(fgl.cg, neoID, false) - CloudGraphs.delete_vertex!(fgl.cg, cvr) -end - -function deleteCloudEdge!(fgl::G, edge::CloudEdge) where G <: AbstractDFG - CloudGraphs.delete_edge!(fgl.cg, edge) -end - - - - -function usecloudgraphsdatalayer!() - IncrementalInference.setdatalayerAPI!( - addvertex= addCloudVert!, - getvertex= getExVertFromCloud, - makeaddedge= makeAddCloudEdge!, - getedge= getEdgeFromCloud, - outneighbors= getCloudOutNeighbors, - updatevertex= updateFullCloudVertData!, - deletevertex= deleteCloudVertex!, - deleteedge= deleteCloudEdge!, - cgEnabled= true ) - nothing -end - -function uselocalmemoryonly!() - IIF.setdatalayerAPI!( - addvertex= IIF.localapi.addvertex!, - getvertex= IIF.localapi.getvertex, - makeaddedge= IIF.localapi.makeaddedge!, - getedge= IIF.localapi.getedge, - outneighbors= IIF.localapi.outneighbors, - updatevertex= IIF.localapi.updatevertex!, - deletevertex= IIF.localapi.deletevertex!, - deleteedge= IIF.localapi.deleteedge!, - cgEnabled= false ) - nothing -end - - - -function getpackedtype(typestring::AS) where {AS <: AbstractString} - # println("Caesar.getpackedtype($(typestring))") - eval(Meta.parse(typestring))() # TODO consider caching or better -end - - - -# function should not be necessary, but fixes a minor bug following elimination algorithm -function removeGenericMarginals!(conn) - loadtx = transaction(conn) - query = "match (n)-[r]-() where n.packedType = 'IncrementalInference.FunctionNodeData{IncrementalInference.GenericMarginal}' detach delete n,r" - cph = loadtx(query, submit=true) - loadresult = commit(loadtx) - # TODO -- can probably be made better, but should not be necessary in the first place - loadtx = transaction(conn) - query = "match (n) where n.packedType = 'IncrementalInference.FunctionNodeData{IncrementalInference.GenericMarginal}' detach delete n" - cph = loadtx(query, submit=true) - loadresult = commit(loadtx) - nothing -end - -""" - $(SIGNATURES) - -Get all Neo4j node IDs in current session. -""" -function getAllExVertexNeoIDs(conn::Neo4j.Connection; - solvable::Int=1, - backendset::Int=1, - - sessionname::AS="", - robotname::AS="", - username::AS="", - reqbackendset::Bool=true, - reqSolvable::Bool=true ) where {AS <: AbstractString} - # - sn = length(sessionname) > 0 ? ":"*sessionname : "" - rn = length(robotname) > 0 ? ":"*robotname : "" - un = length(username) > 0 ? ":"*username : "" - query = "match (n$(sn)$(rn)$(un)) where not n:SESSION and not n:MULTISESSION and exists(n.exVertexId)" - query = reqbackendset || reqSolvable ? query*" and" : query - query = reqSolvable ? query*" n.solvable=$(solvable)" : query - query = reqbackendset && reqSolvable ? query*" and" : query - query = reqbackendset ? query*" n.backendset=$(backendset)" : query - query = query*" return n.exVertexId, id(n), n.label" - - cph, = executeQuery(conn, query) - ret = Array{Tuple{Int64,Int64,Symbol},1}() - - # If no results, return empty array... - if length(cph.results) > 0 - if length(cph.results[1]["data"]) > 0 - @showprogress 1 "Get ExVertex IDs..." for data in cph.results[1]["data"] - exvid, neoid, sym = data["row"][1], data["row"][2], Symbol(data["row"][3]) - push!(ret, (exvid,neoid,sym) ) - end - end - end - - return ret -end - - - -""" - $(SIGNATURES) - -Build query to fetch sub graph and neighboring nodes. For example: -FAILS IN SOME CASES -``` -match (n0:Hackathon:HexagonalDrive) -where n0.label IN ['x0'] -with n0 as m -return m.exVertexId, id(m), m.label -UNION -match (n0:Hackathon:HexagonalDrive)-[:DEPENDENCE]-(n1:HexagonalDrive) -where n0.label IN ['x0'] -with n1 as m -return m.exVertexId, id(m), m.label -UNION -match (n0:Hackathon:HexagonalDrive)-[:DEPENDENCE]-(n1:HexagonalDrive)-[:DEPENDENCE]-(n2:HexagonalDrive) -where n0.label IN ['x0'] -with n2 as m -return m.exVertexId, id(m), m.label -``` -""" -function buildSubGraphIdsQuery(; - lbls::Vector{AS}=String[""], - session::AS="", - robot::AS="", - user::AS="", - label::AS="", - reqSolvable::Bool=true, - solvable::Int=1, - reqbackendset::Bool=true, - backendset::Int=1, - neighbors::Int=0, - includeMultisession::Bool=false ) where {AS <: AbstractString} - # - sn = length(session) > 0 ? ":"*session : "" - rn = length(robot) > 0 ? ":"*robot : "" - un = length(user) > 0 ? ":"*user : "" - lb = length(label) > 0 ? ":"*label : "" - - query = "" - for nei in 0:(neighbors) - query *= "match (n0$(sn)$(rn)$(un)$(lb))" - outerd = 0 - for d in 1:(nei) - query *= "-[:DEPENDENCE]-(n$(d)$(sn)$(rn)$(un)$(lb))" - outerd = d - end - query *= " " - query *= "where n0.label IN [" - for lbl in lbls - query *= "'$(lbl)'," - end - query = chop(query)*"] " - if !includeMultisession - query *= "and not n0:MULTISESSION " - end - query *= "with n$(outerd) as m " - query *= "return m.exVertexId, id(m), m.label" - query *= nei != (neighbors) ? " UNION " : "" - end - return query -end -# qu = buildSubGraphIdsQuery(lbls=["x0";], session="HexagonalDrive", neighbors=3) -# @show qu - -""" - $(SIGNATURES) - -Return array of tuples with ExVertex IDs and Neo4j IDs for vertices with label in session. -""" -function getLblExVertexNeoIDs( - conn::Neo4j.Connection, - lbls::Vector{AS}; - session::AS="", - robot::AS="", - user::AS="", - label::AS="", - reqSolvable::Bool=true, - solvable::Int=1, - backendset::Int=1, - reqbackendset::Bool=true, - neighbors::Int=0, - includeMultisession::Bool=false) where {AS <: AbstractString} - # - - query = buildSubGraphIdsQuery(lbls=lbls, session=session, robot=robot, user=user, label=label, neighbors=neighbors, reqSolvable=reqSolvable, solvable=solvable, reqbackendset=reqbackendset, backendset=backendset, includeMultisession=includeMultisession) - cph, = executeQuery(conn, query) - - ret = Array{Tuple{Int64,Int64,Symbol},1}() - @showprogress 1 "Get ExVertex IDs..." for data in cph.results[1]["data"] - exvid, neoid, vsym = data["row"][1], data["row"][2], Symbol(data["row"][3]) - push!(ret, (exvid,neoid,vsym) ) - end - return ret -end - -""" - $(SIGNATURES) - -Return array of tuples with ExVertex IDs and Neo4j IDs for vertices with label in session. -""" -function getExVertexNeoIDs( - conn::Neo4j.Connection; - label::AS="", - solvable::Int=1, - backendset::Int=1, - session::AS="", - robot::AS="", - user::AS="", - reqbackendset::Bool=true ) where {AS <: AbstractString} - # - sn = length(session) > 0 ? ":"*session : "" - rn = length(robot) > 0 ? ":"*robot : "" - un = length(user) > 0 ? ":"*user : "" - lb = length(label) > 0 ? ":"*label : "" - query = "match (n$(sn)$(rn)$(un)$(lb)) where n.solvable=$(solvable) and exists(n.exVertexId)" - query = reqbackendset ? query*" and n.backendset=$(backendset)" : query - query = query*" return n.exVertexId, id(n), n.label" - - cph, = executeQuery(conn, query) - # loadtx = transaction(conn) - # cph = loadtx(query, submit=true) - - ret = Array{Tuple{Int64,Int64,Symbol},1}() - @showprogress 1 "Get ExVertex IDs..." for data in cph.results[1]["data"] - exvid, neoid, vsym = data["row"][1], data["row"][2], Symbol(data["row"][3]) - push!(ret, (exvid,neoid,vsym) ) - end - return ret -end - -""" - $(SIGNATURES) - -Return array of tuples with ExVertex IDs and Neo4j IDs for all poses. -""" -function getPoseExVertexNeoIDs(conn::Neo4j.Connection; - solvable::Int=1, - backendset::Int=1, - session::AS="", - reqbackendset::Bool=true ) where {AS <: AbstractString} - # - getPoseExVertexNeoIDs(conn, - label="POSE", - solvable=solvable, - backendset=backendset, - session=session, - reqbackendset=reqbackendset ) -end - - -function checkandinsertedges!(fgl::G, exvid::Int, nei::CloudVertex; solvable::Int=1, backendset::Int=1) where G <: AbstractDFG - if nei.properties["solvable"]==solvable && - nei.properties["backendset"] == backendset && - haskey(fgl.g.vertices, nei.exVertexId) - #&& nei.exVertexId <= length(fgl.g.vertices) - alreadythere = false - - # TODO -- error point - v2 = fgl.g.vertices[nei.exVertexId] - for graphsnei in Graphs.out_neighbors(v2, fgl.g) # specifically want Graphs function - # want to ignore if the edge was previously added from the other side, comparing to the out neighbors in the Graphs structure - if graphsnei.index == exvid #graphsnei.index == nei.exVertexId - alreadythere = true - break; - end - end - if !alreadythere - # add the edge to graph - v1 = fgl.g.vertices[exvid] - makeAddEdge!(fgl, v1, v2, saveedgeID=false) - end - end - nothing -end - -function copyAllEdges!(fgl::G, cverts::Dict{Int64, CloudVertex}, IDs::Array{Tuple{Int64,Int64, Symbol},1}) where G <: AbstractDFG - # TODO -- major opportunity for streamlining and improving performance - # do entire graph, one node at a time - @showprogress 1 "Copy all edges..." for ids in IDs - for nei in CloudGraphs.get_neighbors(fgl.cg, cverts[ids[2]], needdata=true) - checkandinsertedges!(fgl, ids[1], nei, solvable=1, backendset=1) - end - end - nothing -end - -function insertnodefromcv!(fgl::G, cvert::CloudGraphs.CloudVertex) where G <: AbstractDFG - exvid = cvert.exVertexId - neoid = cvert.neo4jNodeId - exvert = cloudVertex2ExVertex(cvert) - # TODO -- change to addNode - Graphs.add_vertex!(fgl.g, exvert) - fgl.id < exvert.index ? fgl.id = exvert.index : nothing - fgl.cgIDs[exvid] = neoid - if typeof(exvert.attributes["data"]) == VariableNodeData # variable node - fgl.IDs[Symbol(exvert.label)] = exvid - push!(fgl.nodeIDs, exvid) - else # function node - fgl.fIDs[Symbol(exvert.label)] = exvid - push!(fgl.factorIDs, exvid) - end - nothing -end - -""" - $(SIGNATURES) - -Copy all variable and factor nodes from DB into fgl as listed in IDs vector. -""" -function copyAllNodes!(fgl::G, - cverts::Dict{Int64, CloudVertex}, - IDs::Array{Tuple{Int64,Int64, Symbol},1} ) where G <: AbstractDFG - # conn::Neo4j.Connection ) # what the? - # - @showprogress 1 "Copy all nodes..." for ids in IDs - cvert = CloudGraphs.get_vertex(fgl.cg, ids[2], false) - cverts[ids[2]] = cvert - insertnodefromcv!(fgl, cvert) - end - nothing -end - -""" - $(SIGNATURES) - -Copy nodes into `fgl` from DB as listed in the `IDs` vector. -""" -function copyGraphNodesEdges!(fgl::G, - IDs::Array{Tuple{Int64,Int64, Symbol},1} ) where G <: AbstractDFG - # - if length(IDs) > 0 - cverts = Dict{Int64, CloudVertex}() - unsorted = Int64[] - for ids in IDs - push!(unsorted, ids[1]) - end - perm = sortperm(unsorted) - - # get and add all the nodes - sortedIDs = IDs[perm] - copyAllNodes!(fgl, cverts, sortedIDs) - - # get and insert all edges - copyAllEdges!(fgl, cverts, sortedIDs) - return true - else - print(".") - return false - end -end - -""" - $(SIGNATURES) - -Copy sub graph portion defined by, and including a depth of neighbors, from the lbls vector. -""" -function subLocalGraphCopy!(fgl::G, - lbls::Union{Vector{AS}, Vector{Symbol}}; - neighbors::Int=0, - reqbackendset::Bool=true, - reqSolvable::Bool=true, - includeMultisession::Bool=false) where {G <: AbstractDFG, AS <: AbstractString} - # - @warn "subGraphCopy! is a work in progress" - conn = fgl.cg.neo4j.connection - IDs = getLblExVertexNeoIDs(conn, string.(lbls), session=fgl.sessionname, robot=fgl.robotname, user=fgl.username, reqbackendset=reqbackendset, reqSolvable=reqSolvable, neighbors=neighbors, includeMultisession=includeMultisession) - println("fullSubGraphCopy: $(length(IDs)) nodes in session $(fgl.sessionname) if reqbackendset=$reqbackendset and reqSolvable=$reqSolvable...") - copyGraphNodesEdges!(fgl, IDs) - nothing -end - - -""" - $(SIGNATURES) - -Fetch a full copy of the DB factor graph under fgl.sessionname. -""" -function fullLocalGraphCopy!(fgl::G; - reqbackendset::Bool=true, - reqSolvable::Bool=true ) where G <: AbstractDFG - # - conn = fgl.cg.neo4j.connection - IDs = getAllExVertexNeoIDs(conn, sessionname=fgl.sessionname, robotname=fgl.robotname, username=fgl.username, reqbackendset=reqbackendset, reqSolvable=reqSolvable) - println("fullLocalGraphCopy: $(length(IDs)) nodes in subgraph for user=$(fgl.username), robot=$(fgl.robotname), session=$(fgl.sessionname) if reqbackendset=$reqbackendset and reqSolvable=$reqSolvable...") - copyGraphNodesEdges!(fgl, IDs) -end - -""" - $(SIGNATURES) - -Set all Neo4j nodes in this session solvable = 1, warning function does not support new GraffSDK data storage formats. -""" -function setAllDBSolvable!(conn::Neo4j.Connection, - sessionname::AS, - robotname::AS, - username::AS) where {AS <: AbstractString} - # - @warn "Obsolete setAllDBSolvable! function, see GraffSDK for example solvable function instead." - sn = length(sessionname) > 0 ? ":"*sessionname : "" - rn = length(robotname) > 0 ? ":"*robotname : "" - un = length(username) > 0 ? ":"*username : "" - query = "match (n$(sn)$(rn)$(un)) set n.solvable=1" - cph, loadresult = executeQuery(conn, query) - nothing -end - -# TODO --this will only work with DB version, introduces a bug -function setAllDBSolvable!(fgl::G) where G <: AbstractDFG - setAllDBSolvable!(fgl.cg.neo4j.connection, fgl.sessionname) -end - - -function setBackendWorkingSet!( - conn::Neo4j.Connection, - sessionname::AbstractString, - robotname::AbstractString, - username::AbstractString ) - # - sn = length(sessionname) > 0 ? ":"*sessionname : "" - rn = length(robotname) > 0 ? ":"*robotname : "" - un = length(username) > 0 ? ":"*username : "" - query = "match (n$(sn)$(rn)$(un)) where not (n:NEWDATA) set n.backendset=1" - - cph, loadresult = executeQuery(conn, query) - nothing -end - -""" - $(SIGNATURES) - -Obtain Neo4j global database address and login credientials from STDIN, then insert and return in the addrdict colletion. -""" -function askneo4jcredentials!(;addrdict=Dict{AbstractString,AbstractString}() ) - need = ["neo4jHost";"neo4jPort";"neo4jUsername";"neo4jPassword";"session";"robotId"] - info("Please enter information for Neo4j DB:") - for n in need - info(n) - str = readline(stdin) - addrdict[n] = str - if length(str) > 0 - if str[end] == "\n" - addrdict[n] = str[1:(end-1)] - end - end - end - return addrdict -end - -""" - $(SIGNATURES) - -Obtain Mongo database address and login credientials from STDIN, then insert and return in the addrdict colletion. -""" -function askmongocredentials!(;addrdict=Dict{AbstractString,AbstractString}() ) - need = ["mongoHost";"mongoPort";"mongoUsername";"mongoPassword"] - info("Please enter information for MongoDB:") - for n in need - info(n) - n == "mongoHost" && haskey(addrdict, "neo4jHost") ? print(string("[",addrdict["neo4jHost"],"]: ")) : nothing - str = readline(stdin) - addrdict[n] = str - if length(str) > 0 - if str[end] == "\n" - addrdict[n] = str[1:(end-1)] - end - end - end - addrdict["mongoIsUsingCredentials"] = false, - if addrdict["mongoHost"] == "" && haskey(addrdict, "neo4jHost") - addrdict["mongoHost"] = addrdict["neo4jHost"] - elseif addrdict["mongoHost"] != "" - nothing - else - error("Don't know how to get to MongoDB address.") - end - return addrdict -end - - -""" - $(SIGNATURES) - -Obtain database addresses and login credientials from STDIN, as well as a few case dependent options. -""" -function consoleaskuserfordb(;nparticles=false, drawdepth=false, clearslamindb=false, multisession=false, drawedges=false) - addrdict = Dict{AbstractString, Any}() #Union{AbstractString, Vector{String}} - askneo4jcredentials!(addrdict=addrdict) - askmongocredentials!(addrdict=addrdict) - need = String[] - !nparticles ? nothing : push!(need, "num particles") - !drawdepth ? nothing : push!(need, "draw depth") - !clearslamindb ? nothing : push!(need, "clearslamindb") - !user ? nothing : push!(need, "user") - !robot ? nothing : push!(need, "robot") - !multisession ? nothing : push!(need, "multisession") - !drawedges ? nothing : push!(need, "draw edges") - - - info("Please also enter information for:") - for n in need - info(n) - n == "draw depth" ? print("[y]/n: ") : nothing - n == "draw edges" ? print("[y]/n: ") : nothing - n == "num particles" ? print("[100]: ") : nothing - n == "clearslamindb" ? print("yes/[no]: ") : nothing - n == "user" ? print("[]: ") : nothing - n == "robot" ? print("[]: ") : nothing - n == "multisession" ? print("comma separated list session names/[n]: ") : nothing - str = readline(stdin) - addrdict[n] = str - if length(str) > 0 - if str[end] == "\n" - addrdict[n] = str[1:(end-1)] - end - end - end - if drawdepth - addrdict["draw depth"] = addrdict["draw depth"]=="" || addrdict["draw depth"]=="y" || addrdict["draw depth"]=="yes" ? "y" : "n" - end - if drawedges - addrdict["draw edges"] = addrdict["draw edges"]=="" || addrdict["draw edges"]=="y" || addrdict["draw edges"]=="yes" ? "y" : "n" - end - if nparticles - addrdict["num particles"] = addrdict["num particles"]!="" ? addrdict["num particles"] : "100" - end - if clearslamindb - addrdict["clearslamindb"] = addrdict["clearslamindb"]=="" || addrdict["clearslamindb"]=="n" || addrdict["clearslamindb"]=="no" ? "n" : addrdict["clearslamindb"] - end - if user - addrdict["user"] = addrdict["user"]!="" ? addrdict["user"] : "" - end - if robot - addrdict["robot"] = addrdict["robot"]!="" ? addrdict["robot"] : "" - end - if multisession - addrdict["multisession"] = strip.(Vector{String}(split(addrdict["multisession"],','))) - end - return addrdict -end - - -""" - $(SIGNATURES) - -Connect to databases via network according to addrdict, or ask user for credentials and return -active cloudGraph object, as well as addrdict. -""" -function standardcloudgraphsetup(;addrdict=nothing, - nparticles::Bool=false, - drawdepth::Bool=false, - drawedges::Bool=false, - clearslamindb::Bool=false, - multisession::Bool=false ) - # - if addrdict == nothing - addrdict = consoleaskuserfordb(nparticles=nparticles, drawdepth=drawdepth, clearslamindb=clearslamindb, multisession=multisession, drawedges=drawedges) - end - - @warn "Not considering field: addrdict[\"mongoIsUsingCredentials\"]" - # Connect to database - # addrdict["mongoIsUsingCredentials"] - configuration = CloudGraphs.CloudGraphConfiguration( - addrdict["neo4jHost"], parse(Int, addrdict["neo4jPort"]), addrdict["neo4jUsername"], addrdict["neo4jPassword"], - addrdict["mongoHost"], parse(Int, addrdict["mongoPort"]), false, addrdict["mongoUsername"], addrdict["mongoPassword"]); - cloudGraph = connect(configuration, IncrementalInference.encodePackedType, Caesar.getpackedtype, IncrementalInference.decodePackedType); - # conn = cloudGraph.neo4j.connection - # register types of interest in CloudGraphs - # registerGeneralVariableTypes!(cloudGraph) # TESTING -- using dispatch instead - Caesar.usecloudgraphsdatalayer!() - - return cloudGraph, addrdict -end - -""" - $(SIGNATURES) - -Walk through vertex bigDataElements and return the last matching description. -""" -function getBigDataElement(vertex::CloudVertex, description::AbstractString) - bde = nothing - for bDE in vertex.bigData.dataElements - if bDE.description == description - bde = bDE - end - end - return bde -end - -""" - $(SIGNATURES) - -Return true if vertex has bigDataElements with matching description. -""" -function hasBigDataElement(vertex::CloudVertex, description::AbstractString) - for bDE in vertex.bigData.dataElements - if bDE.description == description - return true - end - end - return false -end - -""" - $(SIGNATURES) - -Append big data element into current blob store and update associated global -vertex information. -""" -function appendvertbigdata!(cloudGraph::CloudGraph, - cv::CloudVertex, - description, - data::Vector{UInt8} ) - # - bd = CloudGraphs.read_BigData!(cloudGraph, cv) - bdei = CloudGraphs.BigDataElement(description, data) - push!(cv.bigData.dataElements, bdei); - CloudGraphs.save_BigData!(cloudGraph, cv) -end - -""" - $(SIGNATURES) - -Append big data element into current blob store and update associated global -vertex information. -""" -function appendvertbigdata!(fgl::G, - vert::Graphs.ExVertex, - description::AbstractString, - data::Vector{UInt8} ) where G <: AbstractDFG - # - # TODO -- improve get/fetch vertex abstraction - cvid = fgl.cgIDs[vert.index] - cv = CloudGraphs.get_vertex(fgl.cg, cvid, true) - appendvertbigdata!(fgl.cg, cv, description, data) -end - - -""" - appendvertbigdata!(fg, sym, descr, data) - -Append big data element into current blob store using parent appendvertbigdata!, -but here specified by symbol of variable node in the FactorGraph. Note the -default data layer api definition. User must define dlapi to refetching the - vertex from the data layer. localapi avoids repeated network database fetches. -""" -function appendvertbigdata!(fgl::G, - sym::Symbol, - description::AbstractString, - data ) where G <: AbstractDFG - # - appendvertbigdata!(fgl, - getVert(fgl, sym), - description, - data ) -end - - -""" - $(SIGNATURES) - -Fetch and insert list of CloudVertices into FactorGraph object, up to neighbor depth. -""" -function fetchsubgraph!(fgl::G, - cvs::Vector{CloudGraphs.CloudVertex}; - numneighbors::Int=0 ) where G <: AbstractDFG - # overwrite::Bool=false ) - # recursion termination condition - numneighbors >= 0 ? nothing : (return nothing) - - for cv in cvs - # test if these are already in fgl - if !hasval(fgl.cgIDs, cv.neo4jNodeId) # may have been inserted as previous neighbor - # add this vert to graph - insertnodefromcv!(fgl, cv) - - # recursive call on neighbors here - neicvs = CloudGraphs.get_neighbors(fgl.cg, cv, needdata=true) - fetchsubgraph!(fgl, neicvs; numneighbors=numneighbors-1 ) - # add edges associated with the neighbors - - if numneighbors-1 >= 0 - for cvn in neicvs - checkandinsertedges!(fgl, cv.exVertexId, cvn, solvable=1, backendset=1) - # makeAddEdge!(fgl, fgl.g.vertices[cv.exVertexId], fgl.g.vertices[cvn.exVertexId], saveedgeID=false) - end - end - end - - end -end - -""" - $SIGNATURES - -Fetch and insert list of Neo4j IDs into FactorGraph object, up to neighbor depth. -""" -function fetchsubgraph!(fgl::G, - neoids::Vector{Int}; - numneighbors::Int=0 ) where G <: AbstractDFG - # overwrite::Bool=false ) - # - for nid in neoids - # test if these are already in fgl - if !hasval(fgl.cgIDs, nid) - cv = CloudGraphs.get_vertex(fgl.cg, nid, false) - fetchsubgraph!(fgl, [cv], numneighbors=numneighbors ) - end - end - nothing -end - -""" - getVertNeoIDs!(::CloudGraph, res::Dict{Symbol, Int}; session::AbstractString="NA", robot::AbstractString="NA", user::AbstractString="NA") - -Insert into and return dict `res` with Neo4j IDs of ExVertex labels as stored per session in Neo4j database. -""" -function getVertNeoIDs!(cloudGraph::CloudGraph, res::Dict{Symbol, Int}; session::AbstractString="NA", robot::AbstractString="NA", user::AbstractString="NA") - loadtx = transaction(cloudGraph.neo4j.connection) - syms = collect(keys(res)) - query = "match (n:$(session):$robot:$user) where " - for i in 1:length(syms) - sym = syms[i] - query =query*"n.label='$(sym)' " - if i < length(syms) - query =query*"or " - end - end - query = query*"return id(n), n.label" - cph = loadtx(query, submit=true) - for qr in cph.results[1]["data"] - res[Symbol(qr["row"][2])] = qr["row"][1] - end - # Symbol(cph.results[1]["data"][1]["row"][2]) == sym ? nothing : error("Neo4j query not returning $(sym)") - return res -end - -""" - removeNeo4jID(cg::CloudGraph, neoid=-1) - -Remove node from Neo4j according to Neo4j Node ID. Big data elements that may be associated with this -node are not removed. -""" -function removeNeo4jID(cg::CloudGraph; neoid::Int=-1) - neoid > 0 ? nothing : error("Can't delete negative neoid=$(neoid).") - loadtx = transaction(cg.neo4j.connection) - query = "match (n) where id(n)=$(neoid) detach delete n return count(n)" - cph = loadtx(query, submit=true) - commit(loadtx) - cnt = Int(cph.results[1]["data"][1]["row"][1]) - cnt == 1 ? nothing : error("Did not delete just one entry after running query = $(query)") - nothing -end - - - -""" - getfirstpose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - -Return Tuple{Symbol, Int} of first pose symbol and Neo4j node ID. -""" -function getfirstpose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - query = "match (n:$(session):$(robot):$(user):POSE) with n.label as nlbl, n.exVertexId as exvid, id(n) as neoid order by exvid asc limit 1 return nlbl, neoid" - cph, = executeQuery(cg, query) - # loadtx = transaction(cg.neo4j.connection) - # cph = loadtx(query, submit=true) - Symbol(cph.results[1]["data"][1]["row"][1]), cph.results[1]["data"][1]["row"][2] -end -getFirstPose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) = getfirstpose(cg, session, robot, user) - -""" - getLastPose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - -Return Tuple{Symbol, Int} of first pose symbol and Neo4j node ID. -""" -function getLastPose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - query = "match (n:$(session):$robot:$user:POSE) with n.label as nlbl, n.exVertexId as exvid, id(n) as neoid order by exvid desc limit 1 return nlbl, neoid" - cph, = executeQuery(cg, query) - # loadtx = transaction(cg.neo4j.connection) - # cph = loadtx(query, submit=true) - Symbol(cph.results[1]["data"][1]["row"][1]), cph.results[1]["data"][1]["row"][2] -end - - -""" - insertrobotdatafirstpose!(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString, robotdict::Dict) - -Saves robotdict via JSON to first pose in a SESSION in the database. Used for -storing general robot specific data in easily accessible manner. Can fetch later -retrieve same dict with counterpart `fetchrobotdatafirstpose` function. -""" -function insertrobotdatafirstpose!(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString, robotdict::Dict) - vsym, neoid = getfirstpose(cg, session, robot, user) - cv = CloudGraphs.get_vertex(cg, neoid, true) - appendvertbigdata!(cg, cv, "robot_description", json(robotdict).data ) -end - -function tryunpackalltypes!(resp::Dict) - for (k,v) in resp - tv = typeof(v) - if tv == Vector{Any} - ttv = typeof(v[1]) - if ttv == Vector{Any} - try resp[k] = hcat(v...) catch end - else - try resp[k] = Vector{ttv}(v) catch end - end - end - end - nothing -end - -""" - fetchrobotdatafirstpose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - -Return dict of JSON parsed "robot_description" field as was inserted by counterpart -`insertrobotdatafirstpose!` function. Used for storing general robot specific data -in easily accessible manner. -""" -function fetchrobotdatafirstpose(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - vsym, neoid = getfirstpose(cg, session, robot, user) - cv = CloudGraphs.get_vertex(cg, neoid, true) - bde = Caesar.getBigDataElement(cv, "robot_description") - resp = JSON.parse(String(take!(IOBuffer(bde.data)))) - tryunpackalltypes!(resp) - return resp -end - - -""" - getRangeKDEMax2D(cgl::CloudGraph, session::AbstractString, vsym1::Symbol, vsym2::Symbol) - -Calculate the cartesian distange between two vertices in the graph, by session and symbol names, -and by maximum belief point. -""" -function getRangeKDEMax2D(cgl::CloudGraph, session::AbstractString, vsym1::Symbol, vsym2::Symbol) - # get the relavent neo4j ids - syms = Dict(vsym1=>0, vsym2 => 0) - getVertNeoIDs!(cgl, syms, session=session) - - # build a local subgraph - sfg = initfg(cloudgraph=cgl, sessionname=session) - fetchsubgraph!(sfg, collect(values(syms)), numneighbors=1 ) - - # calculate distances on local subgraph - getRangeKDEMax2D(sfg, vsym1, vsym2) -end - - -""" - db2jld(cgl::CloudGraph, session::AbstractString, filename::AbstractString) - -Fetch and save a FactorGraph session to a jld, using CloudGraph object and session definition. -""" -function db2jld(cgl::CloudGraph, session::AbstractString, filename::AbstractString) - fg = initfg(sessionname=session, cloudgraph=cgl) - fullLocalGraphCopy!(fg) - savejld(fg, file=filename) - return fg -end - -""" - db2jld(filename::AbstractString; addrdict::NothingUnion{Dict{AbstractString, AbstractString}}=nothing ) - -Fetch and save a FactorGraph session to a jld, using or asking STDIN for credentials in the addrdict field. -""" -function db2jld(filename::AbstractString; addrdict::NothingUnion{Dict{AbstractString, AbstractString}}=nothing ) - cg, cr = standardcloudgraphsetup(addrdict=addrdict) - db2jld(cg, cr["session"], filename) -end - - -function deleteServerSession!(cloudGraph::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString) - query = "match (n:$(session):$robot:$user) - detach delete n - return count(n)" - return executeQuery(cloudGraph.neo4j.connection, query) -end - -# function syncmongos() -# -# end - - # diff --git a/src/attic/cloudgraphs/ConvertGeneralSlaminDB.jl b/src/attic/cloudgraphs/ConvertGeneralSlaminDB.jl deleted file mode 100644 index cc1848a71..000000000 --- a/src/attic/cloudgraphs/ConvertGeneralSlaminDB.jl +++ /dev/null @@ -1,394 +0,0 @@ -# Convert slamindb Functions - - - - -function getmaxfactorid(conn, session::AbstractString, robot::AbstractString, user::AbstractString) - loadtx = transaction(conn) - query = "match (n:$(session):$robot:$user:FACTOR) - where not (n:NEWDATA) - with id(n) as idn, n.exVertexId as nexvid - order by nexvid desc limit 1 - return idn, nexvid" - cph = loadtx(query, submit=true) - exvid = 0 - if length(cph.results[1]["data"]) > 0 - neoid = cph.results[1]["data"][1]["row"][1] - exvid = cph.results[1]["data"][1]["row"][2] - end - return exvid -end - -""" - getnewvertdict(conn, session::AbstractString, robot::AbstractString, user::AbstractString) - -Return a dictionary with frtend and mongo_keys json string information for :NEWDATA -elements in Neo4j database. -""" -function getnewvertdict(conn, session::AbstractString, robot::AbstractString, user::AbstractString) - - loadtx = transaction(conn) - query = "match (n:$(session):$robot:$user)-[:DEPENDENCE]-(f:NEWDATA:$(session):$robot:$user:FACTOR) where n.solvable=1 or f.solvable=1 return distinct n, f" - cph = loadtx(query, submit=true) - # loadresult = commit(loadtx) - # @show cph.results[1] - - newvertdict = DataStructures.SortedDict{Int, Dict{Symbol, Dict{AbstractString,Any}}, Base.Order.ForwardOrdering}(Base.Order.ForwardOrdering()) - # mongokeydict = Dict{Int, Dict{AbstractString,Any}}() - - for val in cph.results[1]["data"] - i = 0 - for elem in val["meta"] - # @show elem["type"] # @show rdict["type"] - i+=1 - newvertdict[elem["id"]] = Dict{Symbol, Dict{AbstractString,Any}}() - for (k,nv) in val["row"][i] - if Symbol(k) == :frtend - newvertdict[elem["id"]][Symbol(k)] = JSON.parse(nv) - else - newvertdict[elem["id"]][Symbol(k)] = Dict{AbstractString, Any}("val"=> nv) - end - end - # rdict = JSON.parse(val["row"][i]["frtend"]) - # newvertdict[elem["id"]][:frtend] = rdict - # if haskey(val["row"][i], "mongo_keys") - # # @show val["row"][i]["mongo_keys"] - # newvertdict[elem["id"]][:mongokeys] = JSON.parse(val["row"][i]["mongo_keys"]) - # end - # # if uppercase(rdict["type"])=="POSE" || uppercase(rdict["type"])=="FACTOR" - # # npsym = Symbol(string("x",parse(Int, rdict["userid"])+1)) # TODO -- fix :x0 requirement - end - # println() - end - - return newvertdict -end - -""" - parseMergeVertAttr(v, elem) - -Parse elem dictionary according to thin ```frtend``` interface from other languages, -and merge contents into attributes of ```v::Graphs.ExVertex```. -""" -function parseMergeVertAttr!(v::Graphs.ExVertex, elem) - mongos = Dict() - for (k,va) in elem - if k == :frtend - v.attributes[string(k)] = JSON.json(va) - elseif k == :mongo_keys - mongos = JSON.parse(va["val"]) - v.attributes[string(k)] = va["val"] - elseif k == :solvable - v.attributes[string(k)] = typeof(va["val"]) == Int ? va["val"] : parse(Int,va["val"]) - else - @warn "setting $(k) to $(typeof(va["val"]))" - v.attributes[string(k)] = va["val"] # this is replacing data incorrectly - end - end - return mongos -end - -""" - mergeCloudVertex!(...) - -Hodgepodge function to merge data in CloudVertex -""" -function mergeCloudVertex!(cg::CloudGraph, - v::Graphs.ExVertex, - neoNodeId::Int, - alreadyexists::Bool, - neo4jNode, - existlbs::Vector{AbstractString}, - mongos; - labels::Vector{T}=String[] ) where {T <: AbstractString} - # - cv = CloudVertex() - if alreadyexists - # simply fetch existing cloudgraph if it exists, AGAIN - cv = CloudGraphs.get_vertex(cg, neoNodeId) - cgv = cloudVertex2ExVertex(cv) - # NOTE, overwrite all values, assuming this is ONLY HAPPENING WITH VARIABLENODES - # not checking to unpack Packed types - for (ke,val) in cgv.attributes - v.attributes[ke] = val - end - else - cv = exVertex2CloudVertex( v ) - cv.neo4jNode = neo4jNode - cv.neo4jNodeId = neoNodeId - # can't fetch in cloudgraphs with thin interface: (fntend, mongo_keys, ready) - cv.isValidNeoNodeId = true - filter!(e->e!="NEWDATA",existlbs) - cv.labels = union(existlbs, labels) - end - - # want to check the mongo keys anyway, since they could have changed - mergeBigDataElements!(cv.bigData.dataElements, mongos) - return cv -end - - -function mergeBigDataElements!(bdes::Vector{BigDataElement}, mongos::Dict) - if mongos != nothing - for (k,oid) in mongos - - haskey = false - for bd in bdes - if bd.description == k - @warn "skipping bigDataElement $(bd.description), assumed to be repeat during merge." - haskey = true - end - end - if !haskey - println("transfer mongo oid $((k,oid))") - # empty data, since we will call update_NeoBigData and not save_BigData - bdei = CloudGraphs.BigDataElement(k, Vector{UInt8}(), string(oid)) - push!(bdes, bdei); - end - end - # else - # println("no mongo") - end - nothing -end - -function mergeValuesIntoCloudVert!(fgl::G, - neoNodeId::Int, - elem, - uidl, - v::Graphs.ExVertex; - tags::Vector{T}=Symbol[] ) where {G <: AbstractDFG, T <: AbstractString} - # - - # why am I getting a node again (because we don't have the labels here)? - # TODO -- pass labels via elem dictionary - neo4jNode = Neo4j.getnode(fgl.cg.neo4j.graph, neoNodeId) - existlbs = Vector{AbstractString}(neo4jNode.metadata["labels"]) - - alreadyexists = sum(existlbs .== "NEWDATA") == 0 - - # parse dictionary of values retrieved from Neo4j - mongos = parseMergeVertAttr!(v, elem) - - if !haskey(fgl.cgIDs, uidl) - fgl.cgIDs[uidl] = neoNodeId - else - fgl.cgIDs[uidl] == neoNodeId ? nothing : error("trying to merge neo ids $(fgl.cgIDs[uidl]) and $(neoNodeId)") - end - - # merge CloudVertex - cv = mergeCloudVertex!(fgl.cg, v, neoNodeId, alreadyexists, neo4jNode, existlbs, mongos, tags=tags ) - - # update merged vertex to database - CloudGraphs.update_vertex!(fgl.cg, cv, true) - # CloudGraphs.update_NeoBigData!(fgl.cg, cv) - nothing -end - -function parsePose2Pose2Constraint(lkl, elem) - msm = split(elem["meas"], ' ') - cov = zeros(3,3) - cov[1,2], cov[1,3], cov[2,3] = parse(Float64, msm[5]), parse(Float64, msm[6]), parse(Float64, msm[8]) - cov += cov' - cov[1,1], cov[2,2], cov[3,3] = parse(Float64, msm[4]), parse(Float64, msm[7]), parse(Float64, msm[9]) - zij = zeros(3,1) - zij[:,1] = [parse(msm[1]);parse(msm[2]);parse(msm[3])] - if length(lkl) >=4 - if lkl[4] == "STDEV" - cov = cov^2 - end - end - return Pose2Pose2(zij, cov, [1.0]) -end - -function recoverConstraintType(cgl::CloudGraph, - elem; - mongokeys::Dict=Dict(), - N::Int=200 ) - # - lkl = split(elem["lklh"], ' ') - if lkl[1]=="PR2" - msm = split(elem["meas"], ' ') - cov = zeros(3,3) - cov[1,2], cov[1,3], cov[2,3] = parse(Float64, msm[5]), parse(Float64, msm[6]), parse(Float64, msm[8]) - cov += cov' - cov[1,1], cov[2,2], cov[3,3] = parse(Float64, msm[4]), parse(Float64, msm[7]), parse(Float64, msm[9]) - zi = zeros(3,1) - zi[:,1] = [parse(msm[1]);parse(msm[2]);parse(msm[3])] - return PriorPose2(MvNormal(zi, cov^2)) - elseif lkl[1]=="PTPR2" - msm = split(elem["meas"], ' ') - cov = zeros(2,2) - cov[1,2] = parse(Float64, msm[4])^2 - cov += cov' - cov[1,1], cov[2,2] = parse(Float64, msm[3])^2, parse(Float64, msm[5])^2 - zi = zeros(2) - zi[1:2] = [parse(msm[1]);parse(msm[2])] - return PriorPoint2(MvNormal(zi, cov)) - elseif lkl[1]=="PP2" - return parsePose2Pose2Constraint(lkl, elem) - # msm = split(elem["meas"], ' ') - # cov = zeros(3,3) - # cov[1,2], cov[1,3], cov[2,3] = parse(Float64, msm[5]), parse(Float64, msm[6]), parse(Float64, msm[8]) - # cov += cov' - # cov[1,1], cov[2,2], cov[3,3] = parse(Float64, msm[4]), parse(Float64, msm[7]), parse(Float64, msm[9]) - # zij = zeros(3,1) - # zij[:,1] = [parse(msm[1]);parse(msm[2]);parse(msm[3])] - # return Pose2Pose2(zij, cov^2, [1.0]) - elseif lkl[1]=="BR" - msm = split(elem["meas"], ' ') - return Pose2Point2BearingRange{Normal, Normal}( - Normal(parse(msm[1]), parse(Float64, msm[3]) ), - Normal(parse(msm[2]),parse(Float64, msm[5]) ) ) - elseif lkl[1]=="rangeBearingMEAS" - @show rangekey = mongokeys["range"] - rngs = bin2arr(CloudGraphs.read_MongoData(cgl, rangekey)) - # rngs = Vector{Float64}(elem["range"] ) - @show bearingkey = mongokeys["bearing"] - bearing = bin2arr(CloudGraphs.read_MongoData(cgl, bearingkey)) - # bearing = Vector{Float64}(elem["bearing"] ) - @show size(rngs), size(bearing) - prange = resample(kde!(rngs),N) - pbear = resample(kde!(bearing),N) - # warn("temporary return") - # return prange, pbear - return Pose2Point2BearingRangeDensity(pbear, prange) - elseif lkl[1]=="rangeMEAS" - @show rangekey = mongokeys["range"] - rngs = bin2arr(CloudGraphs.read_MongoData(cgl, rangekey)) - # rngs = Vector{Float64}(elem["range"] ) - @show size(rngs) - prange = resample(kde!(rngs),N) - # warn("temporary return") - # return prange - return Pose2Point2RangeDensity(prange) - else - return error("Don't know how to convert $(lkl[1]) to a factor") - end -end - - -function populatenewvariablenodes!(fgl::G, newvertdict::SortedDict; N::Int=100) where G <: AbstractDFG - - for (neoNodeId,elem) in newvertdict - # @show neoNodeId - nlbsym = Symbol() - uidl = 0 - tags = Symbol[Symbol("$(fgl.sessionname)")] - initvals = Array{Float64,2}() - if elem[:frtend]["t"] == "P" - uidl = elem[:frtend]["uid"]+1 # TODO -- remove +1 and allow :x0, :l0 - nlbsym = Symbol(string('x', uidl)) - initvals = 0.1*randn(3,N) # TODO -- fix init to proper values - push!(tags,:POSE) - elseif elem[:frtend]["t"] == "L" - @warn "using hack counter for LANDMARKS uid +200000" - uidl = elem[:frtend]["tag_id"]+200000 # TODO complete hack - nlbsym = Symbol(string('l', uidl)) - initvals = 0.1*randn(2,N) # Make sure autoinit still works properly - push!(tags,:LANDMARK) - end - if !haskey(fgl.IDs, nlbsym) && nlbsym != Symbol() - # @show nlbsym, size(initvals) - # TODO remove initstdev, deprecated - v = addVariable!(fgl, nlbsym, initvals, 0.01*eye(size(initvals,2)), N=N, solvable=0, uid=uidl,api=localapi) - mergeValuesIntoCloudVert!(fgl, neoNodeId, elem, uidl, v, tags=tags) - println() - end - end - println("done populating new variables") - nothing -end - -function populatenewfactornodes!(fgl::G, newvertdict::SortedDict, maxfuid::Int) where G <: AbstractDFG - foffset = 100000 - fuid = maxfuid >= foffset ? maxfuid : maxfuid+foffset # offset factor values - @warn "using hack counter for FACTOR uid starting at $(fuid)" - # neoNodeId = 63363 - # elem = newvertdict[neoNodeId] - for (neoNodeId,elem) in newvertdict - if elem[:frtend]["t"] == "F" - # @show neoNodeId - if !haskey(elem,:solvable) - # missing solvable field - continue - end - if Int(elem[:solvable]["val"]) != 1 - @warn "solvable/val field not equal to 1" - continue - end - # verts relating to this factor - verts = Vector{Graphs.ExVertex}() - i=0 - for bf in split(elem[:frtend]["btwn"], ' ') - i+=1 - # uid = 0 - uid = parse(Int,bf)+1 - if ((elem[:frtend]["lklh"][1:2] == "BR" || - elem[:frtend]["lklh"] == "rangeBearingMEAS" || - elem[:frtend]["lklh"] == "rangeMEAS" ) && i==2 ) || - ( elem[:frtend]["lklh"] == "PTPR2 G 2 STDEV" && i==1 ) - # detect bearing range factors being added between pose and landmark - @warn "using hack counter for LANDMARKS uid +$(2*foffset)" - uid = parse(Int,bf)+ 2*foffset # complete hack - end - push!(verts, fgl.g.vertices[uid]) - end - # the factor type - usrfnc = !haskey(elem,:mongo_keys) ? recoverConstraintType(fgl.cg, elem[:frtend]) : recoverConstraintType(fgl.cg, elem[:frtend], mongokeys=JSON.parse(elem[:mongo_keys]["val"]) ) - fuid += 1 - vert = addFactor!(fgl, verts, usrfnc, solvable=0, api=localapi, uid=fuid, autoinit=true) - println("at populatenewfactornodes!, btwn="*elem[:frtend]["btwn"]) - mergeValuesIntoCloudVert!(fgl, neoNodeId, elem, fuid, vert, tags=[:FACTOR;Symbol("$(fgl.sessionname)")]) - - # TODO -- upgrade to add multple variables - # for vv in verts - vv = verts[end] - @show vv.label, Base.mean(vv.attributes["data"].val, 2) - dlapi.updatevertex!(fgl, vv, updateMAPest=false) - # end - end - end - nothing -end - - -""" - $(SIGNATURES) - -Convert vertices of session in Neo4j DB with Caesar.jl's required data elements -in preparation for MM-iSAMCloudSolve process. -""" -function updatenewverts!(fgl::G; N::Int=100) where G <: AbstractDFG - sortedvd = getnewvertdict(fgl.cg.neo4j.connection, fgl.sessionname, fgl.robotname, fgl.username) - populatenewvariablenodes!(fgl, sortedvd, N=N) - maxfuid = getmaxfactorid(fgl.cg.neo4j.connection, fgl.sessionname, fgl.robotname, fgl.username) - populatenewfactornodes!(fgl, sortedvd, maxfuid) - nothing -end - - -""" - $(SIGNATURES) - -match (n:\$(session)) -remove n.backendset, n.solvable, n.data, n.bigData, n.label, n.packedType, n.exVertexId, n.shape, n.width -set n :NEWDATA -return n -""" -function resetentireremotesession(conn, session::AbstractString, robot::AbstractString, user::AbstractString; segment::AbstractString="") - loadtx = transaction(conn) - query = segment == "" ? "match (n:$(session):$robot:$user) " : "match (n:$(session):$robot:$user:$(segment)) " - query = query*"where exists(n.frtend) - remove n.backendset, n.solvable, n.data, n.bigData, n.label, n.packedType, n.exVertexId, n.shape, n.width, n.MAP_est - set n :NEWDATA" - cph = loadtx(query, submit=true) - loadresult = commit(loadtx) - nothing -end - - - - - -# diff --git a/src/attic/cloudgraphs/FoveationUtils.jl b/src/attic/cloudgraphs/FoveationUtils.jl deleted file mode 100644 index cfd9ce726..000000000 --- a/src/attic/cloudgraphs/FoveationUtils.jl +++ /dev/null @@ -1,145 +0,0 @@ -# Utils for foveation and spacial querying of the database - -export - whosNear2D, - whosNear3D, - foveateQueryToPoint - - - - """ - $(SIGNATURES) - - Find vertices near the point specified and return dictionary of symbol to Neo4j ID pairs. - """ - function whosNear2D(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString; - x=nothing, - y=nothing, - yaw=nothing, - dist::Float64=3.0, - angle::Float64=pi/12.0 ) - # - if x==nothing && y==nothing && yaw==nothing - error("please give some info on where you want to run the spacial query, xyYaw.") - end - # Build the query - query = "match (n:$(session):$robot:$user) where exists(n.MAP_est) " - query = x==nothing ? query : query*"and abs(n.MAP_est[0] - $(x)) < $(dist) " - query = y==nothing ? query : query*"and abs(n.MAP_est[1] - $(y)) < $(dist) " - query = yaw==nothing ? query : query*"and abs(n.MAP_est[2] - $(yaw)) < $(angle) " - query = query*"return n.label, id(n)" - - cph, = executeQuery(cg, query) - - symneo = Dict{Symbol, Int}() - for data in cph.results[1]["data"] - symneo[Symbol(data["row"][1])] = data["row"][2] - end - # neoid = cph.results[1]["data"][1]["row"][1] - - symneo - end - - """ - $(SIGNATURES) - - Find vertices near the point specified and return dictionary of symbol to Neo4j ID pairs. - """ - function whosNear3D(cg::CloudGraph, session::AbstractString, robot::AbstractString, user::AbstractString; - x=nothing, - y=nothing, - z=nothing, - roll=nothing, - pitch=nothing, - yaw=nothing, - dist::Float64=3.0, - angle::Float64=pi/12.0 ) - # - if x==nothing && y==nothing && z==nothing && roll==nothing && pitch==nothing && yaw==nothing - error("please give some info on where you want to run the spacial query, xyzRPY.") - end - # Build the query - query = "match (n:$(session):$robot:$user) where exists(n.MAP_est) " - query = x==nothing ? query : query*"and abs(n.MAP_est[0] - $(x)) < $(dist) " - query = y==nothing ? query : query*"and abs(n.MAP_est[1] - $(y)) < $(dist) " - query = z==nothing ? query : query*"and abs(n.MAP_est[2] - $(z)) < $(dist) " - query = roll==nothing ? query : query*"and abs(n.MAP_est[3] - $(roll)) < $(angle) " - query = pitch==nothing ? query : query*"and abs(n.MAP_est[4] - $(pitch)) < $(angle) " - query = yaw==nothing ? query : query*"and abs(n.MAP_est[5] - $(yaw)) < $(angle) " - query = query*"return n.label, id(n)" - - cph, = executeQuery(cg, query) - - symneo = Dict{Symbol, Int}() - for data in cph.results[1]["data"] - symneo[Symbol(data["row"][1])] = data["row"][2] - end - - symneo - end - - -""" - $(SIGNATURES) -""" -function foveateQueryToPoint(cg::CloudGraph, - sessions::Vector{T}, - robot::T, - user::T; - point::Vector{Float64}=[0.0;0.0], - minrange::Number=1.5, maxrange::Number=5, fovrad::Number=0.3 ) where {T <: AbstractString} - # - neoids, syms = Vector{Int}(), Vector{Symbol}() - loadtx = transaction(cg.neo4j.connection) - nms = length(sessions) - query = "MATCH (n:$robot:$user) WHERE (" - cnt = 0 - for session in sessions - query *= "(n:$(session):$robot:$user) " - cnt+=1 - if cnt < nms - query *= " or " - else - query *= ") and " - end - end - query *= - "// Region filtering - ($(point[1])-n.MAP_est[0])*($(point[1])-n.MAP_est[0]) + - ($(point[2])-n.MAP_est[1])*($(point[2])-n.MAP_est[1]) > $(minrange^2) - AND - ($(point[1])-n.MAP_est[0])*($(point[1])-n.MAP_est[0]) + - ($(point[2])-n.MAP_est[1])*($(point[2])-n.MAP_est[1]) < $(maxrange^2) - AND - // Frustum cutoff filtering - (abs(atan2( ($(point[2])-n.MAP_est[1]), - ($(point[1])-n.MAP_est[0])) - n.MAP_est[2] ) < $(fovrad) - OR - abs(atan2( ($(point[2])-n.MAP_est[1]), - ($(point[1])-n.MAP_est[0])) - n.MAP_est[2] + 6.28) < $(fovrad) - OR - abs(atan2( ($(point[2])-n.MAP_est[1]), - ($(point[1])-n.MAP_est[0])) - n.MAP_est[2] - 6.28) < $(fovrad)) - RETURN id(n), n.label" - cph, = executeQuery(cg.neo4j.connection, query) - for res in cph.results[1]["data"] - push!(neoids, res["row"][1] ) - push!(syms, Symbol(res["row"][2]) ) - end - return neoids, syms -end - -function foveateQueryToPoint(cg::CloudGraph, - session::AbstractString, - robot::AbstractString, - user::AbstractString; - point::Vector{Float64}=[0.0;0.0], - minrange::Number=1.5, maxrange::Number=5, fovrad::Number=0.3 ) - # - foveateQueryToPoint(cg::CloudGraph, - [session], - robot, - user, - point=point, - minrange=minrange, maxrange=maxrange, fovrad=fovrad ) -end diff --git a/src/attic/cloudgraphs/IterationStatistics.jl b/src/attic/cloudgraphs/IterationStatistics.jl deleted file mode 100644 index 569148e56..000000000 --- a/src/attic/cloudgraphs/IterationStatistics.jl +++ /dev/null @@ -1,16 +0,0 @@ -using Dates - -export IterationStatistics - -""" -A simple structure containing performance stats from the iteration. -""" -mutable struct IterationStatistics - startTimestamp::DateTime - endTimestamp::DateTime - numNodes::Int - result::String - additionalInfo::Dict{String, String} - IterationStatistics(startTimestamp, endTimestamp, numNodes, result, additionalInfo::Dict{String, String} = Dict{String, String}()) = new(startTimestamp, endTimestamp, numNodes, result, additionalInfo) - IterationStatistics() = new(Dates.now(), Dates.now(), 0, "N/A") -end diff --git a/src/attic/cloudgraphs/MultisessionUtils.jl b/src/attic/cloudgraphs/MultisessionUtils.jl deleted file mode 100644 index 4aff59151..000000000 --- a/src/attic/cloudgraphs/MultisessionUtils.jl +++ /dev/null @@ -1,253 +0,0 @@ -# multisession support for Caesar.jl - - - -function multisessionquery(conn, session::T, robot::T, user::T, multisessions::Vector{T}) where {T <: AbstractString} - len = length(multisessions) - loadtx = transaction(conn) - # construct the query - query = "match (m:$(session):$robot:$user:LANDMARK) "* - "with m.label as mlb "* - "order by mlb asc "* - "match (n:LANDMARK) "* - "where n.label = mlb "* - "and ("; - for i in 1:len - ots = multisessions[i] - query = query*"n:$(ots) " - query = i < len ? query*"or " : query - end - query = query*") "* - "with distinct n.label as lbl, collect(id(n)) as others, collect(labels(n)) as nlb "* - "return lbl, others, nlb"; - - loadtx(query, submit=true) -end - -# multisession must have session label starting with SESS* in each query response line -function parsemultisessionqueryresult!(lm2others::Dict{Symbol, Dict{Symbol, Int}}, cph) - i = 0 - # @show cph.results[1]["data"] - for i in 1:length(cph.results[1]["data"]) - res = cph.results[1]["data"][i]["row"] - for j in 1:length(res[2]) - sess = "" - for lb in res[3][j] - if lb[1:4] == "SESS" - sess = Symbol(lb) - end - end - if !haskey(lm2others, sess) lm2others[sess] = Dict{Symbol, Int}() end - lm2others[sess][Symbol(res[1])] = res[2][j] - end - end - nothing -end - -""" - getLandmOtherSessNeoIDs{T <: AbstractString}(::CloudGraph, session::T="", robot::T="", user::T="", multisessions=Vector{T}()) - -Return dict of dict of Neo4j vertex IDs by session and landmark symbols. -""" -function getLandmOtherSessNeoIDs(cg::CloudGraph; - session::T="", - robot::T="", - user::T="", - multisessions::Vector{T}=String[] ) where {T <: AbstractString} - # - lm2others = Dict{Symbol, Dict{Symbol, Int}}() - - len = length(multisessions) - len > 0 ? nothing : (return lm2others) - - if length(multisessions)==0 - cph = multisessionquery(cg.neo4j.connection, session, robot, user, multisessions) - parsemultisessionqueryresult!(lm2others, cph) - else - info("Ignoring multisession") - end - - return lm2others -end - - -""" - getprp2kde(::CloudGraph, neoids::Vector{Int}; N::Int=100) - -Return PriorPoint2DensityNH with N points based on beliefs of neoids, and equal -share null hypothesis between length(neoids)+1 beliefs. -""" -function getprpt2kde(cloudGraph::CloudGraph, neoids::Vector{Int}; N::Int=100 ) - # - # P = BallTreeDensity[] - PTS = Array{Float64,2}() - for fielem in neoids # lm2others[lm] - cv = CloudGraphs.get_vertex(cloudGraph, fielem) - vert = cloudVertex2ExVertex(cv) - pts = getVal(vert) - PTS = size(PTS,2) == 0 ? pts' : [PTS; pts'] - # push!(P, kde!(pts)) - end - PTS = PTS'; - - l = collect(1:size(PTS,2)) - shuffle!(l) - - # TODO -- not up sampling if N is bigger than size(PTS) - ptsN = PTS[:,l[1:N]]; - @show size(ptsN) - - nh = 1.0/(length(neoids)+1.0) - ph = Float64[nh;1.0-nh] - return PriorPoint2DensityNH(kde!(ptsN), ph) -end - - -""" - $(SIGNATURES) - -Return Vector{Int} of Neo4j vertex IDs relating to symbol, as listed in lm2others. -""" -function getAllLandmarkNeoIDs(lm2others::Dict{Symbol, Dict{Symbol,Int}}, slm::Symbol) - mslmneoids = Int[] - for (sess, vals) in lm2others - if haskey(vals, slm) - push!(mslmneoids, vals[slm]) - end - end - return mslmneoids -end - - -""" - $(SIGNATURES) - -Return subgraph copy of type FactorGraph contaning values from session in lm2others, and Vector{Symbol} of primary -key symbols used for graph exstraction. -""" -function getLocalSubGraphMultisession(cg::CloudGraph, - lm2others; - session::T="", - robot::T="", - user::T="", - numneighbors::Int=0 ) where {T <: AbstractString} - # - res = Dict{Symbol, Int}() - sfg = initfg(sessionname=session, robotname=robot, username=user, cloudgraph=cg) - if length(lm2others) > 0 - for (sess,ms) in lm2others - for (sym, neoid) in ms - res[sym] = 0 - end - end - getVertNeoIDs!(cg, res, session=session, robot=robot, user=user) - fullcurrneolist = collect(values(res)) - fetchsubgraph!(sfg, fullcurrneolist, numneighbors=numneighbors) # can set numneighbors=0 - end - return sfg, collect(keys(res)) -end - - -""" - $(SIGNATURES) - -Return Dict{Symbol, Int} of vertex symbol to Neo4j node ID of MULTISESSION constraints in this `fgl.sessionname`. -""" -function findExistingMSConstraints(fgl::G) where G <: AbstractDFG - query = "match (n:$(fgl.sessionname):$(fgl.robotname):$(fgl.username):MULTISESSION) - return id(n), n.exVertexId, n.label" - cph, = executeQuery(cg, query) - # parse the response into a dictionary - existingms = Dict{Symbol, Int}() # symlbl => neoid - for res in cph.results[1]["data"] - neoid, exvid, lbl = res["row"][1], res["row"][2], res["row"][3] - existingms[Symbol(lbl)] = neoid - end - - return existingms -end - - -""" - $SIGNATURES - -Return new multisession factor, symbol sym, inserted using prp2::PriorPoint2DensityNH using user ExVertex id (uid), -after checking existing multisession dict (exims::(exvsym=>neoid)) if any nodes should be removed before inserting new ones -on that graph node. Assuming just one multisession prior per node. -""" -function removeReinsertMultisessionPrior!(fgl::G, - exims::Dict{Symbol, Int}, - prp2::T, - sym::Symbol, - uid::Int ) where {G <: AbstractDFG, T <: AbstractPrior} - # - # remove previous Multi session constraint on this sym vertex - if haskey(exims, sym) - info("Removing previous multisession neoid=$(exims[sym]) on sym=$(sym).") - removeNeo4jID(fgl.cg, neoid=exims[sym]) - delete!(exims, sym) - end - # add new multisession constraint to the graph - addFactor!(fgl, [sym], prp2, tags=[:MULTISESSION;], uid=uid) -end - - -""" - rmInstMultisessionPriors!(::CloudGraph; session<:AbstractString=, multisessions::Vector{<:AbstractString}= ) -""" -function rmInstMultisessionPriors!(cloudGraph::CloudGraph; - session::T="NA", - robot::T="NA", - user::T="NA", - multisessions::Vector{T}=String[] ) where {T <: AbstractString} - # - session!="NA" ? nothing : error("Please specify a valid session, currently = $(session)") - robot!="NA" ? nothing : error("Please specify a valid robot, currently = $(robot)") - user!="NA" ? nothing : error("Please specify a valid user, currently = $(user)") - - multisessionsl = Vector{String}(setdiff(multisessions, [session])) - length(multisessionsl) > 0 ? nothing : (return nothing) - # get the landmarks of interest from neighboring sessions - lm2others = getLandmOtherSessNeoIDs(cloudGraph, - session=session, robot=robot, user=user, multisessions=multisessionsl) - # - - # grab local subgraph using NeoIDs - sfg, lms = getLocalSubGraphMultisession(cloudGraph, lm2others, - session=session, robot=robot, user=user,numneighbors=1) - # - - # get dict(sym => neoid) of exiting multisession constraints which may be removed during this update - exims = findExistingMSConstraints(sfg) - # get highest factor exvid - mfn4jid = getmaxfactorid(cloudGraph.neo4j.connection, session, robot, user) - - println("Multisession constraints in $(session), from $(multisessionsl), on $(lms)") - for sym in lms - neoids = getAllLandmarkNeoIDs(lm2others, sym) - prp2 = getprpt2kde(cloudGraph, neoids, N=100 ) - mfn4jid += 1 - factorms = removeReinsertMultisessionPrior!(sfg, exims, prp2, sym, mfn4jid) - end - nothing -end - - -function removeMultisessions!(cloudGraph::CloudGraph; session::AbstractString="NA", robot::AbstractString="NA", user::AbstractString="NA") - session!="NA" ? nothing : error("Please specify a valid session, currently = $(session)") - robot!="NA" ? nothing : error("Please specify a valid robot, currently = $(robot)") - user!="NA" ? nothing : error("Please specify a valid user, currently = $(user)") - - loadtx = transaction(cloudGraph.neo4j.connection) - query = "match (n:$(session):$robot:$user:MULTISESSION) - detach delete n - return count(n)" - cph = loadtx(query, submit=true) - commit(loadtx) - return cph -end - - - - -# diff --git a/src/attic/cloudgraphs/SolverStatus.jl b/src/attic/cloudgraphs/SolverStatus.jl deleted file mode 100644 index a74bd46c5..000000000 --- a/src/attic/cloudgraphs/SolverStatus.jl +++ /dev/null @@ -1,26 +0,0 @@ -using Dates -using UUIDs - -export SolverStatus - -""" -A simple structure for monitoring a running solver. -""" -mutable struct SolverStatus - id::String - host::String - isAttached::Bool - userId::String - robotId::String - sessionId::String - iteration::Int64 - currentStep::String - startedUpTimestamp::String - attachedSessionTimestamp::String - detachedSessionTimestamp::String - lastUpdatedTimestamp::String - lastIterationDurationSeconds::Float64 - result::String - SolverStatus() = new(string(uuid4()), "", false, "", "", "", 0, "", string(unix2datetime(time())), "", "", "", 0, "") - SolverStatus(id::String, host::String, isAttached::Bool, userId::String, robotId::String, sessionId::String, iteration::Int64, currentStep::String, startedUpTimestamp::String, attachedSessionTimestamp::String, detachedSessionTimestamp::String, lastUpdatedTimestamp::String, lastIterationDurationSeconds::Float64, result::String) = new(id, host, isAttached, userId, robotId, sessionId, iteration, currentStep, startedUpTimestamp, attachedSessionTimestamp, detachedSessionTimestamp, lastUpdatedTimestamp, lastIterationDurationSeconds, result) -end diff --git a/src/attic/cloudgraphs/slamindb.jl b/src/attic/cloudgraphs/slamindb.jl deleted file mode 100644 index 87ff18daf..000000000 --- a/src/attic/cloudgraphs/slamindb.jl +++ /dev/null @@ -1,276 +0,0 @@ -# SLAMinDB service functions -using Dates - -function getcredentials(;nparticles=true, drawdepth=true, multisession=false, drawedges=true) - cloudGraph, addrdict = standardcloudgraphsetup(nparticles=nparticles, drawdepth=drawdepth, drawedges=drawedges, multisession=multisession) - return addrdict -end - -function slamindbsavejld(fgl::G, session::AbstractString, itercount::Int) where G <: AbstractDFG - dt = Base.Dates.now() - filenamejld = "$(session)_$(Dates.format(dt, "dduyy-HH:MM:SS"))_slamindb_$(itercount).jld" - println("------Save fg to file: $(filenamejld)------") - savejld(fgl,file=filenamejld) - nothing -end - -""" - $(SIGNATURES) - -Runs SlamInDb for given number of iterations against a specific session. -""" -function runSlamInDbOnSession( - caesarConfig::CaesarConfig, - cloudGraph::CloudGraph, - userId::String, - robotId::String, - sessionId::String, - iterations::Int64, - isRecursiveSolver::Bool, - solverStatus::SolverStatus, - iterationCompleteCallback)::Nothing - # - N = caesarConfig.numParticles - - # TODO: Constants to refactor - drawbayestree = false - - # Update the status parameters - solverStatus.isAttached = true - solverStatus.attachedSessionTimestamp = string(unix2datetime(time())) - solverStatus.userId = userId - solverStatus.robotId = robotId - solverStatus.sessionId = sessionId - solverStatus.result = "IN PROGRESS" - - itercount = 0 - while ((iterations > 0 || iterations == -1) && solverStatus.isAttached) - iterationStats = IterationStatistics() - try - iterations = iterations == -1 ? iterations : iterations-1 # stop at 0 or continue indefinitely if -1 - - startns = time_ns() - solverStatus.iteration = itercount - - println("===================CONVERT===================") - solverStatus.currentStep = "Prep_Convert" - fg = initfg(sessionname=sessionId, robotname=robotId, username=userId, cloudgraph=cloudGraph) - updatenewverts!(fg, N=N) - println() - - println("=============ENSURE INITIALIZED==============") - solverStatus.currentStep = "Prep_EnsureInitialized" - initAll!(fg) - println() - - println("================MULTI-SESSION================") - solverStatus.currentStep = "Prep_MultiSession" - rmInstMultisessionPriors!(cloudGraph, session=sessionId, robot=robotId, user=userId, multisessions=caesarConfig.multiSession) - println() - - println("====================SOLVE====================") - solverStatus.currentStep = "Init_Solve" - fg = initfg(sessionname=sessionId, robotname=robotId, username=userId, cloudgraph=cloudGraph) - - setBackendWorkingSet!(cloudGraph.neo4j.connection, sessionId, robotId, userId) - - println("Get local copy of graph") - - solverStatus.currentStep = "Init_LocalGraphCopy" - if fullLocalGraphCopy!(fg) - iterationStats.numNodes = length(fg.IDs) + length(fg.fIDs) #Variables and factors - # (savejlds && itercount == 0) ? slamindbsavejld(fg, sessionId, itercount) : nothing - itercount += 1 - - println("-------------Ensure Initialization-----------") - solverStatus.currentStep = "Solve_EnsureInitialized" - initAll!(fg) - - println("------------Bayes (Junction) Tree------------") - solverStatus.currentStep = "Solve_BuildBayesTree" - tree = wipeBuildNewTree!(fg,drawpdf=drawbayestree) - - solverStatus.currentStep = "Solve_InferOverTree" - if !isRecursiveSolver - inferOverTree!(fg, tree, N=N) - else - inferOverTreeR!(fg, tree, N=N) - end - - else - sleep(0.2) - end - - # Notify iteration update. - solverStatus.lastIterationDurationSeconds = (time_ns() - startns) / 1e9 - solverStatus.currentStep = "Idle" - iterationStats.result = "GOOD" - solverStatus.result = "GOOD" - catch ex - io = IOBuffer() - showerror(io, ex, catch_backtrace()) - err = String(take!(io)) - msg = "ERROR\r\n$err" - iterationStats.result = msg - solverStatus.result = msg - finally - iterationStats.endTimestamp = Dates.now() - iterationCompleteCallback(iterationStats) - end - end - - solverStatus.isAttached = false - solverStatus.detachedSessionTimestamp = string(unix2datetime(time())) - solverStatus.userId = "" - solverStatus.robotId = "" - solverStatus.sessionId = "" - return nothing -end - -""" - $(SIGNATURES) - -Low-level call to iterate the SlamInDb solver for given number of iterations against a specific session and keyword parameters. -""" -function runDbSolver(cloudGraph::CloudGraphs.CloudGraph, - robotId::A, - sessionId::A, - userId::A; - N::Int=100, - loopctrl::Vector{Bool}=Bool[true], - iterations::Int=-1, - multisession::Vector{A}=Sting[""], - savejlds::Bool=false, - recursivesolver::Bool=false, - drawbayestree::Bool=false ) where {A <: AbstractString} - - itercount = 0 - while loopctrl[1] && (iterations > 0 || iterations == -1) # loopctrl for future use - iterations = iterations == -1 ? iterations : iterations-1 # stop at 0 or continue indefinitely if -1 - println("===================CONVERT===================") - fgl = initfg(sessionname=sessionId, robotname=robotId, username=userId, cloudgraph=cloudGraph) - updatenewverts!(fgl, N=N) - println() - - println("=============ENSURE INITIALIZED==============") - initAll!(fgl) - println() - - println("================MULTI-SESSION================") - rmInstMultisessionPriors!(cloudGraph, session=sessionId, robot=robotId, user=userId, multisessions=multisession) - println() - - println("====================SOLVE====================") - fgl = initfg(sessionname=sessionId, robotname=robotId, username=userId, cloudgraph=cloudGraph) - - setBackendWorkingSet!(cloudGraph.neo4j.connection, sessionId, robotId, userId) - - println("get local copy of graph") - - if fullLocalGraphCopy!(fgl) - (savejlds && itercount == 0) ? slamindbsavejld(fgl, sessionName, itercount) : nothing - itercount += 1 - - println("-------------Ensure Initialization-----------") - initAll!(fgl) - - println("------------Bayes (Junction) Tree------------") - tree = wipeBuildNewTree!(fgl,drawpdf=drawbayestree) - if !recursivesolver - inferOverTree!(fgl, tree, N=N) - else - inferOverTreeR!(fgl, tree, N=N) - end - savejlds ? slamindbsavejld(fgl, sessionName, itercount) : nothing - else - sleep(0.2) - end - end -end - -""" -Manually call the SLAMinDB solver to perform inference on a specified session given the keyword parameter settings. -""" -function slamindb(;addrdict=nothing, - N::Int=-1, - loopctrl::Vector{Bool}=Bool[true], - iterations::Int=-1, - multisession::Bool=false, - savejlds::Bool=false, - recursivesolver::Bool=false, - drawbayestree::Bool=false ) - - - nparticles = false - if N > 0 - addrdict["num particles"] = string(N) - else - nparticles = true - end - - cloudGraph, addrdict = standardcloudgraphsetup(addrdict=addrdict, - nparticles=nparticles, multisession=multisession) - - N = parse(Int, addrdict["num particles"]) - session = addrdict["session"] - robot = addrdict["robot"] - user = addrdict["user"] - - if !haskey(addrdict, "multisession") - addrdict["multisession"]=String[] - end - - runDbSolver(cloudGraph, - addrdict["robotId"], - session, - N=N, - loopctrl=loopctrl, - iterations=iterations, - multisession=addrdict["multisession"], - savejlds=savejlds, - recursivesolver=recursivesolver, - drawbayestree=drawbayestree) - nothing -end - -function convertdb(;addrdict=nothing, - N::Int=-1 ) - # - nparticles = false - if N > 0 - addrdict["num particles"] = string(N) - else - nparticles = true - end - cloudGraph, addrdict = standardcloudgraphsetup(addrdict=addrdict, nparticles=nparticles) - N = parse(Int, addrdict["num particles"]) - fg = initfg(sessionname=addrdict["session"], cloudgraph=cloudGraph) - updatenewverts!(fg, N=N) -end - -function resetconvertdb(;addrdict=nothing) - cloudGraph, addrdict = standardcloudgraphsetup(addrdict=addrdict) - println("Clearing slamindb data, leaving front-end data, session: $(addrdict["session"])") - resetentireremotesession(cloudGraph.neo4j.connection, addrdict["session"]) -end - - - - - - - - - - - - - - - - - - - - -# diff --git a/src/attic/multisession/Multisession.jl b/src/attic/multisession/Multisession.jl deleted file mode 100644 index 6e6d415c9..000000000 --- a/src/attic/multisession/Multisession.jl +++ /dev/null @@ -1,312 +0,0 @@ -module Multisession - -using DocStringExtensions -using Combinatorics -using Caesar -using Neo4j, CloudGraphs - -export - getSessionsForEnvironment, - getEnvironmentPrimeLandmarkNodes, - getSessionLandmarks, - getFederatedGraphElements, - buildPrimeLandmarksAndFactors, - getMultiSessionFg, - updateLandmarkProducts - -""" - $(SIGNATURES) - -Return all binary pair combinations of sessions and return a Vector::Tuple{String, String}. - -Example -------- -```julia -str = ["a";"b";"c";"d"] -pstr = stringPairs(str) -@assert length(pstr) == 6 -``` -""" -function stringPairs(strs::Vector{<:AbstractString} )::Vector{Tuple{String, String}} - ret = Tuple{String,String}[] - for co in combinations( strs ) - if length(co) == 2 - push!(ret, (co[1], co[2])) - end - end - return ret -end - -""" - $(SIGNATURES) - -Gets a vector of session IDs that are related to an environment. -""" -function getSessionsForEnvironment( - connection::Neo4j.Connection, - environment::String)::Vector{String} - query = "match (env:ENVIRONMENT:$environment)-[SESSION]->(s:SESSION) return s.id" - cph, = Caesar.executeQuery(connection, query) - return map(s -> s["row"][1], cph.results[1]["data"]) -end - -""" - $(SIGNATURES) - -Get a dictionary (label => Neo4j node) of all prime nodes for a given set of sessions and an environment. -""" -function getEnvironmentPrimeLandmarkNodes(cloudGraph::CloudGraph, sessions::Vector{String}, environment::String)::Dict{String, Neo4j.Node} - # TODO - refactor prime labels as a special snowflake - m or something like `:m14` is better -- still need to test and upgrade IIF for this - query = "match (node:MULTISESSION:LANDMARK) where ("*join("(node:".*sessions.*")", " or ")*") and node.environment = \"$environment\" return id(node)" - cph, = Caesar.executeQuery(cloudGraph.neo4j.connection, query) - existPrimeNodes = map(node -> getnode(cloudGraph.neo4j.graph, node["row"][1]), cph.results[1]["data"]) - labels = map(n -> getnodeproperty(n, "label"), existPrimeNodes) - # Dictionary of all existing prime nodes... - existPrimeNodes = Dict(labels .=> existPrimeNodes) - return existPrimeNodes -end - -""" - $(SIGNATURES) - -Gets all landmark IDs for a given session, excluding multisession. -""" -# TODO: This should be a generic function... -function getSessionLandmarks( - conn::Neo4j.Connection, - sessionId::String, - robotId::String, - userId::String)::Vector{String} - query = "match (landmark:$sessionId:$robotId:$userId:LANDMARK) where NOT landmark:MULTISESSION return landmark.label" - cph, = Caesar.executeQuery(conn, query) - return map(s -> s["row"][1], cph.results[1]["data"]) -end - -""" - $(SIGNATURES) - -Very specific method to check if a prime factor exists between a session landmark and a prime node. -Prime node is identified by NeoNode ID. -""" -function _doesPrimeFactorExistByForSessionLandmark( - conn::Neo4j.Connection, - sessionId::String, - robotId::String, - userId::String, - primeLandmarkNeoNodeId::Int)::Bool - query = "match (node:LANDMARK:$sessionId:$robotId:$userId)-[:DEPENDENCE]-(f:FACTOR)-[:DEPENDENCE]-(m:MULTISESSION) where id(m)=$(primeLandmarkNeoNodeId) return id(node)" - cph, = Caesar.executeQuery(conn, query) - return length(cph.results[1]["data"]) > 0 # If it exists return true. -end - -""" - $(SIGNATURES) - -Returns the tuples of the prime landmark -> prime factor -> session landmark for all existing prime factors. -Tuple elements: mid, mlabel, fid, flabel, lid, llabel -May contain duplicates elements (e.g. two prime factors for one prime landmark). -""" -function getFederatedGraphElements( - connection::Neo4j.Connection, - sessions::Vector{String}, - environment::String)::Vector{Tuple} - query = "match (m:LANDMARK:MULTISESSION)--(f:FACTOR:MULTISESSION)--(l:LANDMARK) where "*(prod("m:".*sessions.*" or ")[1:(end-4)])*" and m.environment=\"$environment\" return id(m), m.label, id(f), f.label, id(l), l.label" - cph, = Caesar.executeQuery(connection, query) - - elements = Vector{Tuple}() - for data in cph.results[1]["data"] - #Tuple elements: mid, mlabel, fid, flabel, lid, llabel - push!(elements, (data["row"][1], Symbol(data["row"][2]), data["row"][3], Symbol(data["row"][4]), data["row"][5], Symbol(data["row"][6]))) - end - return elements -end - -""" - $(SIGNATURES) - -McFlurry step. -Builds the prime landmarks and prime factors for a given environment and sessions (if they don't exist). -Returns all prime landmarks. -""" -function buildPrimeLandmarksAndFactors( - cloudGraph::CloudGraph, - sessionLandmarks::Dict{String, Vector{String}}, - robotId::String, - userId::String, - environment::String)::Dict{String, Neo4j.Node} - @debug " - Checking and updating each combination of sessions for same landmarks..." - sessions = collect(keys(sessionLandmarks)) - sessionPairs = stringPairs(sessions) - primeLandmarkNodes = getEnvironmentPrimeLandmarkNodes(cloudGraph, sessions, environment) - for (s1,s2) in sessionPairs - @info " - Creating landmark links between '$s1' and '$s2'" - # TODO: Find a better way to for landmark equivalence check - # TODO: Check that the landmarks are the same type - commonLandmarks = intersect(sessionLandmarks[s1], sessionLandmarks[s2]) - @info " - Common landmark set: $commonLandmarks" - - for commonLandmark in commonLandmarks - @info " - Checking common landmark $commonLandmark..." - # Make the prime variable if it doesn't exist - sym = Symbol("l"*string(parse(Int, commonLandmark[2:end])+100000)) - if !haskey(primeLandmarkNodes, String(sym)) - # TODO: be generic about which variables and factor types to use - # Make a prime and add to db+list - @info " - Adding a prime landmark variable $sym..." - fg = initfg(cloudgraph=cloudGraph, robotname=robotId, username=userId, sessionname=s1) - - # Check the softtypes to make sure they match. - # TODO: FRACK GETTING AGAIN... YEESH - land1 = Caesar.getCloudVert(cloudGraph, s1, robotId, userId, sym=Symbol(commonLandmark)) - land2 = Caesar.getCloudVert(cloudGraph, s2, robotId, userId, sym=Symbol(commonLandmark)) - if typeof(land1.packed.softtype) != typeof(land2.packed.softtype) - @error "Softtypes don't match for $s1:$sym (got $(typeof(land1.packed.softtype))) and $s2:$sym (got $(typeof(land2.packed.softtype)))" - continue - end - addVariable!(fg, sym, deepcopy(land1.packed.softtype), tags=[:MULTISESSION; :LANDMARK; Symbol(s1); Symbol(s2); Symbol(userId); Symbol(robotId)], uid=100000) - # NOTE: Until DFG, all prime variables have exVertexId of 100000 - # Add the environment property - setnodeproperty(getnode(cloudGraph.neo4j.graph, fg.cgIDs[100000]), "environment", environment) - @debug " - Added prime landmark!" - # primeLandmarkNodes[string(sym)] = primeLandmarkNodes - # Repull the existing prime nodes! - primeLandmarkNodes = getEnvironmentPrimeLandmarkNodes(cloudGraph, sessions, environment) - else - @info " - Prime landmark $sym already exists, making sure it has all the labels!" - addnodelabels(primeLandmarkNodes[String(sym)], [s1, s2]) - end - - # check if factor already exists - prime = primeLandmarkNodes[string(sym)] - for s in [s1, s2] - if !_doesPrimeFactorExistByForSessionLandmark(cloudGraph.neo4j.connection, s, robotId, userId, prime.id) - @info " - Adding a factor between session landmark '$commonLandmark' and prime landmark '$sym' for session $s..." - # add new factor that between session landmark and prime landmark - fg = initfg(cloudgraph=cloudGraph, robotname=robotId, username=userId, sessionname=s) - syms = [Symbol(commonLandmark);sym] - @debug " - Copying local symbols $syms..." - Caesar.subLocalGraphCopy!(fg, syms, neighbors=0, reqbackendset=false, reqSolvable=false, includeMultisession=true) - - # Note: this shouldn't be necessary because the check is done in the landmark creation, but doing just in case here too. - @show sessionLandType = getData(getVert(fg, syms[1], api=localapi)).softtype - @show primeLandType = getData(getVert(fg, syms[2], api=localapi)).softtype - if typeof(sessionLandType) != typeof(primeLandType) - @error "Softtypes don't match for $syms (got $(typeof(sessionLandType))) and (got $(typeof(primeLandType)))" - continue - end - newFactorType = string(typeof(sessionLandType).name)*string(typeof(primeLandType).name) - - @debug " - Trying to create a factor linking $syms of type $newFactorType ..." - # How do i create a Point2Point2 or Pose2Pose2 generically. - newPrimeFactor = Point2Point2(MvNormal(zeros(2), 1e-4*Matrix(LinearAlgebra.I, 2,2) )) - @warn "Currently would like a factor of type $newFactorType, but hard-coded to create Point2Point2's. Please fix in FederatedSolving.jl!" - addFactor!(fg, syms, newPrimeFactor, uid=100001, tags=[:FACTOR; :MULTISESSION; Symbol(userId); Symbol(robotId); Symbol(s)], autoinit=false) - # NOTE: Until DFG, all prime variables have exVertexId of 100000 - # Add the environment property - setnodeproperty(getnode(cloudGraph.neo4j.graph, fg.cgIDs[100001]), "environment", environment) - else - @debug " - Factor link already exists, continuing..." - end - end - end - end - return primeLandmarkNodes -end - -""" - $(SIGNATURES) - -Create a Caesar FactorGraph that contains all landmarks and factors in a multisession -federated solve. -""" -function getMultiSessionFg( - cloudGraph::CloudGraph, - sessions::Vector{String}, - environment::String) -# # - fg = initfg(cloudgraph=cloudGraph) - - # 1. Get all federated elements - Vector of tuples (mid, mlabel, fid, flabel, lid, llabel) - federatedGraphElements = getFederatedGraphElements(cloudGraph.neo4j.connection, sessions, environment) - - localIndex = 1 - for (mid, mlabel, fid, flabel, lid, llabel) in federatedGraphElements - - # make the local index unique - origlabel = llabel - llabel = Symbol(string(llabel, "_", localIndex)) - # If prime landmark not in FG, add it - if !(mid in values(fg.IDs)) - mvert = CloudGraphs.get_vertex(fg.cg, mid, false) - addVariable!(fg, mlabel, mvert.packed.softtype, api=IIF.localapi, uid=mid) - getVert(fg, mlabel, api=localapi).attributes["origlabel"] = mlabel - # Manually add the cloud node IDs - push!(fg.cgIDs, mvert.neo4jNodeId => mvert.neo4jNodeId) - end - # If session landmark not in FG, add it - if !(lid in values(fg.IDs)) - lvert = CloudGraphs.get_vertex(fg.cg, lid, false) - addVariable!(fg, llabel, lvert.packed.softtype, api=IIF.localapi, uid=lid) - getVert(fg, llabel, api=localapi).attributes["origlabel"] = origlabel - Caesar.setValKDE!(fg, llabel, kde!(lvert.packed.val), api=IIF.localapi) - # Manually add the cloud node IDs - push!(fg.cgIDs, lvert.neo4jNodeId => lvert.neo4jNodeId) - # Keep local label index unique - localIndex += 1 - end - # If prime factor (l1 prime -- l1 session) not in FG, add it - if !(fid in values(fg.fIDs)) - vm = fg.g.vertices[mid] - vl = fg.g.vertices[lid] - fvert = CloudGraphs.get_vertex(fg.cg, fid, false) - addFactor!(fg, [llabel; mlabel], fvert.packed.fnc.usrfnc!, api=IIF.localapi, uid=fid, autoinit=false) - end - end - return fg -end - -""" -$(SIGNATURES) - -Updates the specified list of landmarks using local products. -Returns a symbol dictionary of the provided landmarks and a tuple of (new KDE, KDE propsals), -which is useful for plotting with plotKDE. -""" -function updateLandmarkProducts( - fg::G, - landmarkSymbols::Vector{Symbol}, - shouldFreeze::Bool)::Dict{Symbol, Tuple{BallTreeDensity, Vector{BallTreeDensity}}} where G <: AbstractDFG - retDict = Dict{Symbol, Tuple{BallTreeDensity, Vector{BallTreeDensity}}}() - for landmarkSymbol in landmarkSymbols - @debug "Calculating local product for $landmarkSymbol..." - - # Update calculate the local product and persist it - newkde, kdeproposals = IIF.localProduct(fg, landmarkSymbol, api=IIF.localapi) - - # SetValKDE does not do what we need here - do by hand... - # Get local, update cloud. - vert = getVert(fg, landmarkSymbol, api=IIF.localapi) - data = getData(vert) - data.val = getPoints(newkde) - if shouldFreeze - @debug "Freezing $landmarkSymbol..." - # Freeze the landmark (TODO: May be overcooked, possibly refactore) - data.ismargin = true - end - vert.attributes["label"] = vert.attributes["origlabel"] - setData!(vert, data) - - @debug "Updating $landmarkSymbol on server..." - # Fix the label before writing back - dlapi.updatevertex!(fg, vert) - #setValKde is not right call :/ - # setValKDE!(fg, landmarkSymbol, newkde, api=IIF.dlapi) - - push!(retDict, landmarkSymbol=>(newkde, kdeproposals)) - end - return retDict -end - -return nothing - -end From f997af0fc72a3c052d937790ab50894e466fd797 Mon Sep 17 00:00:00 2001 From: dehann Date: Tue, 27 Sep 2022 20:28:47 -0700 Subject: [PATCH 5/5] rm legacy CaesarConfig --- {src/config => examples/visualization}/CaesarConfig.jl | 0 src/Caesar.jl | 3 --- 2 files changed, 3 deletions(-) rename {src/config => examples/visualization}/CaesarConfig.jl (100%) diff --git a/src/config/CaesarConfig.jl b/examples/visualization/CaesarConfig.jl similarity index 100% rename from src/config/CaesarConfig.jl rename to examples/visualization/CaesarConfig.jl diff --git a/src/Caesar.jl b/src/Caesar.jl index 8554bd3d8..c751e752a 100644 --- a/src/Caesar.jl +++ b/src/Caesar.jl @@ -65,9 +65,6 @@ include("transforms/services/_FastTransform3D.jl") include("services/DataUtils.jl") include("services/UserFunctions.jl") -# Configuration -include("config/CaesarConfig.jl") - include("Deprecated.jl") # SAS-SLAM