Source code for vizSupport


#
#  ISC License
#
#  Copyright (c) 2016, Autonomous Vehicle Systems Lab, University of Colorado at Boulder
#
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#
#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

import numpy as np
import os
from Basilisk import __path__
from Basilisk.architecture import messaging
from Basilisk.simulation import spacecraft
from Basilisk.utilities import unitTestSupport
from Basilisk.utilities import deprecated
from Basilisk.utilities import quadMapSupport as qms
from matplotlib import colors
from matplotlib.colors import is_color_like

try:
    from Basilisk.simulation import vizInterface
    vizFound = True
except ImportError:
    vizFound = False

pauseFlag = False
endFlag = False

bskPath = __path__[0]

firstSpacecraftName = ''

def toRGBA255(color, alpha=None):
    if isinstance(color, str):
        # convert color name to 4D array of values with 0-255
        if is_color_like(color):

            answer = np.array(colors.to_rgba(color, alpha=alpha)) * 255
            answer = [round(a) for a in answer]
        else:
            print("toRGBA255() was provided unknown color name " + color)
            exit(1)
    else:
        if not isinstance(color, list):
            print('ERROR: vizSupport: color must be a 4D array of integers')
            exit(1)
        if max(color) > 255 or min(color) < 0:
            print('ERROR: vizSupport: color values must be between [0,255]')
            exit(1)
        answer = color
    return answer

[docs] def setSprite(shape, **kwargs): """ Helper function to set the sprite shape and optional sprite color. :param shape: Sprite shape, must be either "CIRCLE", "SQUARE", "TRIANGLE", "STAR", or "bskSat" :param kwargs: RGBA color, can be either color name string or a 4D list of [0,255] values :return: string of the protobuffer sprite setting """ unitTestSupport.checkMethodKeyword( ['color'], kwargs) shapeList = ["CIRCLE", "SQUARE", "TRIANGLE", "STAR", "bskSat"] if not isinstance(shape, str): print("In setSprite() the shape argument must be a string using " + str(shapeList)) exit(1) if shape not in shapeList: print("The setSprite() method was provided this unknown sprite shape primitive: " + shape) exit(1) answer = shape if 'color' in kwargs: colorInfo = kwargs['color'] if shape == "bskSat": print("cannot set a color for the bskSat sprite option") exit(1) colorValues = toRGBA255(colorInfo) answer += " " + " ".join(map(str, colorValues)) return answer
[docs] def lla2fixedframe(lla_GP, radEquator, radRatio): """ This method receives a latitude/longitude/altitude point above a reference ellipsoid with equatorial radius and flattening ratio, then converts to body-fixed frame coordinates. Parameters ---------- lla_GP: [rad,rad,m] position vector of the location G relative to the parent body in lat/lon/alt components radEquator: [m] equatorial radius of the parent body radRatio: ratio of polar radius to equatorial radius Returns ------- 3-element list [m] r_GP_P, position vector of the location G relative to parent body frame P in P frame components """ lat = lla_GP[0] lon = lla_GP[1] alt = lla_GP[2] N = radEquator / np.sqrt(1 - (1 - radRatio**2) * np.sin(lat)**2) X = (N + alt) * np.cos(lat) * np.cos(lon) Y = (N + alt) * np.cos(lat) * np.sin(lon) Z = (N * (1 - (1 - radRatio**2)) + alt) * np.sin(lat) r_GP_P = [X, Y, Z] return r_GP_P
[docs] def fixedframe2lla(r_GP_P, radEquator, radRatio): """ This method receives a cartesian point above a reference ellipsoid with equatorial radius and flattening ratio, then converts to lat/lon/alt. Parameters ---------- r_GP_P: [m] position vector of the location G relative to the parent body radEquator: [m] equatorial radius of the parent body radRatio: ratio of polar radius to equatorial radius Returns ------- 3-element list [rad,rad,m] lla_GP, position vector of the location G relative to parent body frame P in lat/lon/alt """ X = r_GP_P[0] Y = r_GP_P[1] Z = r_GP_P[2] a = radEquator b = radEquator * radRatio e2 = 1 - (b / a) ** 2 # First eccentricity squared ep2 = (a ** 2 - b ** 2) / b ** 2 # Second eccentricity squared r = np.sqrt(X ** 2 + Y ** 2) lon = np.arctan2(Y, X) theta = np.arctan2(Z * a, r * b) stheta = np.sin(theta) ctheta = np.cos(theta) lat = np.arctan2(Z + ep2 * b * stheta ** 3, r - e2 * a * ctheta ** 3) N = a / np.sqrt(1 - e2 * np.sin(lat) ** 2) h = r / np.cos(lat) - N lla_GP = [lat, lon, h] return lla_GP
locationList = []
[docs] def addLocation(viz, **kwargs): """ This method creates a Location instance on a parent body. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ stationName: str Location text label Required parentBodyName: str Name of the parent body P (spacecraft or planet) on which the location G is positioned. Required r_GP_P: 3-element double-list Position of G relative to parent body frame P. Required, if lla_GP not provided lla_GP: 3-element double-list Position of G relative to parent body in lat/lon/alt coordinates. Required, if r_GP_P not provided ghat_P: 3-element double-list Location normal relative to parent body frame. Required fieldOfView: double [rad] FOV angle measured edge-to-edge. Required color: int-list Color of the Location. Can be 4 RGBA integer value (0-255) or a color string. Required range: double [m] Range of the ground Location. Required markerScale: double Value will be multiplied by default marker scale, values less than 1.0 will decrease size, greater will increase. Optional """ if not vizFound: print('vizFound is false. Skipping this method.') return vizElement = vizInterface.LocationPbMsg() unitTestSupport.checkMethodKeyword( ['stationName', 'parentBodyName', 'r_GP_P', 'lla_GP', 'gHat_P', 'fieldOfView', 'color', 'range'], kwargs) if 'stationName' in kwargs: stationName = kwargs['stationName'] if not isinstance(stationName, str): print('ERROR: stationName must be a string') exit(1) vizElement.stationName = stationName else: print("ERROR: stationName argument must be provided to addLocation") exit(0) if 'parentBodyName' in kwargs: parentBodyName = kwargs['parentBodyName'] if not isinstance(parentBodyName, str): print('ERROR: parentBodyName must be a string') exit(1) vizElement.parentBodyName = parentBodyName else: print("ERROR: parentBodyName argument must be provided to addLocation") exit(1) if 'r_GP_P' in kwargs: r_GP_P = kwargs['r_GP_P'] if not isinstance(r_GP_P, list): print('ERROR: r_GP_P must be a list of floats') print(r_GP_P) exit(1) if len(r_GP_P) != 3: print('ERROR: r_GP_P must be list of three floats') exit(1) try: # check if vector is a list vizElement.r_GP_P = r_GP_P except TypeError: try: # convert Eigen array to list vizElement.r_GP_P = unitTestSupport.EigenVector3d2np(r_GP_P).tolist() except TypeError: pass elif 'lla_GP' in kwargs: lla_GP = kwargs['lla_GP'] if not isinstance(lla_GP, list): print('ERROR: lla_GP must be a list of floats') print(lla_GP) exit(1) if len(lla_GP) != 3: print('ERROR: lla_GP must be a list of three floats') exit(1) if lla_GP[0] > np.pi/2 or lla_GP[0] < -np.pi/2: print('ERROR: Latitude must be between -pi/2 and pi/2 radians') print(lla_GP) exit(1) # find gravity body gravBody = next((s for s in viz.gravBodyInformation if s.bodyName == parentBodyName), None) if gravBody is None: print(f'ERROR: Cannot use LLA to set location for {parentBodyName}') exit(1) # convert lat/lon/altitude to fixed frame r_GP_P = lla2fixedframe(lla_GP, gravBody.radEquator, gravBody.radiusRatio) vizElement.r_GP_P = r_GP_P else: print("ERROR: r_GP_P or lla_GP argument must be provided to addLocation") exit(0) if 'gHat_P' in kwargs: gHat_P = kwargs['gHat_P'] if not isinstance(gHat_P, list): print('ERROR: gHat_P must be a list of three floats') exit(1) if len(gHat_P) != 3: print('ERROR: gHat_P must be list of three floats') exit(1) vizElement.gHat_P = gHat_P else: vizElement.gHat_P = r_GP_P / np.linalg.norm(r_GP_P) if 'fieldOfView' in kwargs: fieldOfView = kwargs['fieldOfView'] if not isinstance(fieldOfView, float): print('ERROR: fieldOfView must be a float value in radians') exit(1) if fieldOfView > np.pi or fieldOfView < 0.0: print('ERROR: fieldOfView must be a value between 0 and Pi') exit(1) vizElement.fieldOfView = fieldOfView if 'color' in kwargs: color = kwargs['color'] vizElement.color = toRGBA255(color) if 'range' in kwargs: rangeParam = kwargs['range'] if not isinstance(rangeParam, float): print('ERROR: range must be a float') exit(1) vizElement.range = rangeParam locationList.append(vizElement) del viz.locations[:] # clear settings list to replace it with updated list viz.locations = vizInterface.LocationConfig(locationList) return
quadMapList = []
[docs] def addQuadMap(viz, **kwargs): """ This method creates a QuadMap element for displaying shaded regions in Vizard. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ ID: int The reference ID of the QuadMap instance. Once instantiated, can be used to change the QuadMap settings. Required parentBodyName: str Name of the parent body to draw the QuadMap in reference to. Required vertices: single or double-list Specifies the internal mesh coordinates of the QuadMap, in body-fixed frame. Required color: int list Color of the QuadMap. Can be 4 RGBA integer value (0-255) or a color string. Required isHidden: bool Flag if the QuadMap should be hidden (1) or shown (-1). Optional. Default: 0 - if not provided, then the Vizard default settings are used. label: str Label to display in the center of QuadMap region. Optional. Send "NOLABEL" to delete label. """ if not vizFound: print('vizFound is false. Skipping this method.') return vizElement = vizInterface.QuadMap() unitTestSupport.checkMethodKeyword( ['ID', 'parentBodyName', 'vertices', 'color', 'isHidden', 'label'], kwargs) if 'ID' in kwargs: ID = kwargs['ID'] if not isinstance(ID, int): print('ERROR: ID must be an integer') exit(1) vizElement.ID = ID else: print("ERROR: ID argument must be provided to addQuadMap") exit(1) if 'parentBodyName' in kwargs: parentBodyName = kwargs['parentBodyName'] if not isinstance(parentBodyName, str): print('ERROR: parentBodyName must be a string') exit(1) vizElement.parentBodyName = parentBodyName else: print("ERROR: parentBodyName argument must be provided to addQuadMap") exit(1) if 'vertices' in kwargs: vertices = kwargs['vertices'] if not isinstance(vertices, list): print('ERROR: vertices must be a list of floats') exit(1) if len(vertices) % 4 != 0: print('ERROR: vertices must be list of floats with length divisible by four') exit(1) vizElement.vertices = vizInterface.DoubleVector(vertices) else: print('ERROR: vertices argument must be provided to addQuadMap') exit(1) if 'color' in kwargs: color = kwargs['color'] vizElement.color = vizInterface.IntVector(toRGBA255(color)) else: print('ERROR: color argument must be provided to addQuadMap') exit(1) if 'isHidden' in kwargs: isHidden = kwargs['isHidden'] if not isinstance(isHidden, bool): print('Error: isHidden must be boolean') exit(1) vizElement.isHidden = isHidden if 'label' in kwargs: label = kwargs['label'] if not isinstance(label, str): print('Error: label must be a string') exit(1) vizElement.label = label quadMapList.append(vizElement) del viz.quadMaps[:] # clear settings list to replace it with updated list viz.quadMaps = vizInterface.QuadMapVector(quadMapList) return
pointLineList = []
[docs] def createPointLine(viz, **kwargs): """ This method creates a PointLine between two bodies. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ fromBodyName: str Body from which PointLine originates. Optional, default selects ``firstSpacecraftName`` toBodyName: str Body which the PointLine points to. Required lineColor: int list Color of the PointLine. Can be 4 RGBA integer value (0-255) or a color string. Required """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.PointLine() unitTestSupport.checkMethodKeyword( ['fromBodyName', 'toBodyName', 'lineColor'], kwargs) if 'fromBodyName' in kwargs: fromName = kwargs['fromBodyName'] if not isinstance(fromName, str): print('ERROR: vizSupport: fromBodyName must be a string') exit(1) vizElement.fromBodyName = fromName else: vizElement.fromBodyName = firstSpacecraftName if 'toBodyName' in kwargs: toName = kwargs['toBodyName'] if not isinstance(toName, str): print('ERROR: vizSupport: toBodyName must be a string') exit(1) vizElement.toBodyName = toName else: print('ERROR: vizSupport: toBodyName must be a specified') exit(1) if 'lineColor' in kwargs: vizElement.lineColor = toRGBA255(kwargs['lineColor']) else: print('ERROR: vizSupport: lineColor must be a specified') exit(1) pointLineList.append(vizElement) del viz.settings.pointLineList[:] # clear settings list to replace it with updated list viz.settings.pointLineList = vizInterface.PointLineConfig(pointLineList) return
targetLineList = []
[docs] def createTargetLine(viz, **kwargs): """ This method creates a TargetLine between two bodies. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ fromBodyName: str Body from which PointLine originates. Optional, default selects ``firstSpacecraftName`` toBodyName: str Body which the PointLine points to. Required lineColor: int list Color of the PointLine. Can be 4 RGBA integer value (0-255) or a color string. Required """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.PointLine() unitTestSupport.checkMethodKeyword( ['fromBodyName', 'toBodyName', 'lineColor'], kwargs) if 'fromBodyName' in kwargs: fromName = kwargs['fromBodyName'] if not isinstance(fromName, str): print('ERROR: vizSupport: fromBodyName must be a string') exit(1) vizElement.fromBodyName = fromName else: vizElement.fromBodyName = firstSpacecraftName if 'toBodyName' in kwargs: toName = kwargs['toBodyName'] if not isinstance(toName, str): print('ERROR: vizSupport: toBodyName must be a string') exit(1) vizElement.toBodyName = toName else: print('ERROR: vizSupport: toBodyName must be a specified') exit(1) if 'lineColor' in kwargs: vizElement.lineColor = toRGBA255(kwargs['lineColor']) else: print('ERROR: vizSupport: lineColor must be a specified') exit(1) targetLineList.append(vizElement) updateTargetLineList(viz) return
def updateTargetLineList(viz): del viz.liveSettings.targetLineList[:] # clear settings list to replace it with updated list viz.liveSettings.targetLineList = vizInterface.PointLineConfig(targetLineList) return customModelList = []
[docs] def createCustomModel(viz, **kwargs): """ This method creates a CustomModel. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ modelPath: str Path to model obj -OR- ``CUBE``, ``CYLINDER``, or ``SPHERE`` to use a primitive shape Required simBodiesToModify: list Which bodies in scene to replace with this model, use ``ALL_SPACECRAFT`` to apply custom model to all spacecraft in simulation Optional, default modifies ``firstSpacecraftName`` offset: 3-element double-list [m] Offset to use to draw the model Optional, default is [0.0, 0.0, 0.0] rotation: 3-element double-list [rad] 3-2-1 Euler angles to rotate CAD about z, y, x axes Optional, default is [0.0, 0.0, 0.0] scale: 3-element double-list Desired model scaling factor along the body x, y, z, axes in spacecraft CS Optional, default is [1.0, 1.0, 1.0] customTexturePath: str Path to texture to apply to model (note that a custom model's .mtl will be automatically imported with its textures during custom model import) Optional normalMapPath: str Path to the normal map for the customTexture Optional shader: int Value of -1 to use viz default, 0 for Unity Specular Standard Shader, 1 for Unity Standard Shader Optional color: int list Send desired RGBA as values between 0 and 255, default is gray, and will be applied to the albedo color setting Optional """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.CustomModel() unitTestSupport.checkMethodKeyword( ['modelPath', 'simBodiesToModify', 'offset', 'rotation', 'scale', 'customTexturePath', 'normalMapPath', 'shader', 'color'], kwargs) if 'modelPath' in kwargs: modelPathName = kwargs['modelPath'] if not isinstance(modelPathName, str): print('ERROR: vizSupport: modelPath must be a string') exit(1) if len(modelPathName) == 0: print('ERROR: vizSupport: modelPath is required and must be specified.') exit(1) vizElement.modelPath = modelPathName else: print('ERROR: vizSupport: modelPath is required and must be specified.') exit(1) if 'simBodiesToModify' in kwargs: simBodiesList = kwargs['simBodiesToModify'] if not isinstance(simBodiesList, list): print('ERROR: vizSupport: simBodiesToModify must be a list of strings') exit(1) if len(simBodiesList) == 0: print('ERROR: vizSupport: simBodiesToModify must be a non-empty list of strings') exit(1) for item in simBodiesList: if not isinstance(item, str): print('ERROR: vizSupport: the simBody name must be a string, not ' + str(item)) exit(1) vizElement.simBodiesToModify = vizInterface.StringVector(simBodiesList) else: vizElement.simBodiesToModify = vizInterface.StringVector([firstSpacecraftName]) if 'offset' in kwargs: offsetVariable = kwargs['offset'] if not isinstance(offsetVariable, list): print('ERROR: vizSupport: offset must be a list of three floats') exit(1) if len(offsetVariable) != 3: print('ERROR: vizSupport: offset must be list of three floats') exit(1) vizElement.offset = offsetVariable else: vizElement.offset = [0.0, 0.0, 0.0] if 'rotation' in kwargs: rotationVariable = kwargs['rotation'] if not isinstance(rotationVariable, list): print('ERROR: vizSupport: rotation must be a list of three floats') exit(1) if len(rotationVariable) != 3: print('ERROR: vizSupport: rotation must be list of three floats') exit(1) vizElement.rotation = rotationVariable else: vizElement.rotation = [0.0, 0.0, 0.0] if 'scale' in kwargs: scaleVariable = kwargs['scale'] if not isinstance(scaleVariable, list): print('ERROR: vizSupport: scale must be a list of three floats') exit(1) if len(scaleVariable) != 3: print('ERROR: vizSupport: scale must be list of three floats') exit(1) vizElement.scale = scaleVariable else: vizElement.scale = [1.0, 1.0, 1.0] if 'customTexturePath' in kwargs: customTexturePathName = kwargs['customTexturePath'] if not isinstance(customTexturePathName, str): print('ERROR: vizSupport: customTexturePath must be a string') exit(1) vizElement.customTexturePath = customTexturePathName else: vizElement.customTexturePath = "" if 'normalMapPath' in kwargs: normalMapPathName = kwargs['normalMapPath'] if not isinstance(normalMapPathName, str): print('ERROR: vizSupport: normalMapPath must be a string') exit(1) vizElement.normalMapPath = normalMapPathName else: vizElement.normalMapPath = "" if 'shader' in kwargs: shaderVariable = kwargs['shader'] if not isinstance(shaderVariable, int): print('ERROR: vizSupport: shader must be a an integer.') exit(1) if abs(shaderVariable) > 1: print('ERROR: vizSupport: shader must have a value of -1, 0 or +1.') exit(1) vizElement.shader = shaderVariable if 'color' in kwargs: colorVariable = kwargs['color'] if not isinstance(colorVariable, list): print('ERROR: vizSupport: color must be a list of 4 integers') exit(1) if len(colorVariable) != 4: print('ERROR: vizSupport: offset must be list of 4 integers') exit(1) vizElement.color = vizInterface.IntVector(colorVariable) customModelList.append(vizElement) del viz.settings.customModelList[:] # clear settings list to replace it with updated list viz.settings.customModelList = vizInterface.CustomModelConfig(customModelList) return
actuatorGuiSettingList = []
[docs] def setActuatorGuiSetting(viz, **kwargs): """ This method sets the actuator GUI properties for a particular spacecraft. If no ``spacecraftName`` is provided, then the name of the first spacecraft in the simulation is assumed. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ spacecraftName: str The name of the spacecraft for which the actuator GUI options are set. Default: If not provided, then the name of the first spacecraft in the simulation is used. viewThrusterPanel: bool flag if the GUI panel should be shown illustrating the thruster states Default: if not provided, then the Vizard default settings are used viewRWPanel: bool flag if the GUI panel should be shown illustrating the reaction wheel states Default: if not provided, then the Vizard default settings are used viewThrusterHUD: bool flag if the HUD visualization of the thruster states should be shown Default: if not provided, then the Vizard default settings are used viewRWHUD: bool flag if the HUD visualization of the reaction wheel states should be shown Default: if not provided, then the Vizard default settings are used showThrusterLabels: bool flag if the thruster labels should be shown Default: if not provided, then the Vizard default settings are used showRWLabels: bool flag if the reaction wheel labels should be shown Default: if not provided, then the Vizard default settings are used """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.ActuatorGuiSettings() unitTestSupport.checkMethodKeyword( ['spacecraftName', 'viewThrusterPanel', 'viewThrusterHUD', 'viewRWPanel', 'viewRWHUD', 'showThrusterLabels', 'showRWLabels'], kwargs) if 'spacecraftName' in kwargs: scName = kwargs['spacecraftName'] if not isinstance(scName, str): print('ERROR: vizSupport: spacecraftName must be a string') exit(1) vizElement.spacecraftName = scName else: vizElement.spacecraftName = firstSpacecraftName if 'viewThrusterPanel' in kwargs: setting = kwargs['viewThrusterPanel'] if not isinstance(setting, bool): print('ERROR: vizSupport: viewThrusterPanel must be True or False') exit(1) vizElement.viewThrusterPanel = setting if 'viewThrusterHUD' in kwargs: setting = kwargs['viewThrusterHUD'] if not isinstance(setting, bool): print('ERROR: vizSupport: viewThrusterHUD must be True or False') exit(1) vizElement.viewThrusterHUD = setting if 'viewRWPanel' in kwargs: setting = kwargs['viewRWPanel'] if not isinstance(setting, bool): print('ERROR: vizSupport: viewRWPanel must be True or False') exit(1) vizElement.viewRWPanel = setting if 'viewRWHUD' in kwargs: setting = kwargs['viewRWHUD'] if not isinstance(setting, bool): print('ERROR: vizSupport: viewRWHUD must be True or False') exit(1) vizElement.viewRWHUD = setting if 'showThrusterLabels' in kwargs: setting = kwargs['showThrusterLabels'] if not isinstance(setting, bool): print('ERROR: vizSupport: showThrusterLabels must be True or False') exit(1) vizElement.showThrusterLabels = setting if 'showRWLabels' in kwargs: setting = kwargs['showRWLabels'] if not isinstance(setting, bool): print('ERROR: vizSupport: showRWLabels must be an True or False') exit(1) vizElement.showRWLabels = setting actuatorGuiSettingList.append(vizElement) del viz.settings.actuatorGuiSettingsList[:] # clear settings list to replace it with updated list viz.settings.actuatorGuiSettingsList = vizInterface.ActuatorGuiSettingsConfig(actuatorGuiSettingList) return
instrumentGuiSettingList = []
[docs] def setInstrumentGuiSetting(viz, **kwargs): """ This method sets the instrument GUI properties for a particular spacecraft. If no ``spacecraftName`` is provided, then the name of the first spacecraft in the simulation is assumed. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ spacecraftName: str The name of the spacecraft for which the actuator GUI options are set. Default: 0 - If not provided, then the name of the first spacecraft in the simulation is used. viewCSSPanel: int flag if the GUI panel should be shown (1) or hidden (-1) illustrating the CSS states Default: 0 - if not provided, then the Vizard default settings are used viewCSSCoverage: int flag if the HUD spherical coverage of the CSS states should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used viewCSSBoresight: int flag if the HUD boresight axes of the CSS states should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showCSSLabels: int flag if the CSS labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showGenericSensorLabels: int flag if the generic sensor labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showTransceiverLabels: int flag if the generic sensor labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showTransceiverFrustrum: int flag if the generic sensor labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showGenericStoragePanel: int flag if the generic sensor labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used showMultiShapeLabels: int flag if the generic sensor labels should be shown (1) or hidden (-1) Default: 0 - if not provided, then the Vizard default settings are used """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.InstrumentGuiSettings() unitTestSupport.checkMethodKeyword( ['spacecraftName', 'viewCSSPanel', 'viewCSSCoverage', 'viewCSSBoresight', 'showCSSLabels', 'showGenericSensorLabels', 'showTransceiverLabels', 'showTransceiverFrustrum', 'showGenericStoragePanel', 'showMultiShapeLabels'], kwargs) if 'spacecraftName' in kwargs: scName = kwargs['spacecraftName'] if not isinstance(scName, str): print('ERROR: vizSupport: spacecraftName must be a string') exit(1) vizElement.spacecraftName = scName else: vizElement.spacecraftName = firstSpacecraftName if 'viewCSSPanel' in kwargs: setting = kwargs['viewCSSPanel'] if not isinstance(setting, int): print('ERROR: vizSupport: viewCSSPanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: viewCSSPanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.viewCSSPanel = setting print(vizElement.viewCSSPanel) if 'viewCSSCoverage' in kwargs: setting = kwargs['viewCSSCoverage'] if not isinstance(setting, int): print('ERROR: vizSupport: viewCSSCoverage must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: viewCSSPanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.viewCSSCoverage = setting if 'viewCSSBoresight' in kwargs: setting = kwargs['viewCSSBoresight'] if not isinstance(setting, int): print('ERROR: vizSupport: viewCSSBoresight must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: viewCSSPanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.viewCSSBoresight = setting if 'showCSSLabels' in kwargs: setting = kwargs['showCSSLabels'] if not isinstance(setting, int): print('ERROR: vizSupport: showCSSLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: viewCSSPanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showCSSLabels = setting if 'showGenericSensorLabels' in kwargs: setting = kwargs['showGenericSensorLabels'] if not isinstance(setting, int): print('ERROR: vizSupport: showGenericSensorLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: showGenericSensorLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showGenericSensorLabels = setting if 'showTransceiverLabels' in kwargs: setting = kwargs['showTransceiverLabels'] if not isinstance(setting, int): print('ERROR: vizSupport: showTransceiverLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: showTransceiverLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showTransceiverLabels = setting if 'showTransceiverFrustrum' in kwargs: setting = kwargs['showTransceiverFrustrum'] if not isinstance(setting, int): print('ERROR: vizSupport: showTransceiverFrustrum must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: showTransceiverFrustrum must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showTransceiverFrustrum = setting if 'showGenericStoragePanel' in kwargs: setting = kwargs['showGenericStoragePanel'] if not isinstance(setting, int): print('ERROR: vizSupport: showGenericStoragePanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: showGenericStoragePanel must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showGenericStoragePanel = setting if 'showMultiShapeLabels' in kwargs: setting = kwargs['showMultiShapeLabels'] if not isinstance(setting, int): print('ERROR: vizSupport: showMultiShapeLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) if setting is False: setting = -1 if setting*setting > 1: print('ERROR: vizSupport: showMultiShapeLabels must be -1 (Off), 0 (default) or 1 (On)') exit(1) vizElement.showMultiShapeLabels = setting instrumentGuiSettingList.append(vizElement) del viz.settings.instrumentGuiSettingsList[:] # clear settings list to replace it with updated list viz.settings.instrumentGuiSettingsList = vizInterface.InstrumentGuiSettingsConfig(instrumentGuiSettingList) return
coneInOutList = []
[docs] def createConeInOut(viz, **kwargs): """ This method creates a ``KeepOutInCone``. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: void Keyword Args ------------ fromBodyName: str Name of body to attach cone onto. Optional, default selects ``firstSpacecraftName`` toBodyName: str Detect changes if this body has impingement on cone. Required coneColor: int list Color of the KeepOutInCone. Can be 4 RGBA integer value (0-255) or a color string. Required isKeepIn: bool True -> keep-in cone created, False -> keep-out cone created Required position_B: 3-element double-list [m] Cone start relative to from-body coordinate frame. Optional, default [0.0, 0.0, 0.0] normalVector_B: 3-element double-list Cone normal direction vector Required incidenceAngle: double [rad] Cone incidence angle Required coneHeight: double [m] Sets height of visible cone (aesthetic only, does not impact function) Required coneName: str Cone name, if unspecified, viz will autogenerate name Optional """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName vizElement = vizInterface.KeepOutInCone() unitTestSupport.checkMethodKeyword( ['fromBodyName', 'toBodyName', 'coneColor', 'isKeepIn', 'position_B', 'normalVector_B', 'incidenceAngle', 'coneHeight', 'coneName'], kwargs) if 'fromBodyName' in kwargs: fromName = kwargs['fromBodyName'] if not isinstance(fromName, str): print('ERROR: vizSupport: fromBodyName must be a string') exit(1) vizElement.fromBodyName = fromName else: vizElement.fromBodyName = firstSpacecraftName if 'toBodyName' in kwargs: toName = kwargs['toBodyName'] if not isinstance(toName, str): print('ERROR: vizSupport: toBodyName must be a string') exit(1) vizElement.toBodyName = toName else: print('ERROR: vizSupport: toBodyName must be a specified') exit(1) if 'coneColor' in kwargs: vizElement.coneColor = toRGBA255(kwargs['coneColor']) else: print('ERROR: vizSupport: coneColor must be a specified') exit(1) if 'isKeepIn' in kwargs: keepInFlag = kwargs['isKeepIn'] if not isinstance(keepInFlag, bool): print('ERROR: vizSupport: isKeepIn must be a BOOL') exit(1) vizElement.isKeepIn = keepInFlag else: print('ERROR: vizSupport: isKeepIn must be a specified') exit(1) if 'position_B' in kwargs: pos_B = kwargs['position_B'] if not isinstance(pos_B, list): print('ERROR: vizSupport: position_B must be a 3D array of doubles') exit(1) vizElement.position_B = pos_B else: vizElement.position_B = [0.0, 0.0, 0.0] if 'normalVector_B' in kwargs: n_B = kwargs['normalVector_B'] if not isinstance(n_B, list): print('ERROR: vizSupport: normalVector_B must be a 3D array of doubles') exit(1) vizElement.normalVector_B = n_B else: print('ERROR: vizSupport: normalVector_B must be a specified') exit(1) if 'incidenceAngle' in kwargs: angle = kwargs['incidenceAngle'] if not isinstance(angle, float): print('ERROR: vizSupport: incidenceAngle must be a float value in radians') exit(1) vizElement.incidenceAngle = angle else: print('ERROR: vizSupport: incidenceAngle must be a specified') exit(1) if 'coneHeight' in kwargs: height = kwargs['coneHeight'] if not isinstance(height, float): print('ERROR: vizSupport: coneHeight must be a float value') exit(1) vizElement.coneHeight = height else: print('ERROR: vizSupport: coneHeight must be a specified') exit(1) if 'coneName' in kwargs: coneName = kwargs['coneName'] if not isinstance(coneName, str): print('ERROR: vizSupport: coneName must be a string') exit(1) vizElement.coneName = coneName else: vizElement.coneName = "" coneInOutList.append(vizElement) del viz.settings.coneList[:] # clear settings list to replace it with updated list viz.settings.coneList = vizInterface.KeepOutInConeConfig(coneInOutList) return
stdCameraList = []
[docs] def createStandardCamera(viz, **kwargs): """ This method creates a Standard Camera. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: camera instance Keyword Args ------------ spacecraftName: str Name of spacecraft to attach camera onto. Optional, default selects ``firstSpacecraftName`` setMode: int 0 -> body targeting, 1 -> pointing vector (default). Optional setView: int 0 -> nadir (default), 1 -> orbit normal, 2 -> along track. This is a setting for body targeting mode. Optional fieldOfView: double [rad] FOV angle measured edge-to-edge, -1 to use viz default. Optional bodyTarget: str Name of body camera should point to (default to first celestial body in messages). This is a setting for body targeting mode. Optional pointingVector_B: 3-element double-list Camera pointing vector in the spacecraft body frame. Optional, default [1.0, 0.0, 0.0] position_B: 3-element double-list If a non-zero vector, this determines the location of the camera. If a zero vector, then the camera is placed outside the spacecraft along the pointing vector direction. Optional, default [0.0, 0.0, 0.0] displayName: str Name of the standard camera panel. Optional """ if not vizFound: print('vizFound is false. Skipping this method.') return cam = vizInterface.StdCameraSettings() unitTestSupport.checkMethodKeyword( ['spacecraftName', 'setMode', 'setView', 'fieldOfView', 'bodyTarget', 'pointingVector_B', 'position_B', 'displayName'], kwargs) if 'spacecraftName' in kwargs: scName = kwargs['spacecraftName'] if not isinstance(scName, str): print('ERROR: vizSupport: spacecraftName must be a string, you provided ' + str(scName)) exit(1) cam.spacecraftName = scName else: cam.spacecraftName = firstSpacecraftName if 'setMode' in kwargs: setMode = kwargs['setMode'] if not isinstance(setMode, int): print('ERROR: vizSupport: setMode must be an integer') exit(1) if setMode < 0 or setMode > 2: print('ERROR: vizSupport: setMode must be a 0 (body targeting) or 1 (pointing vector)') exit(1) cam.setMode = setMode if 'setView' in kwargs: setView = kwargs['setView'] if cam.setMode == 1: print('ERROR: vizSupport: setView does not apply to pointing vector mode.') exit(1) if not isinstance(setView, int): print('ERROR: vizSupport: setView must be an integer') exit(1) if setView < 0 or setView > 2: print('ERROR: vizSupport: setView must be a number of [0,2]') print('0 -> Nadir, 1 -> Orbit Normal, 2 -> Along Track (default to nadir). ' 'This is a setting for body targeting mode.') exit(1) cam.setView = setView if 'fieldOfView' in kwargs: fieldOfView = kwargs['fieldOfView'] if not isinstance(fieldOfView, float): print('ERROR: vizSupport: spacecraftVisible must be a float in radians') exit(1) cam.fieldOfView = fieldOfView if 'bodyTarget' in kwargs: if cam.setMode == 1: print('ERROR: vizSupport: bodyTarget does not apply in pointing vector mode') exit(1) bodyTargetName = kwargs['bodyTarget'] if not isinstance(bodyTargetName, str): print('ERROR: vizSupport: targetBodyName must be a string') exit(1) cam.bodyTarget = bodyTargetName else: cam.bodyTarget = "" if 'pointingVector_B' in kwargs: if cam.setMode == 0: print('ERROR: vizSupport: pointingVector_B does not apply in body pointing mode') exit(1) pointingVector_B = kwargs['pointingVector_B'] if not isinstance(pointingVector_B, list): print('ERROR: vizSupport: pointingVector_B must be a 3D array of doubles') exit(1) if len(pointingVector_B) != 3: print('ERROR: vizSupport: pointingVector_B must be 3D list') exit(1) cam.pointingVector_B = pointingVector_B else: cam.pointingVector_B = [1.0, 0.0, 0.0] if 'position_B' in kwargs: position_B = kwargs['position_B'] if len(position_B) != 3: print('ERROR: vizSupport: position_B must be 3D list of float values') exit(1) cam.position_B = position_B else: cam.position_B = [0, 0, 0] if 'displayName' in kwargs: displayName = kwargs['displayName'] if not isinstance(displayName, str): print('ERROR: vizSupport: createStandardCamera: displayName must be a string') exit(1) cam.displayName = displayName stdCameraList.append(cam) del viz.settings.stdCameraList[:] # clear settings list to replace it with updated list viz.settings.stdCameraList = vizInterface.StdCameraConfig(stdCameraList) return cam
[docs] def createCameraConfigMsg(viz, **kwargs): """ This method configures camera settings. :param viz: copy of the vizInterface module :param kwargs: list of keyword arguments that this method supports :return: camera instance Keyword Args ------------ cameraID: int ID of the camera that took the snapshot. Required parentName: str Name of the parent body to which the camera should be attached Optional, default is ``firstSpacecraftName`` fieldOfView: double [rad] Camera FOV, edge-to-edge along camera y-axis. Required resolution: 2-element int-list Camera resolution, width/height in pixels. Required renderRate: int [ns] Frame time interval at which to capture images. Optional cameraPos_B: 3-element double-list [m] Camera position in body frame. Required sigma_CB: 3-element double-list MRP defining the orientation of the camera frame relative to the body frame. Required skyBox: str String containing the star field preference. Optional postProcessingOn: int Enable post-processing of camera image. Value of 0 (protobuffer default) to use viz default which is off, -1 for false, 1 for true. Optional ppFocusDistance: double Distance to the point of focus, minimum value of 0.1, Value of 0 to turn off this parameter entirely. Optional ppAperature: double Ratio of the aperture (known as f-stop or f-number). The smaller the value is, the shallower the depth of field is. Valid Setting Range: 0.05 to 32. Value of 0 to turn off this parameter entirely. Optional ppFocalLength: double Valid setting range: 0.001m to 0.3m. Value of 0 to turn off this parameter entirely. Optional ppMaxBlurSize: int Convolution kernel size of the bokeh filter, which determines the maximum radius of bokeh. It also affects the performance (the larger the kernel is, the longer the GPU time is required). Depth textures Value of 1 for Small, 2 for Medium, 3 for Large, 4 for Extra Large. Value of 0 to turn off this parameter entirely. Optional updateCameraParameters: int If true, commands camera to update Instrument Camera to current message's parameters. Optional renderMode: int Value of 0 to render visual image (default), value of 1 to render depth buffer to image. Optional depthMapClippingPlanes: 2-element double-list [m] Set the bounds of rendered depth map by setting the near and far clipping planes when in renderMode=1 (depthMap mode). Default values of 0.1 and 100. Optional """ if not vizFound: print('vizFound is false. Skipping this method.') return global firstSpacecraftName unitTestSupport.checkMethodKeyword( ['cameraID', 'parentName', 'fieldOfView', 'resolution', 'renderRate', 'cameraPos_B', 'sigma_CB', 'skyBox', 'postProcessingOn', 'ppFocusDistance', 'ppAperture', 'ppFocalLength', 'ppMaxBlurSize', 'updateCameraParameters', 'renderMode', 'depthMapClippingPlanes'], kwargs) cameraConfigMsgPayload = messaging.CameraConfigMsgPayload() if 'cameraID' in kwargs: val = kwargs['cameraID'] if not isinstance(val, int) or val < 0: print('ERROR: vizSupport: cameraID must be non-negative integer value.') exit(1) cameraConfigMsgPayload.cameraID = val else: print('ERROR: vizSupport: cameraID must be defined in createCameraConfigMsg()') exit(1) if 'parentName' in kwargs: val = kwargs['parentName'] if not isinstance(val, str): print('ERROR: vizSupport: parentName must be a string') exit(1) cameraConfigMsgPayload.parentName = val else: cameraConfigMsgPayload.parentName = firstSpacecraftName if 'fieldOfView' in kwargs: val = kwargs['fieldOfView'] if not isinstance(val, float): print('ERROR: vizSupport: fieldOfView must be a float in radians') exit(1) cameraConfigMsgPayload.fieldOfView = val else: print('ERROR: vizSupport: fieldOfView must be defined in createCameraConfigMsg()') exit(1) if 'resolution' in kwargs: val = kwargs['resolution'] if not isinstance(val, list): print('ERROR: vizSupport: resolution must be a list') exit(1) if len(val) != 2: print('ERROR: vizSupport: resolution list ' + str(val) + 'must be of length 2') exit(1) if not isinstance(val[0], int) or not isinstance(val[1], int): print('ERROR: vizSupport: resolution list ' + str(val) + ' must contain integers') exit(1) cameraConfigMsgPayload.resolution = val else: print('ERROR: vizSupport: resolution must be defined in createCameraConfigMsg()') exit(1) if 'renderRate' in kwargs: val = kwargs['renderRate'] if not isinstance(val, float) or val < 0: print('ERROR: vizSupport: renderRate ' + str(val) + ' must be positive float value in units of seconds.') exit(1) cameraConfigMsgPayload.renderRate = int(val * 1e9) # convert to nano-seconds if 'cameraPos_B' in kwargs: val = kwargs['cameraPos_B'] if not isinstance(val, list): print('ERROR: vizSupport: cameraPos_B must be a list') exit(1) if len(val) != 3: print('ERROR: vizSupport: cameraPos_B list ' + str(val) + 'must be of length 3') exit(1) if not isinstance(val[0], float) or not isinstance(val[1], float) or not isinstance(val[2], float): print('ERROR: vizSupport: cameraPos_B list ' + str(val) + ' must contain floats') exit(1) cameraConfigMsgPayload.cameraPos_B = val else: print('ERROR: vizSupport: cameraPos_B must be defined in createCameraConfigMsg()') exit(1) if 'sigma_CB' in kwargs: val = kwargs['sigma_CB'] if not isinstance(val, list): print('ERROR: vizSupport: sigma_CB must be a list') exit(1) if len(val) != 3: print('ERROR: vizSupport: sigma_CB list ' + str(val) + 'must be of length 3') exit(1) if not isinstance(val[0], float) or not isinstance(val[1], float) or not isinstance(val[2], float): print('ERROR: vizSupport: sigma_CB list ' + str(val) + ' must contain floats') exit(1) cameraConfigMsgPayload.sigma_CB = val else: print('ERROR: vizSupport: sigma_CB must be defined in createCameraConfigMsg()') exit(1) if 'skyBox' in kwargs: val = kwargs['skyBox'] if not isinstance(val, str): print('ERROR: vizSupport: skyBox must be a string') exit(1) cameraConfigMsgPayload.skyBox = val else: cameraConfigMsgPayload.skyBox = "" if 'postProcessingOn' in kwargs: val = kwargs['postProcessingOn'] if not isinstance(val, int) or val < 0: print('ERROR: vizSupport: postProcessingOn must be non-negative integer value.') exit(1) cameraConfigMsgPayload.postProcessingOn = val if 'ppFocusDistance' in kwargs: val = kwargs['ppFocusDistance'] if not isinstance(val, float) or val < 0: print('ERROR: vizSupport: ppFocusDistance ' + str(val) + ' must be 0 or greater than 0.1.') exit(1) cameraConfigMsgPayload.ppFocusDistance = int(val) if 'ppAperture' in kwargs: val = kwargs['ppAperture'] if not isinstance(val, float) or val < 0 or val > 32: print('ERROR: vizSupport: ppAperture ' + str(val) + ' must be 0 or with [0.05, 32].') exit(1) cameraConfigMsgPayload.ppAperture = int(val) if 'ppFocalLength' in kwargs: val = kwargs['ppFocalLength'] if not isinstance(val, float) or val < 0 or val > 0.3: print('ERROR: vizSupport: ppFocalLength ' + str(val) + ' must be 0 or with [0.001, 0.3] meters.') exit(1) cameraConfigMsgPayload.ppFocalLength = int(val) if 'ppMaxBlurSize' in kwargs: val = kwargs['ppMaxBlurSize'] if not isinstance(val, int) or val < 0 or val > 4: print('ERROR: vizSupport: ppMaxBlurSize must be non-negative integer value between [0, 4].') exit(1) cameraConfigMsgPayload.ppMaxBlurSize = val if 'updateCameraParameters' in kwargs: val = kwargs['updateCameraParameters'] if not isinstance(val, int) or val < 0 or val > 1: print('ERROR: vizSupport: updateCameraParameters must be 0 or 1.') exit(1) cameraConfigMsgPayload.cameraID = val else: cameraConfigMsgPayload.cameraID = 0 if 'renderMode' in kwargs: val = kwargs['renderMode'] if not isinstance(val, int) or val < 0 or val > 1: print('ERROR: vizSupport: renderMode must be 0 or 1.') exit(1) cameraConfigMsgPayload.renderMode = val else: cameraConfigMsgPayload.renderMode = 0 if 'depthMapClippingPlanes' in kwargs: if cameraConfigMsgPayload.renderMode != 1: print('WARNING: vizSupport: depthMapClippingPlanes only works with renderMode set to 1 (depthMap).') exit(1) val = kwargs['depthMapClippingPlanes'] if not isinstance(val, list): print('ERROR: vizSupport: depthMapClippingPlanes must be a list of two doubles.') exit(1) if len(val) != 2: print('ERROR: vizSupport: depthMapClippingPlanes list ' + str(val) + 'must be of length 2') exit(1) if not isinstance(val[0], float) or not isinstance(val[1], float): print('ERROR: vizSupport: depthMapClippingPlanes list ' + str(val) + ' must contain floats') exit(1) print(val) cameraConfigMsgPayload.depthMapClippingPlanes = val else: cameraConfigMsgPayload.depthMapClippingPlanes = [-1.0, -1.0] cameraConfigMsg = messaging.CameraConfigMsg().write(cameraConfigMsgPayload) # need to add code to retain camera config msg in memory. Below # the function makes vizInterface subscribe to the pointer to this Msg object viz.addCamMsgToModule(cameraConfigMsg) return cameraConfigMsgPayload
[docs] def enableUnityVisualization(scSim, simTaskName, scList, **kwargs): """ This method creates an instance of the vizInterface() modules and sets up associated Vizard configuration setting messages. Parameters ---------- scSim: variable with the simulationBaseClass copy simTaskName: task to which to add the vizInterface module scList: :ref:`spacecraft` objects. Can be a single object or list of objects Keyword Args ------------ saveFile: str can be a single file name, or a full path + file name. In both cases a local results are stored in a local sub-folder. Default: empty string resulting in the data not being saved to a file rwEffectorList: single or list of ``ReactionWheelStateEffector`` The list must have the same length ``scList``. Each entry is the :ref:`ReactionWheelStateEffector` instance for the spacecraft, or ``None`` if the spacecraft has no RW devices. thrEffectorList: single or double-list of :ref:`ThrusterDynamicEffector` The list must have the same length ``scList``. Each entry is a list of :ref:`ReactionWheelStateEffector` instances for the spacecraft denoting a thruster cluster, or ``None`` if the spacecraft has no thruster devices. thrColors: single or vector of int(4) array of RGBA color values for each thruster set. The list must have the same length as ``scList``. Each list entry is a list of RGBA array values for each cluster set. cssList: list of lists of :ref:`CoarseSunSensor` objects. The outer list length must match ``scList``. genericSensorList: list of lists of ``GenericSensor`` structures. The outer list length must match ``scList``. genericSensorCmdInMsgs: list of lists of :ref:`DeviceCmdMsgPayload` sensor state messages. The outer list length must match ``scList``. If the spacecraft has no sensor command msg, then use ``None``. liveStream: bool flag if live data streaming to Vizard should be used broadcastStream: bool flag if messages should be broadcast for listener Vizards to pick up. noDisplay: bool flag if Vizard should run performance opNav (no Vizard display) genericStorageList: list of lists of ``GenericStorage`` structures. The outer list length must match ``scList``. lightList: list of lists of ``Light`` structures. The outer list length must match ``scList``. spriteList: list of sprite information for each spacecraft modelDictionaryKeyList: list of the spacecraft model dictionary. Use ``None`` if default values are used oscOrbitColorList: list of spacecraft osculating orbit colors. Can be 4 RGBA integer value (0-255), a color string, or ``None`` if default values should be used. The array must be of the length of the spacecraft list trueOrbitColorList: list of spacecraft true or actual orbit colors. Can be 4 RGBA integer value (0-255), a color string, or ``None`` if default values should be used. The array must be of the length of the spacecraft list trueOrbitColorInMsgList: list of color messages to read and provide the true orbit color at each time step. This overwrites the values set with trueOrbitColorList. msmInfoList: list of MSM configuration messages ellipsoidList: list of lists of ``Ellipsoid`` structures. The outer list length must match ``scList``. Returns ------- :ref:`vizInterface` object copy of the vizInterface instance """ if not vizFound: print('Could not find vizInterface when import attempted. Be sure to build BSK with vizInterface support.') return # clear the list of point line elements del pointLineList[:] del actuatorGuiSettingList[:] del coneInOutList[:] global firstSpacecraftName unitTestSupport.checkMethodKeyword( ['saveFile', 'rwEffectorList', 'thrEffectorList', 'thrColors', 'cssList', 'liveStream', 'broadcastStream', 'noDisplay', 'genericSensorList', 'transceiverList', 'genericStorageList', 'lightList', 'spriteList', 'modelDictionaryKeyList', 'oscOrbitColorList', 'trueOrbitColorList', 'logoTextureList', 'msmInfoList', 'ellipsoidList', 'trueOrbitColorInMsgList'], kwargs) # set up the Vizard interface module vizMessenger = vizInterface.VizInterface() vizMessenger.ModelTag = "vizMessenger" scSim.AddModelToTask(simTaskName, vizMessenger) # ensure the spacecraft object list is a list if not isinstance(scList, list): scList = [scList] scListLength = len(scList) firstSpacecraftName = scList[0].ModelTag # process the RW effector argument rwEffectorScList = False if 'rwEffectorList' in kwargs: rwEffectorScList = kwargs['rwEffectorList'] if not isinstance(rwEffectorScList, list): rwEffectorScList = [rwEffectorScList] if len(rwEffectorScList) != scListLength: print('ERROR: vizSupport: rwEffectorList should have the same length as the number of spacecraft') exit(1) thrEffectorScList = False if 'thrEffectorList' in kwargs: thrEffectorScList = kwargs['thrEffectorList'] if not isinstance(thrEffectorScList, list): thrEffectorScList = [[thrEffectorScList]] if len(thrEffectorScList) != scListLength: print('ERROR: vizSupport: thrEffectorList should have the same length as the number of spacecraft') exit(1) thrColorsScList = False if 'thrColors' in kwargs: thrColorsScList = kwargs['thrColors'] if len(thrColorsScList) == 4: colorCheck = True for c in thrColorsScList: if not isinstance(c, int): colorCheck = False if colorCheck: thrColorsScList = [[thrColorsScList]] if len(thrColorsScList) != scListLength: print('ERROR: vizSupport: thrColors should have the same length as the number of spacecraft') exit(1) cssScList = False if 'cssList' in kwargs: cssScList = kwargs['cssList'] if not isinstance(cssScList, list): cssScList = [[cssScList]] if len(cssScList) != scListLength: print('ERROR: vizSupport: cssList should have the same length as the number ' 'of spacecraft and contain lists of CSSs') exit(1) gsScList = False if 'genericSensorList' in kwargs: gsScList = kwargs['genericSensorList'] if not isinstance(gsScList, list): gsScList = [[gsScList]] if len(gsScList) != scListLength: print('ERROR: vizSupport: genericSensorList should have the same length as the ' 'number of spacecraft and contain lists of generic sensors') exit(1) elScList = False if 'ellipsoidList' in kwargs: elScList = kwargs['ellipsoidList'] if not isinstance(elScList, list): elScList = [[elScList]] if len(elScList) != scListLength: print('ERROR: vizSupport: ellipsoidList should have the same length as the ' 'number of spacecraft and contain lists of generic sensors') exit(1) liScList = False if 'lightList' in kwargs: liScList = kwargs['lightList'] if not isinstance(liScList, list): liScList = [[liScList]] if len(liScList) != scListLength: print('ERROR: vizSupport: lightList should have the same length as the ' 'number of spacecraft and contain lists of light devices') exit(1) gsdScList = False if 'genericStorageList' in kwargs: gsdScList = kwargs['genericStorageList'] if not isinstance(gsdScList, list): gsdScList = [[gsdScList]] if len(gsdScList) != scListLength: print('ERROR: vizSupport: genericStorageList should have the same length as the ' 'number of spacecraft and contain lists of generic sensors') exit(1) tcScList = False if 'transceiverList' in kwargs: tcScList = kwargs['transceiverList'] if not isinstance(tcScList, list): tcScList = [[tcScList]] if len(tcScList) != scListLength: print('ERROR: vizSupport: tcScList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) spriteScList = False if 'spriteList' in kwargs: spriteScList = kwargs['spriteList'] if not isinstance(spriteScList, list): spriteScList = [spriteScList] if len(spriteScList) != scListLength: print('ERROR: vizSupport: spriteScList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) modelDictionaryKeyList = False if 'modelDictionaryKeyList' in kwargs: modelDictionaryKeyList = kwargs['modelDictionaryKeyList'] if not isinstance(modelDictionaryKeyList, list): modelDictionaryKeyList = [modelDictionaryKeyList] if len(modelDictionaryKeyList) != scListLength: print('ERROR: vizSupport: modelDictionaryKeyList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) logoTextureList = False if 'logoTextureList' in kwargs: logoTextureList = kwargs['logoTextureList'] if not isinstance(logoTextureList, list): logoTextureList = [logoTextureList] if len(logoTextureList) != scListLength: print('ERROR: vizSupport: logoTextureList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) oscOrbitColorList = False if 'oscOrbitColorList' in kwargs: oscOrbitColorList = kwargs['oscOrbitColorList'] if len(oscOrbitColorList) != scListLength: print('ERROR: vizSupport: oscOrbitColorList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) for elem in oscOrbitColorList: if isinstance(elem, list): if len(elem) != 4: print('ERROR: vizSupport: if specifying oscOrbitColorList color via RGBA values, you ' 'must provide 4 integers values from 0 to 255 ') exit(1) for color in elem: if color < 0 or color > 255: print('ERROR: vizSupport: oscOrbitColorList color contained negative value ') exit(1) trueOrbitColorList = False if 'trueOrbitColorList' in kwargs: trueOrbitColorList = kwargs['trueOrbitColorList'] if len(trueOrbitColorList) != scListLength: print('ERROR: vizSupport: trueOrbitColorList should have the same length as the ' 'number of spacecraft and contain lists of transceivers') exit(1) for elem in trueOrbitColorList: if isinstance(elem, list): if len(elem) != 4: print('ERROR: vizSupport: if specifying trueOrbitColorList color via RGBA values, you ' 'must provide 4 integers values from 0 to 255 ') exit(1) for color in elem: if color < 0 or color > 255: print('ERROR: vizSupport: trueOrbitColorList color contained negative value ') exit(1) msmInfoList = False if 'msmInfoList' in kwargs: msmInfoList = kwargs['msmInfoList'] if not isinstance(msmInfoList, list): msmInfoList = [msmInfoList] if len(msmInfoList) != scListLength: print('ERROR: vizSupport: msmInfoList should have the same length as the ' 'number of spacecraft') exit(1) trueOrbitColorInMsgList = False if 'trueOrbitColorInMsgList' in kwargs: trueOrbitColorInMsgList = kwargs['trueOrbitColorInMsgList'] if not isinstance(trueOrbitColorInMsgList, list): trueOrbitColorInMsgList = [trueOrbitColorInMsgList] if len(trueOrbitColorInMsgList) != scListLength: print('ERROR: vizSupport: trueOrbitColorInMsgList should have the same length as the ' 'number of spacecraft') exit(1) # loop over all spacecraft to associated states and msg information planetNameList = [] planetInfoList = [] spiceMsgList = [] vizMessenger.scData.clear() c = 0 spacecraftParentName = "" for sc in scList: # create spacecraft information container scData = vizInterface.VizSpacecraftData() # link to spacecraft state message if isinstance(sc, type(spacecraft.Spacecraft())): # set spacecraft name scData.spacecraftName = sc.ModelTag spacecraftParentName = sc.ModelTag scData.scStateInMsg.subscribeTo(sc.scStateOutMsg) # link to celestial bodies information for gravBody in sc.gravField.gravBodies: # check if the celestial object has already been added if gravBody.planetName not in planetNameList: planetNameList.append(gravBody.planetName) planetInfo = vizInterface.GravBodyInfo() if gravBody.displayName == "": planetInfo.bodyName = gravBody.planetName else: planetInfo.bodyName = gravBody.displayName planetInfo.mu = gravBody.mu planetInfo.radEquator = gravBody.radEquator planetInfo.radiusRatio = gravBody.radiusRatio planetInfo.modelDictionaryKey = gravBody.modelDictionaryKey planetInfoList.append(planetInfo) spiceMsgList.append(gravBody.planetBodyInMsg) else: # the scList object is an effector belonging to the parent spacecraft scData.parentSpacecraftName = spacecraftParentName ModelTag = sc[0] effStateOutMsg = sc[1] scData.spacecraftName = ModelTag scData.scStateInMsg.subscribeTo(effStateOutMsg) # process RW effectors if rwEffectorScList: rwList = [] if rwEffectorScList[c] is not None: # RWs have been added to this spacecraft for rwLogMsg in rwEffectorScList[c].rwOutMsgs: rwList.append(rwLogMsg.addSubscriber()) scData.rwInMsgs = messaging.RWConfigLogMsgInMsgsVector(rwList) # process THR effectors if thrEffectorScList: thrList = [] thrInfo = [] if thrEffectorScList[c] is not None: # THR clusters have been added to this spacecraft clusterCounter = 0 for thrEff in thrEffectorScList[c]: # loop over the THR effectors attached to this spacecraft thSet = vizInterface.ThrClusterMap() thSet.thrTag = thrEff.ModelTag # set the label for this cluster of THR devices if thrColorsScList: if thrColorsScList[c] is not None: thSet.color = thrColorsScList[c][clusterCounter] for thrLogMsg in thrEff.thrusterOutMsgs: # loop over the THR cluster log message thrList.append(thrLogMsg.addSubscriber()) thrInfo.append(thSet) clusterCounter += 1 scData.thrInMsgs = messaging.THROutputMsgInMsgsVector(thrList) scData.thrInfo = vizInterface.ThrClusterVector(thrInfo) # process CSS information if cssScList: cssDeviceList = [] if cssScList[c] is not None: # CSS list has been added to this spacecraft for css in cssScList[c]: cssDeviceList.append(css.cssConfigLogOutMsg.addSubscriber()) scData.cssInMsgs = messaging.CSSConfigLogMsgInMsgsVector(cssDeviceList) # process generic sensor HUD information if gsScList: gsList = [] if gsScList[c] is not None: # generic sensor(s) have been added to this spacecraft for gs in gsScList[c]: gsList.append(gs) scData.genericSensorList = vizInterface.GenericSensorVector(gsList) # process spacecraft ellipsoids if elScList: elList = [] if elScList[c] is not None: # generic sensor(s) have been added to this spacecraft for el in elScList[c]: elList.append(el) scData.ellipsoidList = vizInterface.EllipsoidVector(elList) # process spacecraft lights if liScList: liList = [] if liScList[c] is not None: # light objects(s) have been added to this spacecraft for li in liScList[c]: liList.append(li) scData.lightList = vizInterface.LightVector(liList) # process generic storage HUD information if gsdScList: gsdList = [] if gsdScList[c] is not None: # generic storage device(s) have been added to this spacecraft for gsd in gsdScList[c]: if len(gsd.color) > 1: if len(gsd.color)/4 != len(gsd.thresholds) + 1: print("ERROR: vizSupport: generic storage " + gsd.label + " threshold list does not have the correct dimension. " "It should be 1 smaller than the list of colors.") exit(1) else: if len(gsd.thresholds) > 0: print("ERROR: vizSupport: generic storage " + gsd.label + " threshold list is set, but no multiple of colors are provided.") exit(1) gsdList.append(gsd) scData.genericStorageList = vizInterface.GenericStorageVector(gsdList) # process transceiver HUD information if tcScList: tcList = [] if tcScList[c] is not None: # transceiver(s) have been added to this spacecraft for tc in tcScList[c]: tcList.append(tc) scData.transceiverList = vizInterface.TransceiverVector(tcList) # process sprite information if spriteScList: if spriteScList[c] is not None: scData.spacecraftSprite = spriteScList[c] # process modelDictionaryKey information if modelDictionaryKeyList: if modelDictionaryKeyList[c] is not None: scData.modelDictionaryKey = modelDictionaryKeyList[c] # process logoTexture information if logoTextureList: if logoTextureList[c] is not None: scData.logoTexture = logoTextureList[c] if oscOrbitColorList: if oscOrbitColorList[c] is not None: scData.oscOrbitLineColor = vizInterface.IntVector(oscOrbitColorList[c]) if trueOrbitColorList: if trueOrbitColorList[c] is not None: scData.trueTrajectoryLineColor = vizInterface.IntVector(trueOrbitColorList[c]) if trueOrbitColorInMsgList: if trueOrbitColorInMsgList[c] is not None: scData.trueTrajectoryLineColorInMsg = trueOrbitColorInMsgList[c] # process MSM information if msmInfoList: if msmInfoList[c] is not None: # MSM have been added to this spacecraft scData.msmInfo = msmInfoList[c] vizMessenger.scData.push_back(scData) c += 1 vizMessenger.gravBodyInformation = vizInterface.GravBodyInfoVector(planetInfoList) vizMessenger.spiceInMsgs = messaging.SpicePlanetStateMsgInMsgsVector(spiceMsgList) # note that the following logic can receive a single file name, or a full path + file name. # In both cases a local results are stored in a local sub-folder. vizMessenger.saveFile = False if 'saveFile' in kwargs: fileNamePath = kwargs['saveFile'] fileName = os.path.splitext(os.path.basename(fileNamePath))[0] filePath = os.path.dirname(fileNamePath) if filePath == "": filePath = "." if not os.path.isdir(filePath + '/_VizFiles'): os.mkdir(filePath + '/_VizFiles') vizFileNamePath = filePath + '/_VizFiles/' + fileName + '_UnityViz.bin' vizMessenger.saveFile = True vizMessenger.protoFilename = vizFileNamePath print("Saving Viz file to " + vizFileNamePath) if 'liveStream' in kwargs: val = kwargs['liveStream'] if not isinstance(val, bool): print('ERROR: vizSupport: liveStream must be True or False') exit(1) vizMessenger.liveStream = val if 'broadcastStream' in kwargs: val = kwargs['broadcastStream'] if not isinstance(val, bool): print('ERROR: vizSupport: broadcastStream must be True or False') exit(1) vizMessenger.broadcastStream = val if 'noDisplay' in kwargs: val = kwargs['noDisplay'] if not isinstance(val, bool): print('ERROR: vizSupport: noDisplay must be True or False') exit(1) if val and (vizMessenger.liveStream or vizMessenger.broadcastStream): print('ERROR: vizSupport: noDisplay mode cannot be used with liveStream or broadcastStream.') exit(1) vizMessenger.noDisplay = val return vizMessenger