From ad65ac86293e8d41c5b9261842f0562bd57b81d2 Mon Sep 17 00:00:00 2001 From: hrbrmstr Date: Thu, 19 Aug 2021 16:29:17 -0400 Subject: [PATCH] intial commit --- DESCRIPTION | 19 +++++-- LICENSE | 2 + LICENSE.md | 21 ++++++++ NAMESPACE | 15 +++++- R/aaa.R | 1 + R/core.R | 61 +++++++++++++++++++++ R/tcam-package.R | 18 +++++-- R/utils-pipe.R | 14 +++++ R/utils.R | 43 +++++++++++++++ README.Rmd | 44 ++++++++++++++- README.md | 119 +++++++++++++++++++++++++++++++++++++++++ man/figures/README-ex-02-1.png | Bin 0 -> 40273 bytes man/get_image.Rd | 14 +++++ man/get_status.Rd | 14 +++++ man/pipe.Rd | 20 +++++++ man/tcam.Rd | 8 ++- man/tcam_connect.Rd | 14 +++++ man/tidy_radiometric.Rd | 18 +++++++ 18 files changed, 431 insertions(+), 14 deletions(-) create mode 100644 LICENSE create mode 100644 LICENSE.md create mode 100644 R/aaa.R create mode 100644 R/core.R create mode 100644 R/utils-pipe.R create mode 100644 R/utils.R create mode 100644 README.md create mode 100644 man/figures/README-ex-02-1.png create mode 100644 man/get_image.Rd create mode 100644 man/get_status.Rd create mode 100644 man/pipe.Rd create mode 100644 man/tcam_connect.Rd create mode 100644 man/tidy_radiometric.Rd diff --git a/DESCRIPTION b/DESCRIPTION index d1500ba..bde9333 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,7 @@ Package: tcam Type: Package -Title: tcam Title Goes Here Otherwise CRAN Checks Fail +Title: Retrieve Radiometric Image Data from and Configure and Control tCam and + tCam-Mini Thermal Imaging Systems Version: 0.1.0 Date: 2021-08-19 Authors@R: c( @@ -8,17 +9,25 @@ Authors@R: c( comment = c(ORCID = "0000-0001-5670-2640")) ) Maintainer: Bob Rudis -Description: A good description goes here otherwise CRAN checks fail. +Description: The tCam and tCam-Mini () + are two cameras designed around the ESP32 chipset and provide easy access to + radiometric data from Lepton 3.5 sensors. Tools are provided to configure, control, + and receive radiometric data from tCam systems. URL: https://git.rud.is/hrbrmstr/tcam BugReports: https://git.rud.is/hrbrmstr/tcam/issues Encoding: UTF-8 -License: AGPL +License: MIT + file LICENSE Suggests: covr, tinytest Depends: R (>= 3.6.0) Imports: - httr, - jsonlite + RcppSimdJson, + openssl, + tidyr, + dplyr, + magrittr, + stringi, + utils Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b6e2729 --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2021 +COPYRIGHT HOLDER: tcam authors diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..f8a435d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2021 tcam authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE index 5b4b9ae..260d10b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,4 +1,15 @@ # Generated by roxygen2: do not edit by hand -import(httr) -importFrom(jsonlite,fromJSON) +export("%>%") +export(get_image) +export(get_status) +export(tcam_connect) +export(tidy_radiometric) +importFrom(RcppSimdJson,fparse) +importFrom(dplyr,mutate) +importFrom(dplyr,mutate_at) +importFrom(magrittr,"%>%") +importFrom(openssl,base64_decode) +importFrom(stringi,stri_replace_all_regex) +importFrom(tidyr,gather) +importFrom(utils,hasName) diff --git a/R/aaa.R b/R/aaa.R new file mode 100644 index 0000000..4476951 --- /dev/null +++ b/R/aaa.R @@ -0,0 +1 @@ +utils::globalVariables(c(".")) \ No newline at end of file diff --git a/R/core.R b/R/core.R new file mode 100644 index 0000000..4e8fb43 --- /dev/null +++ b/R/core.R @@ -0,0 +1,61 @@ +#' Make a socket connection to a tCam device +#' +#' @param host,port IP/hostname + port; defaults to the device defaults +#' @export +tcam_connect <- function(host = "192.168.4.1", port = 5001) { + socketConnection( + host = host, + port = port, + open = "a+b" + ) +} + +#' Returns a packet with camera status. +#' +#' @param con open socket connection from [tcam_connect()] +#' @export +get_status <- function(con) { + + writeBin( + object = c(as.raw(0x02), charToRaw('{"cmd":"get_status"}'), as.raw(0x03)), + con = con, + useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readChar( + con = con, + nchars = 2048L, + useBytes = TRUE + ) %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} + +#' Returns a packet with metadata, radiometric (or AGC) image data and Lepton telemetry objects. +#' +#' @param con open socket connection from [tcam_connect()] +#' @export +get_image <- function(con) { + + tmp <- get_status(con) + + writeBin( + object = c(as.raw(0x02), charToRaw('{"cmd":"get_image"}'), as.raw(0x03)), + con = con, + useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readChar( + con = con, + nchars = 65536L, + useBytes = TRUE + ) %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} \ No newline at end of file diff --git a/R/tcam-package.R b/R/tcam-package.R index 5b12cfa..e3b6bd2 100644 --- a/R/tcam-package.R +++ b/R/tcam-package.R @@ -1,9 +1,19 @@ -#' ... -#' +#' Retrieve Radiometric Image Data from and Configure and Control tCam and tCam-Mini +#' Thermal Imaging Systems +#' +#' The tCam and tCam-Mini () +#' are two cameras designed around the ESP32 chipset and provide easy access to +#' radiometric data from Lepton 3.5 sensors. Tools are provided to configure, control, +#' and receive radiometric data from tCam systems. +#' #' @md #' @name tcam #' @keywords internal #' @author Bob Rudis (bob@@rud.is) -#' @import httr -#' @importFrom jsonlite fromJSON +#' @importFrom RcppSimdJson fparse +#' @importFrom openssl base64_decode +#' @importFrom tidyr gather +#' @importFrom dplyr mutate mutate_at +#' @importFrom stringi stri_replace_all_regex +#' @importFrom utils hasName "_PACKAGE" diff --git a/R/utils-pipe.R b/R/utils-pipe.R new file mode 100644 index 0000000..fd0b1d1 --- /dev/null +++ b/R/utils-pipe.R @@ -0,0 +1,14 @@ +#' Pipe operator +#' +#' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. +#' +#' @name %>% +#' @rdname pipe +#' @keywords internal +#' @export +#' @importFrom magrittr %>% +#' @usage lhs \%>\% rhs +#' @param lhs A value or the magrittr placeholder. +#' @param rhs A function call using the magrittr semantics. +#' @return The result of calling `rhs(lhs)`. +NULL diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..a005251 --- /dev/null +++ b/R/utils.R @@ -0,0 +1,43 @@ +#' Return a tidy data frame of Lepton radiometric data retrieved with [get_image()] +#' +#' Converts the base64 16-bit coded Kelvin radiometric data to a tidy "XYZ" +#' data frame in Fahrenheit. +#' +#' @param img_data data structure retrieved with [get_image()] +#' @returns data frame of `x`, `y`, and `value` +#' @export +tidy_radiometric <- function(img_data) { + + if (!hasName(img_data, "radiometric")) { + stop("Data structure does not seem to be tCam radiometric image data.", call.=FALSE) + } + + openssl::base64_decode(img_data$radiometric) %>% + readBin( + what = "integer", + n = 19200, + size = 2 + ) %>% + matrix( + nrow = 120, + ncol = 160, + byrow = TRUE, + dimnames = list(120:1) + ) -> m + + as.data.frame(m) %>% + mutate(y = rownames(m)) %>% + gather(x, value, -y) %>% + mutate_at( + vars(x), + ~sub("V", "", .) + ) %>% + mutate( + x = as.integer(x), + y = as.integer(y), + value = ((value / 100) * 1.8) - 459.67 # convert to degrees F b/c I'm a brutish Murican + ) -> xdf + + xdf[,c("x", "y", "value")] + +} \ No newline at end of file diff --git a/README.Rmd b/README.Rmd index bb89576..615a405 100644 --- a/README.Rmd +++ b/README.Rmd @@ -7,7 +7,7 @@ editor_options: hrbrpkghelpr::global_opts() ``` -```{r badges, results='asis', echo=FALSE, cache=FALSE} +```{r badges, results='asis', echo=FALSE, cache=FALSE, eval=FALSE} hrbrpkghelpr::stinking_badges() ``` @@ -33,12 +33,54 @@ hrbrpkghelpr::install_block() ```{r lib-ex} library(tcam) +library(ggplot2) # for plotting # current version packageVersion("tcam") ``` +Open a connection and get the status of the tCam: + +```{r ex-01} +con <- tcam_connect() + +get_status(con) +``` + +Take a picture and plot it: + +```{r ex-02, cache=TRUE} +img <- get_image(con) + +ggplot(tidy_radiometric(img)) + + geom_tile( + aes(x, y, fill = value), + color = NA + ) + + scale_fill_viridis_c( + name = "°F", + option = "magma" + ) + + coord_fixed() + + labs( + x = NULL, y = NULL + ) + + theme_minimal() + + theme( + axis.text.x.bottom = element_blank(), + axis.text.y.left = element_blank(), + panel.grid.major = element_blank(), + panel.grid.minor = element_blank() + ) +``` + +Done, so we close the connection. + +```{r ex-99} +close(con) +``` + ## tcam Metrics ```{r cloc, echo=FALSE} diff --git a/README.md b/README.md new file mode 100644 index 0000000..19e8fd5 --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ + +# tcam + +Retrieve Radiometric Image Data from and Configure and Control tCam and +tCam-Mini Thermal Imaging Systems + +## Description + +The tCam and tCam-Mini +() are two cameras +designed around the ESP32 chipset and provide easy access to radiometric +data from Lepton 3.5 sensors. Tools are provided to configure, control, +and receive radiometric data from tCam systems. + +## What’s Inside The Tin + +The following functions are implemented: + +- `get_image`: Returns a packet with metadata, radiometric (or AGC) + image data and Lepton telemetry objects. +- `get_status`: Returns a packet with camera status. +- `tcam_connect`: Make a socket connection to a tCam device +- `tidy_radiometric`: Return a tidy data frame of Lepton radiometric + data retrieved with get_image() + +## Installation + +``` r +remotes::install_git("https://git.rud.is/hrbrmstr/tcam.git") +``` + +NOTE: To use the ‘remotes’ install options you will need to have the +[{remotes} package](https://github.com/r-lib/remotes) installed. + +## Usage + +``` r +library(tcam) +library(ggplot2) # for plotting + +# current version +packageVersion("tcam") +## [1] '0.1.0' +``` + +Open a connection and get the status of the tCam: + +``` r +con <- tcam_connect() + +get_status(con) +## $status +## $status$Camera +## [1] "tCam-Mini-B3CD" +## +## $status$Model +## [1] 2 +## +## $status$Version +## [1] "1.3" +## +## $status$Time +## [1] "2:02:48.364" +## +## $status$Date +## [1] "1/1/-30" +``` + +Take a picture and plot it: + +``` r +img <- get_image(con) + +ggplot(tidy_radiometric(img)) + + geom_tile( + aes(x, y, fill = value), + color = NA + ) + + scale_fill_viridis_c( + name = "°F", + option = "magma" + ) + + coord_fixed() + + labs( + x = NULL, y = NULL + ) + + theme_minimal() + + theme( + axis.text.x.bottom = element_blank(), + axis.text.y.left = element_blank(), + panel.grid.major = element_blank(), + panel.grid.minor = element_blank() + ) +``` + + + +Done, so we close the connection. + +``` r +close(con) +``` + +## tcam Metrics + +| Lang | # Files | (%) | LoC | (%) | Blank lines | (%) | # Lines | (%) | +|:-----|--------:|-----:|----:|-----:|------------:|-----:|--------:|-----:| +| R | 6 | 0.33 | 74 | 0.28 | 18 | 0.21 | 51 | 0.28 | +| Rmd | 1 | 0.06 | 33 | 0.13 | 23 | 0.27 | 37 | 0.21 | +| YAML | 2 | 0.11 | 23 | 0.09 | 2 | 0.02 | 2 | 0.01 | +| SUM | 9 | 0.50 | 130 | 0.50 | 43 | 0.50 | 90 | 0.50 | + +clock Package Metrics for tcam + +## Code of Conduct + +Please note that this project is released with a Contributor Code of +Conduct. By participating in this project you agree to abide by its +terms. diff --git a/man/figures/README-ex-02-1.png b/man/figures/README-ex-02-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ab03b35e9ca7f072f5c8def309ce9b19ce52d303 GIT binary patch literal 40273 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 literal 0 HcmV?d00001 diff --git a/man/get_image.Rd b/man/get_image.Rd new file mode 100644 index 0000000..dcf8b29 --- /dev/null +++ b/man/get_image.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{get_image} +\alias{get_image} +\title{Returns a packet with metadata, radiometric (or AGC) image data and Lepton telemetry objects.} +\usage{ +get_image(con) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} +} +\description{ +Returns a packet with metadata, radiometric (or AGC) image data and Lepton telemetry objects. +} diff --git a/man/get_status.Rd b/man/get_status.Rd new file mode 100644 index 0000000..4d73e84 --- /dev/null +++ b/man/get_status.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{get_status} +\alias{get_status} +\title{Returns a packet with camera status.} +\usage{ +get_status(con) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} +} +\description{ +Returns a packet with camera status. +} diff --git a/man/pipe.Rd b/man/pipe.Rd new file mode 100644 index 0000000..a648c29 --- /dev/null +++ b/man/pipe.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils-pipe.R +\name{\%>\%} +\alias{\%>\%} +\title{Pipe operator} +\usage{ +lhs \%>\% rhs +} +\arguments{ +\item{lhs}{A value or the magrittr placeholder.} + +\item{rhs}{A function call using the magrittr semantics.} +} +\value{ +The result of calling \code{rhs(lhs)}. +} +\description{ +See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. +} +\keyword{internal} diff --git a/man/tcam.Rd b/man/tcam.Rd index 3ad54db..14e952d 100644 --- a/man/tcam.Rd +++ b/man/tcam.Rd @@ -4,9 +4,13 @@ \name{tcam} \alias{tcam} \alias{tcam-package} -\title{...} +\title{Retrieve Radiometric Image Data from and Configure and Control tCam and tCam-Mini +Thermal Imaging Systems} \description{ -A good description goes here otherwise CRAN checks fail. +The tCam and tCam-Mini (\url{https://github.com/danjulio/lepton/tree/master/ESP32}) +are two cameras designed around the ESP32 chipset and provide easy access to +radiometric data from Lepton 3.5 sensors. Tools are provided to configure, control, +and receive radiometric data from tCam systems. } \seealso{ Useful links: diff --git a/man/tcam_connect.Rd b/man/tcam_connect.Rd new file mode 100644 index 0000000..0c119c3 --- /dev/null +++ b/man/tcam_connect.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{tcam_connect} +\alias{tcam_connect} +\title{Make a socket connection to a tCam device} +\usage{ +tcam_connect(host = "192.168.4.1", port = 5001) +} +\arguments{ +\item{host, port}{IP/hostname + port; defaults to the device defaults} +} +\description{ +Make a socket connection to a tCam device +} diff --git a/man/tidy_radiometric.Rd b/man/tidy_radiometric.Rd new file mode 100644 index 0000000..e517411 --- /dev/null +++ b/man/tidy_radiometric.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{tidy_radiometric} +\alias{tidy_radiometric} +\title{Return a tidy data frame of Lepton radiometric data retrieved with \code{\link[=get_image]{get_image()}}} +\usage{ +tidy_radiometric(img_data) +} +\arguments{ +\item{img_data}{data structure retrieved with \code{\link[=get_image]{get_image()}}} +} +\value{ +data frame of \code{x}, \code{y}, and \code{value} +} +\description{ +Converts the base64 16-bit coded Kelvin radiometric data to a tidy "XYZ" +data frame in Fahrenheit. +}