From 8e781f60c5924b72ce70826e5ff32c8b05cd03f2 Mon Sep 17 00:00:00 2001 From: Will Forker Date: Thu, 5 Oct 2023 12:33:11 -0700 Subject: [PATCH 1/4] add websockets to vcd --- src/vcd/main.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vcd/main.py b/src/vcd/main.py index ddd01ae..899c7fe 100644 --- a/src/vcd/main.py +++ b/src/vcd/main.py @@ -34,6 +34,8 @@ class VcdRunConfig: TRUST_LABELS: bool = False COMPUTE_HAG: bool = False LOG_TYPE: str = "rich" + WEBSOCKET_URL: str = "127.0.0.1:8889" + def __post_init__(self) -> None: # set output directory @@ -178,6 +180,12 @@ def get_args() -> argparse.Namespace: default=VcdRunConfig.LOG_TYPE, help="Specify how to log codem output, options include websocket, rich or console", ) + ap.add_argument( + "--websocket-url", + type=str, + default=VcdRunConfig.WEBSOCKET_URL, + help="Url to websocket receiver to connect to" + ) return ap.parse_args() @@ -234,12 +242,14 @@ def run_no_console(config: VCDParameters) -> None: from codem.lib.progress import WebSocketProgress logger = config["log"].logger - for key, value in config.items(): - logger.info(f"{key} = {value}") + with WebSocketProgress(config["WEBSOCKET_URL"]) as progress: change_detection = progress.add_task("Vertical Change Detection...", total=100) - + + for key, value in config.items(): + logger.info(f"{key} = {value}") + before = PointCloud(config, "BEFORE") progress.advance(change_detection, 14) From a494b71501f4c3982c23dacc7bbd51922e2b4ca8 Mon Sep 17 00:00:00 2001 From: Ogi Moore Date: Thu, 5 Oct 2023 13:20:59 -0700 Subject: [PATCH 2/4] websocket not websocketS, use python -m vcd not vcd --- src/codem/__main__.py | 3 +++ src/vcd/__main__.py | 3 +++ src/vcd/main.py | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 src/codem/__main__.py create mode 100644 src/vcd/__main__.py diff --git a/src/codem/__main__.py b/src/codem/__main__.py new file mode 100644 index 0000000..7186d05 --- /dev/null +++ b/src/codem/__main__.py @@ -0,0 +1,3 @@ +from .main import main + +main() \ No newline at end of file diff --git a/src/vcd/__main__.py b/src/vcd/__main__.py new file mode 100644 index 0000000..7186d05 --- /dev/null +++ b/src/vcd/__main__.py @@ -0,0 +1,3 @@ +from .main import main + +main() \ No newline at end of file diff --git a/src/vcd/main.py b/src/vcd/main.py index 899c7fe..0d89b97 100644 --- a/src/vcd/main.py +++ b/src/vcd/main.py @@ -352,7 +352,7 @@ def main() -> None: config = create_config(args) if config["LOG_TYPE"] == "rich": run_rich_console(config) - elif config["LOG_TYPE"] == "websockets": + elif config["LOG_TYPE"] == "websocket": run_no_console(config) else: run_stdout_console(config) # type: ignore From 778bd8120f9376f53e878bae6743f1f067effd03 Mon Sep 17 00:00:00 2001 From: Ogi Moore Date: Thu, 2 Nov 2023 12:39:08 -0700 Subject: [PATCH 3/4] Use hyphens instead of lower-case, support custom websocket URL --- src/codem/lib/log.py | 6 +++++- src/codem/lib/progress.py | 6 +++++- src/codem/main.py | 33 +++++++++++++++++---------------- src/vcd/main.py | 17 +++++++++-------- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/codem/lib/log.py b/src/codem/lib/log.py index b81d48e..f36a7f1 100644 --- a/src/codem/lib/log.py +++ b/src/codem/lib/log.py @@ -92,7 +92,11 @@ def __init__(self, config: Dict[str, Any]): elif config["LOG_TYPE"] == "websocket": formatter = CustomJsonFormatter() self.relay = websocket.WebSocket() - self.relay.connect(f'ws://{config["WEBSOCKET_URL"]}/websocket') + url = f'ws://{config["WEBSOCKET_URL"]}/websocket' + try: + self.relay.connect(url) + except ConnectionRefusedError as err: + raise ConnectionRefusedError(f"Connection Refused to {url}") log_handler = WebSocketHandler("DEBUG", websocket=self.relay) log_handler.setFormatter(formatter) else: diff --git a/src/codem/lib/progress.py b/src/codem/lib/progress.py index 4f06cc4..42e5e02 100644 --- a/src/codem/lib/progress.py +++ b/src/codem/lib/progress.py @@ -19,7 +19,11 @@ def __init__(self, url: str) -> None: self.url = url def __enter__(self) -> Any: - self.ws.connect(f"ws://{self.url}/websocket") + url = f'ws://{self.url}/websocket' + try: + self.ws.connect(url) + except ConnectionRefusedError as err: + raise ConnectionRefusedError(f"Connection Refused to {url}") return self def __exit__(self, *args: Any, **kwargs: Any) -> None: diff --git a/src/codem/main.py b/src/codem/main.py index cf10785..d4dc3eb 100644 --- a/src/codem/main.py +++ b/src/codem/main.py @@ -170,98 +170,98 @@ def get_args() -> argparse.Namespace: help="path to the area of interest file", ) ap.add_argument( - "--min_resolution", + "--min-resolution", "-min", type=float, default=CodemRunConfig.MIN_RESOLUTION, help="minimum pipeline data resolution", ) ap.add_argument( - "--dsm_akaze_threshold", + "--dsm-akaze-threshold", "-dat", type=float, default=0.0001, help="AKAZE feature detection response threshold", ) ap.add_argument( - "--dsm_lowes_ratio", + "--dsm-lowes-ratio", "-dlr", type=float, default=0.9, help="feature matching relative strength control", ) ap.add_argument( - "--dsm_ransac_max_iter", + "--dsm-ransac-max-iter", "-drmi", type=int, default=10000, help="max iterations for the RANSAC algorithm", ) ap.add_argument( - "--dsm_ransac_threshold", + "--dsm-ransac-threshold", "-drt", type=float, default=10, help="maximum residual error for a feature matched pair to be included in RANSAC solution", ) ap.add_argument( - "--dsm_solve_scale", + "--dsm-solve-scale", "-dss", type=str2bool, default=True, help="boolean to include or exclude scale from the solved registration transformation", ) ap.add_argument( - "--dsm_strong_filter", + "--dsm-strong-filter", "-dsf", type=float, default=10, help="stddev of the large Gaussian filter used to normalize DSM prior to feature extraction", ) ap.add_argument( - "--dsm_weak_filter", + "--dsm-weak-filter", "-dwf", type=float, default=1, help="stddev of the small Gaussian filter used to normalize the DSM prior to feature extraction", ) ap.add_argument( - "--icp_angle_threshold", + "--icp-angle-threshold", "-iat", type=float, default=0.001, help="minimum change in Euler angle between ICP iterations", ) ap.add_argument( - "--icp_distance_threshold", + "--icp-distance-threshold", "-idt", type=float, default=0.001, help="minimum change in translation between ICP iterations", ) ap.add_argument( - "--icp_max_iter", + "--icp-max-iter", "-imi", type=int, default=100, help="max iterations of the ICP algorithm", ) ap.add_argument( - "--icp_rmse_threshold", + "--icp-rmse-threshold", "-irt", type=float, default=0.0001, help="minimum relative change between iterations in the RMSE", ) ap.add_argument( - "--icp_robust", + "--icp-robust", "-ir", type=str2bool, default=True, help="boolean to include or exclude robust weighting in registration solution", ) ap.add_argument( - "--icp_solve_scale", + "--icp-solve-scale", "-iss", type=str2bool, default=True, @@ -285,7 +285,7 @@ def get_args() -> argparse.Namespace: ), ) ap.add_argument( - "--output_dir", "-o", type=str, help="Directory to place registered output." + "--output-dir", "-o", type=str, help="Directory to place registered output." ) ap.add_argument( "--version", @@ -294,7 +294,7 @@ def get_args() -> argparse.Namespace: help="Display codem version information", ) ap.add_argument( - "--log_type", + "--log-type", "-l", type=str, default=CodemRunConfig.LOG_TYPE, @@ -332,6 +332,7 @@ def create_config(args: argparse.Namespace) -> CodemParameters: TIGHT_SEARCH=args.tight_search, OUTPUT_DIR=args.output_dir, LOG_TYPE=args.log_type, + WEBSOCKET_URL=args.websocket_url ) config_dict = dataclasses.asdict(config) log = Log(config_dict) diff --git a/src/vcd/main.py b/src/vcd/main.py index 0d89b97..7c0ea01 100644 --- a/src/vcd/main.py +++ b/src/vcd/main.py @@ -110,25 +110,25 @@ def get_args() -> argparse.Namespace: help="Raster output resolution", ) ap.add_argument( - "--min_points", + "--min-points", type=int, default=VcdRunConfig.MIN_POINTS, help="Minimum points to cluster around", ) ap.add_argument( - "--cluster_tolerance", + "--cluster-tolerance", type=float, default=VcdRunConfig.CLUSTER_TOLERANCE, help="Cluster tolerance used by pdal.Filter.cluster", ) ap.add_argument( - "--cull_cluster_ids", + "--cull-cluster-ids", type=str, default=",".join(map(str, VcdRunConfig.CULL_CLUSTER_IDS)), help="Comma separated list of cluster IDs to cull when producing the meshes", ) ap.add_argument( - "--class_labels", + "--class-labels", type=str, default=",".join(map(str, VcdRunConfig.CLASS_LABELS)), help="Comma separated list of classification labels to use when producing the meshes", @@ -148,7 +148,7 @@ def get_args() -> argparse.Namespace: ), ) ap.add_argument( - "--trust_labels", + "--trust-labels", action="store_true", help=( "Trusts existing classification labels in the removal of vegetation/noise, " @@ -157,7 +157,7 @@ def get_args() -> argparse.Namespace: ), ) ap.add_argument( - "--compute_hag", + "--compute-hag", action="store_true", help=( "Compute height above ground between after scan (non-ground) and before " @@ -165,7 +165,7 @@ def get_args() -> argparse.Namespace: ), ) ap.add_argument( - "--output_dir", "-o", type=str, help="Directory to place VCD output" + "--output-dir", "-o", type=str, help="Directory to place VCD output" ) ap.add_argument( "--version", @@ -174,7 +174,7 @@ def get_args() -> argparse.Namespace: help="Display codem version information", ) ap.add_argument( - "--log_type", + "--log-type", "-l", type=str, default=VcdRunConfig.LOG_TYPE, @@ -205,6 +205,7 @@ def create_config(args: argparse.Namespace) -> VCDParameters: COMPUTE_HAG=args.compute_hag, OUTPUT_DIR=args.output_dir, LOG_TYPE=args.log_type, + WEBSOCKET_URL=args.websocket_url ) config_dict = dataclasses.asdict(config) log = Log(config_dict) From 1d8a9e1ea8bb95bd44bfb0cf92da0cc18f67ecc0 Mon Sep 17 00:00:00 2001 From: Ogi Moore Date: Thu, 2 Nov 2023 12:47:14 -0700 Subject: [PATCH 4/4] bump version for release --- src/codem/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codem/__init__.py b/src/codem/__init__.py index 71d59d1..5165cf8 100644 --- a/src/codem/__init__.py +++ b/src/codem/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.25.4.dev0" +__version__ = "0.25.4" import codem.lib.log as log import codem.lib.resources as resources