solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit bc9f037f22b3f5ac05a73426b2d5c3eddf89881f
parent 92eae8328afc2a958a22515e161c83af061b9c26
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon,  6 Mar 2017 19:11:16 +0100

First commit; not tested on Linux yet.

Diffstat:
Mcmake/CMakeLists.txt | 1+
Mcmake/parser/CMakeLists.txt | 2+-
Acmake/test_model/CMakeLists.txt | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/solstice.c | 9++++++---
Msrc/solstice_args.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/solstice_args.h.in | 8++++++++
Asrc/test_model/test_model.c | 364+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/beam_down.ref | 5+++++
Ayaml/beam_down.yaml | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/beam_down_receiver.yaml | 1+
10 files changed, 606 insertions(+), 6 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -59,6 +59,7 @@ include_directories( ################################################################################ add_subdirectory(parser) add_subdirectory(receivers) +add_subdirectory(test_model) ################################################################################ # Generate files diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -39,7 +39,7 @@ set(SOLPARSER_FILES_INC solparser_shape.h solparser_sun.h) -# Prepend each file in the `SOLSTICE_FILES_<SRC|INC>' list by `SOLSTICE_SOURCE_DIR' +# Prepend each file in the `SOLPARSER_FILES_<SRC|INC>' list by `SOLPARSER_SOURCE_DIR' rcmake_prepend_path(SOLPARSER_FILES_SRC ${SOLPARSER_SOURCE_DIR}) rcmake_prepend_path(SOLPARSER_FILES_INC ${SOLPARSER_SOURCE_DIR}) rcmake_prepend_path(SOLPARSER_FILES_DOC ${PROJECT_SOURCE_DIR}/../) diff --git a/cmake/test_model/CMakeLists.txt b/cmake/test_model/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (C) CNRS 2016-2017 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 2.8) +project(test_model C) + +set(TESTMODEL_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../src/test_model) + +################################################################################ +# Define include directories +################################################################################ +include_directories( + ${LibYAML_INCLUDE_DIR} + ${RSys_INCLUDE_DIR} + ${TESTMODEL_SOURCE_DIR}/../) + +################################################################################ +# Configure and define targets +################################################################################ +set(TESTMODEL_FILES_SRC + test_model.c) + +# Prepend each file in the `TESTMODEL_FILES_<SRC|INC>' list by `TESTMODEL_SOURCE_DIR' +rcmake_prepend_path(TESTMODEL_FILES_SRC ${TESTMODEL_SOURCE_DIR}) + +if(CMAKE_COMPILER_IS_GNUCC) + set(MATH_LIB m) +endif() + +add_executable(test_model ${TESTMODEL_FILES_SRC}) + +################################################################################ +# Tests +################################################################################ +if(NOT NO_TEST) + add_test(test_beam_down test_model beam_down) + + rcmake_copy_runtime_libraries(test_model) + +endif() diff --git a/src/solstice.c b/src/solstice.c @@ -306,11 +306,11 @@ static res_T setup_sun_dirs(struct solstice* solstice, const struct solstice_args* args) { double* sun_dirs = NULL; - size_t i; + size_t i, ii; res_T res = RES_OK; ASSERT(solstice && args); - res = darray_double_resize(&solstice->sun_dirs, args->nsun_dirs*3/*#dims*/); + res = darray_double_resize(&solstice->sun_dirs, (args->nsun_dirs + args->nsun_dirs3)*3/*#dims*/); if(res != RES_OK) { fprintf(stderr, "Could not reserve the list of %lu sun directions.\n", @@ -323,6 +323,9 @@ setup_sun_dirs(struct solstice* solstice, const struct solstice_args* args) FOR_EACH(i, 0, args->nsun_dirs) { spherical_to_cartesian_sun_dir(args->sun_dirs + i, sun_dirs + i*3/*#dims*/); } + FOR_EACH(ii, 0, args->nsun_dirs3) { + d3_normalize(sun_dirs + (i + ii) * 3/*#dims*/, &args->sun_dirs3[ii].x); + } exit: return res; @@ -664,6 +667,7 @@ solstice_run(struct solstice* solstice) } else { FOR_EACH(i, 0, nsun_dirs) { const double* sun_dir = sun_dirs + i*3/*#dims*/; + fprintf(solstice->output, "#--- Sun direction: %g %g %g\n", SPLIT3(sun_dir)); res = solstice_update_entities(solstice, sun_dir); if(res != RES_OK) goto error; @@ -683,7 +687,6 @@ solstice_run(struct solstice* solstice) res = solstice_solve(solstice); if(res != RES_OK) goto error; } - fprintf(solstice->output, "#--- Sun direction: %g %g %g\n", SPLIT3(sun_dir)); } } diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -44,6 +44,8 @@ print_help(const char* program) printf( " -D <dirs> list of sun directions.\n"); printf( +" -3 <dir> sun direction.\n"); + printf( " -f do not prompt before overwriting the output file submitted\n" " with the '-o' option.\n"); printf( @@ -162,6 +164,57 @@ error: } static res_T +parse_sun_dir3(const char* str, struct solstice_args* args) +{ + char buf[512]; + char* tk; + char* ctx; + size_t len; + res_T res = RES_OK; + ASSERT(str && args); + + if (strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the list of sun directions `%s'.\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + tk = strtok_r(buf, ":", &ctx); + while (tk) { + struct solstice_args_dir3 tmp; + + res = cstr_to_list_double(tk, ',', &tmp.x, &len, 3); + if (res == RES_OK && len != 3) res = RES_BAD_ARG; + if (res != RES_OK) { + fprintf(stderr, "Invalid sun direction `%s'.\n", tk); + goto error; + } + + if (tmp.x == 0 && tmp.y == 0 && tmp.z == 0) { + fprintf(stderr, "Invalid 0,0,0 sun direction.\n"); + res = RES_BAD_ARG; + goto error; + } + sa_push(args->sun_dirs3, tmp); + + tk = strtok_r(NULL, ":", &ctx); + } + args->nsun_dirs3 += sa_size(args->sun_dirs3); + +exit: + return res; +error: + if (args->sun_dirs3) { + sa_release(args->sun_dirs3); + args->sun_dirs3 = NULL; + args->nsun_dirs3 = 0; + } + goto exit; +} + +static res_T parse_image_definition (const char* str, unsigned long* width, @@ -438,11 +491,14 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) *args = SOLSTICE_ARGS_DEFAULT; optind = 0; - while((opt = getopt(argc, argv, "D:fg:Hhn:o:qR:r:t:")) != -1) { + while((opt = getopt(argc, argv, "D:3:fg:Hhn:o:qR:r:t:")) != -1) { switch(opt) { case 'D': res = parse_sun_dir_list(optarg, args); break; + case '3': + res = parse_sun_dir3(optarg, args); + break; case 'f': args->force_overwriting = 1; break; case 'H': args->output_hits = 1; break; case 'h': @@ -476,7 +532,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) if(!args->rendering && args->dump_format == SOLSTICE_ARGS_DUMP_NONE - && !args->nsun_dirs) { + && 0 == args->nsun_dirs + args->nsun_dirs3) { fprintf(stderr, "Missing sun direction.\n"); res = RES_BAD_ARG; goto error; @@ -505,6 +561,7 @@ solstice_args_release(struct solstice_args* args) { ASSERT(args); sa_release(args->sun_dirs); + sa_release(args->sun_dirs3); *args = SOLSTICE_ARGS_NULL; } diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in @@ -24,6 +24,10 @@ struct solstice_args_spherical { double elevation; /* In radians */ }; +struct solstice_args_dir3 { + double x, y, z; +}; + enum solstice_args_dump_format { SOLSTICE_ARGS_DUMP_OBJ, SOLSTICE_ARGS_DUMP_NONE @@ -45,6 +49,8 @@ struct solstice_args { /* List of sun directions */ struct solstice_args_spherical* sun_dirs; size_t nsun_dirs; + struct solstice_args_dir3* sun_dirs3; + size_t nsun_dirs3; struct { double pos[3]; @@ -81,6 +87,8 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; \ NULL, /* sun_dirs */ \ 0, /* # nsun_dirs */ \ + NULL, /* sun_dirs3 */ \ + 0, /* # nsun_dirs3 */ \ \ { /* Camera */ \ { @SOLSTICE_ARGS_DEFAULT_CAMERA_POS@ }, \ diff --git a/src/test_model/test_model.c b/src/test_model/test_model.c @@ -0,0 +1,364 @@ +/* Copyright (C) CNRS 2016-2017 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <rsys/rsys.h> + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#ifdef COMPILER_CL + /* Wrap POSIX functions and constants */ + #include <io.h> + #define fdopen _fdopen + #define fileno _fileno + #define execvp _execvp +#endif + +#ifndef COMPILER_CL +#include <linux/limits.h> /* MAX_PATH */ +#endif + +enum side { + FRONT, + BACK +}; + +enum RESULTS { + FRONT_INTEGRATED_IRRADIANCE, + BACK_INTEGRATED_IRRADIANCE, + FRONT_REFLECTIVITY_LOSS, + BACK_REFLECTIVITY_LOSS, + FRONT_ABSORPTIVITY_LOSS, + BACK_ABSORPTIVITY_LOSS, + FRONT_COS_LOSS, + BACK_COS_LOSS, + FRONT_EFFICIENCY, + BACK_EFFICIENCY, + MAX_RESULTS_COUNT__ +}; + +static int +file_exists(const char* name) +{ + FILE* f = fopen(name, "r"); + if (!f) return 0; + fclose(f); + return 1; +} + +#define MAX_LINE_LEN 2048 +static res_T +get_dir_and_counts + (FILE* ref_file, + double sun_dir[3], + size_t* recv_count, + size_t* realisation_count) +{ + const char sundir_header [] = "#--- Sun direction:"; + char line[MAX_LINE_LEN]; + + ASSERT(ref_file); + if (!fgets(line, sizeof(line), ref_file)) return RES_BAD_ARG; + if (0 != strncmp(line, sundir_header, strlen(sundir_header))) + return RES_BAD_ARG; + /* get sun dir */ + if (3 != sscanf(line + strlen(sundir_header), + "%lg%lg%lg", &sun_dir[0], &sun_dir[1], &sun_dir[2])) { + return RES_BAD_ARG; + } + /* get sun dir */ + if (!fgets(line, sizeof(line), ref_file)) return RES_BAD_ARG; + if (2 != sscanf(line, "%zu%zu", recv_count, realisation_count)) + return RES_BAD_ARG; + return RES_OK; +} + +#define READ_RECV(Name, Values, Std) \ +{ \ + if (2 * MAX_RESULTS_COUNT__ + 1 \ + != sscanf(line, \ + "%s%*zu%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg", \ + Name, \ + &Values[FRONT_INTEGRATED_IRRADIANCE], &Std[FRONT_INTEGRATED_IRRADIANCE], \ + &Values[BACK_INTEGRATED_IRRADIANCE], &Std[BACK_INTEGRATED_IRRADIANCE], \ + &Values[FRONT_REFLECTIVITY_LOSS], &Std[FRONT_REFLECTIVITY_LOSS], \ + &Values[BACK_REFLECTIVITY_LOSS], &Std[BACK_REFLECTIVITY_LOSS], \ + &Values[FRONT_ABSORPTIVITY_LOSS], &Std[FRONT_ABSORPTIVITY_LOSS], \ + &Values[BACK_ABSORPTIVITY_LOSS], &Std[BACK_ABSORPTIVITY_LOSS], \ + &Values[FRONT_COS_LOSS], &Std[FRONT_COS_LOSS], \ + &Values[BACK_COS_LOSS], &Std[BACK_COS_LOSS], \ + &Values[FRONT_EFFICIENCY], &Std[FRONT_EFFICIENCY], \ + &Values[BACK_EFFICIENCY], &Std[BACK_EFFICIENCY]) \ + ) \ + { \ + res = RES_BAD_ARG; \ + goto error; \ + } \ +} + +#define POSITIVE_OR_M_ONE(x) ((x) == -1 || (x) >= 0) + +static FINLINE int +is_compatible_with + (const double ref_E, + const double ref_SE, + const double test_E, + const double test_SE) +{ + ASSERT(POSITIVE_OR_M_ONE(ref_E) && POSITIVE_OR_M_ONE(ref_SE) + && POSITIVE_OR_M_ONE(test_E) && POSITIVE_OR_M_ONE(test_SE)); + if (ref_E == -1) { + ASSERT(ref_SE == -1); + return (test_E == -1 && test_SE == -1); + } + ASSERT(ref_SE != -1); + return (fabs(ref_E - test_E) <= 2 * ref_SE && test_SE <= 2 * ref_SE); +} + +static res_T +check_1_reference + (const char* tested_file_name, + const char* rcv_name, + const double* reference_E, + const double* reference_SE) +{ + res_T res = RES_OK; + ASSERT(tested_file_name && rcv_name && reference_E && reference_SE); + FILE* tested_file = fopen(tested_file_name, "r"); + double d[3]; + size_t c1, c2; + + if (!tested_file) { + res = RES_IO_ERR; + goto end; + } + res = get_dir_and_counts(tested_file, d, &c1, &c2); /* skip headers */ + if (res != RES_OK) goto error; + while(!feof(tested_file)) { + char line[MAX_LINE_LEN]; + char tested_rcv_name[MAX_LINE_LEN]; + double tested_E[MAX_RESULTS_COUNT__], tested_SE[MAX_RESULTS_COUNT__]; + enum RESULTS r; + if (!fgets(line, sizeof(line), tested_file)) { + res = RES_BAD_ARG; + goto error; + } + READ_RECV(tested_rcv_name, tested_E, tested_SE); + if (strcmp(rcv_name, tested_rcv_name)) continue; + for (r = FRONT_INTEGRATED_IRRADIANCE; r < MAX_RESULTS_COUNT__; r++) { + if (!is_compatible_with + (reference_E[r], reference_SE[r], tested_E[r], tested_SE[r])) + { + res = RES_BAD_ARG; + goto error; + } + } + goto end; /* success */ + } + res = RES_BAD_ARG; /* could not find data */ +end: + if (tested_file) fclose(tested_file); + return res; +error: + goto end; +} + +static res_T +check_1_global + (const char* tested_file_name, + const double reference_E, + const double reference_SE, + const unsigned rank) +{ + res_T res = RES_OK; + char line[MAX_LINE_LEN]; + FILE* tested_file; + double d[3]; + size_t recv_count, r2; + unsigned i; + int nb; + double tested_E, tested_SE; + + ASSERT(tested_file_name); + tested_file = fopen(tested_file_name, "r"); + if (!tested_file) { + res = RES_IO_ERR; + goto end; + } + res = get_dir_and_counts(tested_file, d, &recv_count, &r2); + if (res != RES_OK) goto error; + /* skip receivers */ + for ( ; recv_count--; ) { + if (!fgets(line, sizeof(line), tested_file)) { + res = RES_BAD_ARG; + goto error; + } + } + /* read the rank th global data */ + for (i = 0; i <= rank; i++) { + if (!fgets(line, sizeof(line), tested_file)) { + res = RES_BAD_ARG; + goto error; + } + } + nb = sscanf(line, "%lg%lg", &tested_E, &tested_SE); + if (nb != 2) { + res = RES_BAD_ARG; + goto error; + } + if (!is_compatible_with + (reference_E, reference_SE, tested_E, tested_SE)) { + res = RES_BAD_ARG; + goto error; + } + +end: + if (tested_file) fclose(tested_file); + return res; +error: + goto end; +} + + +static res_T +check_references + (FILE* ref_file, const char* tested_file_name) +{ + res_T res = RES_OK; + char line[MAX_LINE_LEN]; + int nb_global = 0; + + ASSERT(ref_file && tested_file_name); + for ( ; ; ) { + int nb = 0; + double val, std; + if (!fgets(line, sizeof(line), ref_file)) { + if (feof(ref_file)) goto end; + res = RES_BAD_ARG; + goto error; + } + nb = sscanf(line, "%lg%lg", &val, &std); + ASSERT(nb == 0 || nb == 2); + if (nb != 0) { + res = check_1_global(tested_file_name, val, std, nb_global); + if (res != RES_OK) goto error; + nb_global++; + } + else { + char ref_name[MAX_LINE_LEN]; + double reference_E[MAX_RESULTS_COUNT__], reference_SE[MAX_RESULTS_COUNT__]; + READ_RECV(ref_name, reference_E, reference_SE); + res = + check_1_reference(tested_file_name, ref_name, reference_E, reference_SE); + if (res != RES_OK) goto error; + } + }; + +end: + CHECK(remove(tested_file_name), 0); + return res; +error: + goto end; +} + +static FINLINE res_T +create_tmp_file_name(char* out_name) +{ + ASSERT(out_name); +#ifdef COMPILER_CL + if (tmpnam_s(out_name, L_tmpnam_s)) return RES_IO_ERR; +#else + int fd; + strncpy(out_name, "solstice_tmp_file_XXXXXX", L_tmpnam_s); + fd = mkstemp(out_name); + if (-1 == fd) return RES_IO_ERR; + /* just want a name */ + close(fd); +#endif + return RES_OK; +} + +static res_T +do_check(const char* base_name) +{ + res_T res = RES_OK; + FILE* ref_file; + char ref_file_name[MAX_PATH]; + size_t c1, realisation_count; + + ASSERT(base_name); + snprintf(ref_file_name, MAX_PATH, "../../yaml/%s.ref", base_name); + ref_file = fopen(ref_file_name, "r"); + if (!ref_file) { + res = RES_IO_ERR; + printf("Cannot open file '%s'\n", base_name); + goto end; + } + while (!feof(ref_file)) { + char cmd[128 + 3 * MAX_PATH]; + double sun_dir[3]; + char tested_file_name[L_tmpnam_s]; +#ifdef COMPILER_CL + char* exe_name = "..\\Debug\\solstice.exe"; +#else + char* exe_name = "../Debug/solstice.exe"; +#endif + + res = get_dir_and_counts(ref_file, sun_dir, &c1, &realisation_count); + if (res != RES_OK) goto end; + + res = create_tmp_file_name(tested_file_name); + if (res != RES_OK) goto end; + + snprintf(cmd, sizeof(cmd), + "%s -o %s -f -3 %lg,%lg,%lg -n %zu -R ../../yaml/%s_receiver.yaml ../../yaml/%s.yaml", + exe_name, tested_file_name, SPLIT3(sun_dir), realisation_count, base_name, base_name); + if (system(cmd)) { + res = RES_BAD_ARG; + goto end; + } + res = check_references(ref_file, tested_file_name); + if (res != RES_OK) { + goto end; + } + } +end: + if (ref_file) fclose(ref_file); + return res; +} + +/* + * FIXME: does not manage multiple sun directions + */ +int +main(int argc, char** argv) +{ + int err = 0; + + if (argc != 2) goto usage; + + if (RES_OK != do_check(argv[1])) + goto error; + +exit: + return err; +usage: + printf("Usage: %s <file_base_name>\n", argv[0]); +error: + err = 1; + goto exit; +} + diff --git a/yaml/beam_down.ref b/yaml/beam_down.ref @@ -0,0 +1,5 @@ +#--- Sun direction: -3.7494e-33 -6.12323e-17 -1 +1 10000 +tower.receptor 14 465.464 0.00509812 -1 -1 0 0 -1 -1 0 0 -1 -1 34.5362 0.00509812 -1 -1 0.930847 1.01954e-05 -1 -1 +0 0 +0 0 diff --git a/yaml/beam_down.yaml b/yaml/beam_down.yaml @@ -0,0 +1,108 @@ +# Debug/solstice -D 90,90 -R ../yaml/beam_down_receiver.yaml ../yaml/beam_down.yaml +# Debug/solstice -D 90,90 -r pos=-100,-100,50:tgt=0,0,50:up=0,0,1:img=1000x800 -o ../yaml/beam_down.ppm -f ../yaml/beam_down.yaml +# +# 1 10000 +# tower.receptor 14 465.464 0.00509812 -1 -1 0 0 -1 -1 0 0 -1 -1 34.5362 0.00509812 -1 -1 0.930847 1.01954e-05 -1 -1 +# 0 0 +# 0 0 +# --- Sun direction: -3.7494e-33 -6.12323e-17 -1 + +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } + +- material: &mirror { mirror: { reflectivity: 1, roughness: 0 } } +- material: &black { matte: { reflectivity: 0 } } +- material: &virtual { virtual: } + +- template: &hyperbol + name: hyperbol + primary: 0 + geometry: + - hyperbol: + focals: &hyperbol_focals { real: 100, image: 20 } + clip: + - operation: AND + #vertices: [[-25, -25], [-25, 25], [25, 25], [25, -25]] + vertices: [[-5, 0], [20, -10], [35, 0], [20, 10]] + material: { front: *mirror, back: *virtual } + anchors: + - name: image_point + hyperboloid_image_focals: *hyperbol_focals + +- geometry: &target + - plane: + clip: + - operation: AND + vertices: [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]] + #vertices: [[-1, -1], [-1, 1], [1, 1], [1, -1]] + #vertices: [[-.5, -.5], [-.5, .5], [.5, .5], [.5, -.5]] + #vertices: [[-.1, -.1], [-.1, .1], [.1, .1], [.1, -.1]] + material: *black + +- geometry: &primary150 + - parabol: + focal: 150 + clip: + - operation: AND + vertices: [[-5, -5], [-5, 5], [5, 5], [5, -5]] + #vertices: [[-3, -3], [-3, 3], [3, 3], [3, -3]] + #vertices: [[-2, -2], [-2, 2], [2, 2], [2, -2]] + #vertices: [[-1, -1], [-1, 1], [1, 1], [1, -1]] + #vertices: [[-.01, -.01], [-.01, .01], [.01, .01], [.01, -.01]] + material: *mirror + +- template: &temp_heliostat150 + name: "temp-heliostat150" + primary: 0 + geometry: + - cylinder: { radius: 0.3, height: 10 } + transform: { translation: [0, 0, 5] } + material: *black + children: + - name: "pivot" + transform: { translation: [0, 0, 10] } + zx_pivot: + spacing: 1 + target: { anchor: tower.secondary.hyperbol.image_point } + children: + - name: "reflector" + transform: { rotation: [-90, 0, 0] } + primary: 1 + geometry: *primary150 + +- entity: + name: "tower" + children: + - name: secondary + children: [ *hyperbol ] + transform: { translation: [ 0, 0, 100 ] } + - name: receptor + geometry: *target + primary: 0 + - name: "building" + primary: 0 + geometry: + - cylinder: { radius: 1, height: 110 } + transform: { translation: [-4, 0, 55] } + material: *black + +- entity: + name: "heliostat1" + transform: { translation: [100, -30, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat2" + transform: { translation: [101, -15, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat3" + transform: { translation: [102, 0, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat4" + transform: { translation: [101, 15, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat5" + transform: { translation: [100, 30, 0] } + children: [ *temp_heliostat150 ] + +\ No newline at end of file diff --git a/yaml/beam_down_receiver.yaml b/yaml/beam_down_receiver.yaml @@ -0,0 +1 @@ +- { name: "tower.receptor", side: FRONT }