diff --git a/pano/README.md b/pano/README.md
index 3485af31..edb34f77 100644
--- a/pano/README.md
+++ b/pano/README.md
@@ -148,8 +148,11 @@ Note that some of the individual steps within each panorama stitch (e.g., `enble
### View the tour
-TODO
+In the host OS, point a web browser at `http://127.0.0.1:8080/`. The `run.sh` script forwards port 8080 of the host to port 80 of the container, where an Apache server is running to provide a preview of the tour.
+### Install the tour
+
+Recursively copy the `$ISAAC_PANO_OUTPUT/html` folder wherever you want on your web server. Make sure permissions are set to enable your users to access files in the folder. No special configuration should be needed as long as the server is configured to serve static files with the appropriate MIME types. None of the application logic runs on the web server; the viewing interfaces run completely in the browser. When users make annotations, they will be stored locally in the user's web browser, not on the web server.
### Generate target pose from image
@@ -185,4 +188,4 @@ An example output would be:
Things to look for are that the timestamps are not too large, this would mean that results are unreliable.
Pay attention to the point cloud point to vector distance to make sure that the point is not too far away from the target vector, meaning that the point cloud does not include the target which is possible due to different field of views between the cameras.
-Lastly the mesh and pcl should not disagree, if they do, some manual analysis is needed. Be aware that the attitude provided is defined by the direction pointing at the target assuming roll zero.
\ No newline at end of file
+Lastly the mesh and pcl should not disagree, if they do, some manual analysis is needed. Be aware that the attitude provided is defined by the direction pointing at the target assuming roll zero.
diff --git a/pano/docker/pano.Dockerfile b/pano/docker/pano.Dockerfile
index ea986cd4..80017faa 100644
--- a/pano/docker/pano.Dockerfile
+++ b/pano/docker/pano.Dockerfile
@@ -4,29 +4,37 @@ ARG REMOTE=ghcr.io/nasa
FROM ${REMOTE}/isaac:latest-ubuntu${UBUNTU_VERSION}
+# apache2: Local web server for previewing pano tour interface
# default-jre: Java runtime needed for minifying Pannellum web files
# hugin: pano stitching tools (and hsi Python interface)
# libvips-tools: convert images to multires, zoomable in OpenSeaDragon
# python3-pip: for installing Python packages later in this Dockerfile
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
+ apache2 \
default-jre \
+ gfortran \
hugin \
+ libfftw3-dev \
+ libopenblas-dev \
libvips-tools \
python3-pip \
- gfortran libopenblas-dev libfftw3-dev \
&& rm -rf /var/lib/apt/lists/*
-# pandas: pulled in as pyshtools dependency but install breaks if not mentioned explicitly (?)
-# pyshtools: used during Pannellum multires generation
-# snakemake: modern build system based on Python, manages stitching workflows
-
# Install Jupyter explicitly first
-RUN pip3 install --no-cache-dir --upgrade pip && \
- pip3 install --no-cache-dir jupyter
+RUN pip3 install --no-cache-dir --upgrade pip \
+ && pip3 install --no-cache-dir jupyter
# Install other Python packages: jupyter package needs to be installed before attempting to build pyshtools
-RUN pip3 install --no-cache-dir pandas pyshtools snakemake pulp==2.7 --ignore-installed PyYAML
+# - pandas: pulled in as pyshtools dependency but install breaks if not mentioned explicitly (?)
+# - pyshtools: used during Pannellum multires generation
+# - snakemake: modern build system based on Python, manages stitching workflows
+RUN pip3 install --no-cache-dir \
+ --ignore-installed PyYAML \
+ pandas \
+ pulp==2.7 \
+ pyshtools \
+ snakemake
# pannellum: library for viewing/navigating panorama tours
RUN mkdir -p /opt \
@@ -73,3 +81,16 @@ RUN echo 'source "/src/isaac/devel/setup.bash"\nexport ASTROBEE_CONFIG_DIR="/src
# once new pano folder is merged into develop and official docker
# images are updated.
RUN echo 'export ROS_PACKAGE_PATH="${ROS_PACKAGE_PATH}:/src/isaac/src/pano/pano_stitch::/src/isaac/src/pano/pano_view"' >> "${HOME}/.bashrc"
+
+# This is a bit unusual, but starting apache in .bashrc ensures it's
+# running whenever we run an interactive session using
+# run.sh. (Running it multiple times doesn't cause a problem.)
+RUN echo 'apachectl start' >> "${HOME}/.bashrc"
+
+# Make /output/html the DocumentRoot for the apache2 debug web server
+RUN perl -i -ple 's:/var/www:/output:g' \
+ /etc/apache2/apache2.conf \
+ /etc/apache2/sites-available/000-default.conf
+
+# Expose local web server for pano tour preview
+EXPOSE 80
diff --git a/pano/docker/run.sh b/pano/docker/run.sh
index f6513fb2..2879e59d 100755
--- a/pano/docker/run.sh
+++ b/pano/docker/run.sh
@@ -20,4 +20,5 @@ docker run \
--mount type=bind,source=${ISAAC_PANO_INPUT},target=/input,readonly \
--mount type=bind,source=${ISAAC_PANO_OUTPUT},target=/output \
--mount type=bind,source=${ISAAC_SRC},target=/src/isaac/src \
+ -p 127.0.0.1:8080:80 \
isaac/pano
diff --git a/pano/pano_stitch/scripts/pano_image_meta.py b/pano/pano_stitch/scripts/pano_image_meta.py
index b20934cd..c8c1f6f3 100755
--- a/pano/pano_stitch/scripts/pano_image_meta.py
+++ b/pano/pano_stitch/scripts/pano_image_meta.py
@@ -26,7 +26,7 @@
import rosbag
from tf.transformations import euler_from_quaternion
-IMAGE_TOPIC = ["/hw/cam_sci/compressed", "/hw/cam_sci_info"]
+IMAGE_TOPICS = ["/hw/cam_sci/compressed", "/hw/cam_sci_info"]
POSE_TOPIC = "/loc/pose"
FIELD_NAMES = (
"timestamp",
@@ -50,9 +50,8 @@ def get_image_meta(inbag_path, num_images=None):
images = []
with rosbag.Bag(inbag_path) as bag:
img_meta = None
- topics = IMAGE_TOPIC + [POSE_TOPIC]
- for topic, msg, t in bag.read_messages(topics):
- if topic in IMAGE_TOPIC:
+ for topic, msg, t in bag.read_messages([*IMAGE_TOPICS, POSE_TOPIC]):
+ if topic in IMAGE_TOPICS:
if num_images is not None and len(images) == num_images:
break
diff --git a/pano/pano_view/CMakeLists.txt b/pano/pano_view/CMakeLists.txt
index 0c727839..d0251ffd 100644
--- a/pano/pano_view/CMakeLists.txt
+++ b/pano/pano_view/CMakeLists.txt
@@ -82,7 +82,7 @@ add_dependencies(point_cloud_intersect ${catkin_EXPORTED_TARGETS})
target_link_libraries(point_cloud_intersect ${catkin_LIBRARIES})
-## Declare a C++ executable: find_point_coordinate
+## Declare a C++ executable: find_point_coordinate
add_executable(find_point_coordinate tools/find_point_coordinate.cc)
add_dependencies(find_point_coordinate ${catkin_EXPORTED_TARGETS})
target_link_libraries(find_point_coordinate mesh_intersect point_cloud_intersect
diff --git a/pano/pano_view/config/phase1x_inspection_results.config b/pano/pano_view/config/phase1x_inspection_results.config
new file mode 100644
index 00000000..2e9d3bc6
--- /dev/null
+++ b/pano/pano_view/config/phase1x_inspection_results.config
@@ -0,0 +1,183 @@
+# ======================================================================
+# The content below the line is from the file
+# isaac/src/pano/pano_view/config/phase1x_inspection_results.config
+# and is designed to be copy/pasted at the bottom of pano_meta.yaml.
+
+# How inspection_results was generated: The photos were manually
+# selected from all hatch seal targeted inspection photos to be the
+# best ones (at most one from each focus stack) for showing
+# recognizable damage sites. Pitch/yaw values for each image were
+# manually selected using the Pannellum hotSpotDebug feature.
+inspection_results:
+ scene001_isaac11_bumble_usl_bay6:
+ # ISAAC11 USL aft hatch seal inspection
+ - pitch: -19.496113033067832
+ yaw: -178.49501734467697
+ image: /input/inspection_results/isaac11_usl_aft/1657549131.173.jpg
+ slug: Hatch Seal ISAAC16 USL AFT
+
+ scene004_isaac11_queen_usl_bay1:
+ # ISAAC16 USL forward hatch seal deck section positions, numbered 0 .. 3 port -> starboard
+ # Only position 1 has a recognizable damage site, leaving out the others
+
+ #- pitch: -23.829139007892287
+ # yaw: -9.57794857674467
+ # image: /input/inspection_results/isaac16_usl_fwd/1720198615.236.jpg
+ # slug: Hatch Seal ISAAC16 USL FWD 0
+ - pitch: -24.233722398730837
+ yaw: -2.3869610431019694
+ image: /input/inspection_results/isaac16_usl_fwd/1720199288.313.jpg
+ slug: Hatch Seal ISAAC16 USL FWD 1
+ #- pitch: -24.210064732216285
+ # yaw: 6.143908859653246
+ # image: /input/inspection_results/isaac16_usl_fwd/1720199367.399.jpg
+ # slug: Hatch Seal ISAAC16 USL FWD 2
+ #- pitch: -24.167778451658435
+ # yaw: 10.29111636247168
+ # image: /input/inspection_results/isaac16_usl_fwd/1720199447.824.jpg
+ # slug: Hatch Seal ISAAC16 USL FWD 3
+
+ # ISAAC11 USL forward hatch seal inspection
+ - pitch: -24.233722398730837
+ yaw: -1
+ image: /input/inspection_results/isaac11_usl_fwd/1657551186.506.jpg
+ slug: Hatch Seal ISAAC11 USL FWD
+
+# How initial_annotations was generated: I used the existing target
+# selection feature to annotate the (somewhat) recognizable damage
+# sites, saved the results, and simply copy/pasted the file contents
+# here. Conveniently, YAML is a superset of the JSON format used for
+# the annotations, so it was already valid YAML (even if the style
+# clashes with the one used above).
+initial_annotations: {
+ "scene004_isaac11_queen_usl_bay1": {
+ "1720199288.313": [
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "A: Divot on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:3449.820556640625,1809.1005859375,52.701171875,39.3167724609375"
+ }
+ },
+ "id": "#5e67f4b4-86ed-4eaf-9bf2-caeac4358691"
+ },
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "B: Cut on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:3723.783203125,1791.1153564453125,124.642333984375,58.97509765625"
+ }
+ },
+ "id": "#f5f60596-a44a-48d2-aafb-49d63621bd20"
+ }
+ ],
+ "1657551186.506": [
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "B: Cut on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:3658.030517578125,2492.563720703125,110.6806640625,51.651123046875"
+ }
+ },
+ "id": "#5a8d060a-259e-47f9-9b42-519a09246897"
+ },
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "A: Divot on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:3269.641845703125,2496.58837890625,52.992431640625,42.930908203125"
+ }
+ },
+ "id": "#49a5daa0-41c1-4856-b21b-09164687415a"
+ }
+ ]
+ },
+ "scene001_isaac11_bumble_usl_bay6": {
+ "1657549131.173": [
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "F: Divot and Cut on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:2259.4794921875,2235.703125,56.346435546875,41.589111328125"
+ }
+ },
+ "id": "#0b8ab636-3697-425a-b683-089712796e24"
+ },
+ {
+ "@context": "http://www.w3.org/ns/anno.jsonld",
+ "type": "Annotation",
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "G: Divot on Inner Seal",
+ "purpose": "commenting"
+ }
+ ],
+ "target": {
+ "source": "http://localhost:8080/src/undefined",
+ "selector": {
+ "type": "FragmentSelector",
+ "conformsTo": "http://www.w3.org/TR/media-frags/",
+ "value": "xywh=pixel:2729.704833984375,2227.653564453125,63.72509765625,38.906005859375"
+ }
+ },
+ "id": "#84eb0fa7-4601-43e1-a900-46077fc93c4a"
+ }
+ ]
+ }
+}
diff --git a/pano/pano_view/media/camera_highlight.png b/pano/pano_view/media/camera_highlight.png
new file mode 100644
index 00000000..6c742bd0
Binary files /dev/null and b/pano/pano_view/media/camera_highlight.png differ
diff --git a/pano/pano_view/media/favicon/favicon-128x128.png b/pano/pano_view/media/favicon/favicon-128x128.png
new file mode 100755
index 00000000..5fcc91ba
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-128x128.png differ
diff --git a/pano/pano_view/media/favicon/favicon-16x16.png b/pano/pano_view/media/favicon/favicon-16x16.png
new file mode 100755
index 00000000..3a8fd9d4
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-16x16.png differ
diff --git a/pano/pano_view/media/favicon/favicon-192x192.png b/pano/pano_view/media/favicon/favicon-192x192.png
new file mode 100755
index 00000000..39a0e8e8
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-192x192.png differ
diff --git a/pano/pano_view/media/favicon/favicon-196x196.png b/pano/pano_view/media/favicon/favicon-196x196.png
new file mode 100755
index 00000000..4d79ea2a
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-196x196.png differ
diff --git a/pano/pano_view/media/favicon/favicon-228x228.png b/pano/pano_view/media/favicon/favicon-228x228.png
new file mode 100755
index 00000000..58a5ea38
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-228x228.png differ
diff --git a/pano/pano_view/media/favicon/favicon-32x32.png b/pano/pano_view/media/favicon/favicon-32x32.png
new file mode 100755
index 00000000..f0a1d1aa
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-32x32.png differ
diff --git a/pano/pano_view/media/favicon/favicon-57x57.png b/pano/pano_view/media/favicon/favicon-57x57.png
new file mode 100755
index 00000000..4ef8e0b3
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-57x57.png differ
diff --git a/pano/pano_view/media/favicon/favicon-76x76.png b/pano/pano_view/media/favicon/favicon-76x76.png
new file mode 100755
index 00000000..0e4502b2
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-76x76.png differ
diff --git a/pano/pano_view/media/favicon/favicon-96x96.png b/pano/pano_view/media/favicon/favicon-96x96.png
new file mode 100755
index 00000000..c6c60bc4
Binary files /dev/null and b/pano/pano_view/media/favicon/favicon-96x96.png differ
diff --git a/pano/pano_view/media/inspection.png b/pano/pano_view/media/inspection.png
new file mode 100644
index 00000000..0697f755
Binary files /dev/null and b/pano/pano_view/media/inspection.png differ
diff --git a/pano/pano_view/scripts/generate_tour.py b/pano/pano_view/scripts/generate_tour.py
index a0d7b836..82ad7613 100755
--- a/pano/pano_view/scripts/generate_tour.py
+++ b/pano/pano_view/scripts/generate_tour.py
@@ -178,7 +178,8 @@ def install_static_files(out_folder, package_paths):
# we can just install them; in the future we might replace them
# with templates to provide greater flexibility, which would require
# template rendering.
- install_glob(os.path.join(PANO_VIEW_ROOT, "templates/pannellum.htm"), out_folder)
+ install_glob(os.path.join(PANO_VIEW_ROOT, "templates/pannellum.html"), out_folder)
+ install_glob(os.path.join(PANO_VIEW_ROOT, "templates/help.html"), out_folder)
install_file(
os.path.join(PANO_VIEW_ROOT, "templates/isaac_source_image.html"),
os.path.join(out_folder, "src"),
@@ -336,18 +337,35 @@ def link_source_images(config, tour_scenes, out_folder):
with open(src_images_meta_path, "r") as src_images_meta_stream:
src_images_meta = json.load(src_images_meta_stream)
+ scene_meta = get_display_scene_meta(scene_id, config_scene_meta)
+
img_ids = sorted(src_images_meta.keys())
for i, img_id in enumerate(img_ids):
+ img_num = i + 1
img_meta = src_images_meta[img_id]
+ try:
+ # get manually configured slug for inspection result
+ text = img_meta["slug"]
+ slug = text.replace(" ", "_")
+ except KeyError:
+ # generic fallback for pano images
+ text = "Image %d" % img_num
+ slug = "%s_%s_Image_%s" % (
+ scene_meta["module"],
+ scene_meta["bay"],
+ img_num,
+ )
hot_spots.append(
{
"type": "info",
- "id": i,
- "text": "Image %d" % i,
+ "id": img_id,
+ "text": text,
"yaw": img_meta["yaw"] - tour_scene.get("northOffset", 0),
"pitch": img_meta["pitch"],
- "URL": "src/#scene=%s&imageId=%s" % (scene_id, img_id),
- "cssClass": "isaac-source-image pnlm-hotspot pnlm-sprite",
+ "task": img_meta["task"],
+ "URL": "src/#scene=%s&imageId=%s&slug=%s"
+ % (scene_id, img_id, slug),
+ "cssClass": f"isaac-source-image isaac-{img_meta['task']} pnlm-hotspot pnlm-sprite",
"attributes": {
"target": "_blank",
},
@@ -362,6 +380,7 @@ def generate_tour_json(config, out_folder):
tour_scenes = {}
tour["scenes"] = tour_scenes
+ tour["initialAnnotations"] = config["initial_annotations"]
for scene_id, config_scene_meta in config["scenes"].items():
# Read tiler scene metadata
@@ -430,7 +449,7 @@ def generate_scene_index(config, out_folder):
index.append(
fill_field(
(
- '
The Panoramic Tour Viewer lets you freely explore the interior of the ISS. Some features include:
+
+
Throughout the panorama view:
+
+
Click/tap and drag to pan your view and look in different directions.
+
Zoom in and out with a pinch gesture on a multitouch display, or mouse wheel scroll if you have a mouse.
+
+
+
The panorama controls at the upper left provide:
+
+
The [+] and [-] buttons are another way to zoom in and out.
+
The button with the viewfinder icon toggles full-screen mode for more immersive exploration.
+
+
+
The overview map at the upper right provides:
+
+
The map shows the modules of the U.S. Orbital Segment of the ISS where the Astrobee robots are able to operate to collect panoramic survey data. (Only three modules have been surveyed so far.)
+
The red arrow shows the position and orientation (yaw) of the current view so you can stay aware of where you are.
+
The gray dots show the locations of ISS module bays where panorama scenes are available to explore. Click/tap on one of the dots to move to that scene.
+
+
+
The icons scattered throughout the panorama provide:
+
+
An upward pointing arrow icon is a hotspot that links to a neighboring panorama scene. Click/tap on the hotspot to move the tour view to that scene.
+
The camera icons are hotspots that link to one of the source images that were stitched together to form the panorama. You may prefer to view these images because they are free from stitching artifacts, or because you want to add annotations. Click/tap on the hotspot to open an Image Viewer window on that image. The camera icon is normally colored grey but is highlighted yellow if the image has been annotated.
+
The blue magnifying glass icons are hotspots that link to a targeted inspection image. You may prefer to view these images because they provide higher resolution than the panorama due to being captured closer up and with optimized lighting. Click/tap on the hotspot to open an Image Viewer window on that image.
+
+
+
The toolbar above the panorama provides:
+
+
The "Help" button opens this help.
+
The "View Options" menu lets you toggle hide/show for various elements of the tour interface. You may prefer to hide some elements you don't need in order to minimize distractions, especially when taking screenshots.
+
The "Pano Image" button starts a download of the full stitched panorama image. You may find this image helpful if you want to work with the panorama using other applications. Note that: You can't substitute for the "Pano Image" button using browser features like "Open Image in New Tab" or "Save Image": at best, they will open an image tile rather than the whole panorama. The downloaded panorama image will have very high resolution (typical: 26K x 13K pixels, 60+ MB), so you may have trouble opening it with some applications.
+
The "Annotations" section provides:
+
+
The "Previous" and "Next" buttons cycle through the list of annotated images throughout the whole tour. Each time you click/tap one of these buttons, the view will pan to focus on the hotspot for the previous/next annotated image (switching to a new scene if needed). Click/tap on the hotspot to open an Image Viewer window on that image, where you can view its annotations.
+
The "Load" button loads a whole-tour set of annotations that were previously saved. They are loaded into the local storage for your browser and will only be visible to you when you use that browser.
+
The "Save" button saves your current set of whole-tour annotations, downloading them as a file called "isaac_iss_annotations.json". You can share this file with other users, who can load it into the tour interface in their browser, or analyze it using other tools. For example, we have a tool that interprets a set of annotations as requested inspection targets and extracts the 3D target positions to use for commanding Astrobee follow-up inspections during a future ISS activity.
+
The "Clear" button deletes your current whole-tour set of annotations. (Like all annotation edits, this change only affects your view in your current browser.)
+
(The "Load", "Save", and "Clear" buttons have exactly the same behavior in both the Panoramic Tour Viewer and Image Viewer.)
The Image Viewer lets you view and annotate an individual image collected by the Astrobee robots. Some features include:
+
+
Throughout the image view:
+
+
Click/tap and drag to pan your view and look at different parts of the image.
+
Zoom in and out with a pinch gesture on a multitouch display, or mouse wheel scroll if you have a mouse.
+
Shift-click and drag to add an annotation if you have a keyboard and mouse.
+
+
+
The view controls at the upper left provide:
+
+
The [+] and [-] buttons are another way to zoom in and out.
+
The home button restores the original image view (zooms out to view the whole image).
+
The rectangle+arrow button toggles full-screen mode for more immersive exploration.
+
(These buttons auto-hide themselves after a period of inactivity. You can make them reappear by moving around in the image.)
+
+
+
The rectangular annotations in the image provide:
+
+
Click/tap on an annotation to open it. This lets you view or edit the annotation text, move the rectangle corners to adjust its shape and position, or delete the annotation using its trash can button.
+
+
+
The toolbar above the panorama provides:
+
+
The "Help" button opens this help.
+
The "Raw" button opens a new browser window displaying the full-size raw image without the Image Viewer interface. From the new window, you can view the raw image using your browser's normal interface, or download it to work with it using other applications. Note that you can't substitute for the "Raw" button by using browser features like "Open Image in New Tab" or "Save Image" in the Image Viewer: at best, they will open an image tile rather than the full-size raw image.
+
The "Annotations" section provides:
+
+
The "Undo" and "Redo" buttons undo or redo annotation edits in the current image only.
+
The "Add" button activates add-annotation mode. After you click/tap this button, click/tap and drag anywhere in the image to add a new annotation.
+
The "Previous" and "Next" buttons cycle through the list of annotations on the current image. Each time you click/tap one of these buttons, the view will open the previous/next annotation.
+
The "Load" button loads a whole-tour set of annotations that were previously saved. They are loaded into the local storage for your browser and will only be visible to you when you use that browser.
+
The "Save" button saves your current set of whole-tour annotations, downloading them as a file called "isaac_iss_annotations.json". You can share this file with other users, who can load it into the tour interface in their browser, or analyze it using other tools. For example, we have a tool that interprets a set of annotations as requested inspection targets and extracts the 3D target positions to use for commanding Astrobee follow-up inspections during a future ISS activity.
+
The "Clear" button deletes your current whole-tour set of annotations. (Like all annotation edits, this change only affects your view in your current browser.)
+
(The "Load", "Save", and "Clear" buttons have exactly the same behavior in both the Panoramic Tour Viewer and Image Viewer.)