boB Rudis
3 years ago
18 changed files with 431 additions and 14 deletions
@ -0,0 +1,2 @@ |
|||
YEAR: 2021 |
|||
COPYRIGHT HOLDER: tcam authors |
@ -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. |
@ -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) |
|||
|
@ -0,0 +1 @@ |
|||
utils::globalVariables(c(".")) |
@ -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() |
|||
|
|||
} |
@ -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 (<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. |
|||
#' |
|||
#' @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" |
|||
|
@ -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 |
@ -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")] |
|||
|
|||
} |
@ -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 |
|||
(<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. |
|||
|
|||
## 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() |
|||
) |
|||
``` |
|||
|
|||
<img src="man/figures/README-ex-02-1.png" width="672" /> |
|||
|
|||
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. |
After Width: | Height: | Size: 39 KiB |
@ -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. |
|||
} |
@ -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. |
|||
} |
@ -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} |
@ -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 |
|||
} |
@ -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. |
|||
} |
Loading…
Reference in new issue