{
"cells": [
{
"cell_type": "markdown",
"id": "510eb5b7",
"metadata": {
"slideshow": {
"slide_type": "skip"
},
"tags": []
},
"source": [
"# 2021 IIW Annual Assembly C-XII\n",
"This notebook is an extended interactive version of the `weldx` features and example dataset presented at the **2021 IIW Annual Assembly C-XII** meeting.\n",
"\n",
"The code of this notebook can be found here: [https://github.com/BAMWelDX/IIW2021_AA_CXII](https://github.com/BAMWelDX/IIW2021_AA_CXII)\n",
"\n",
"You can launch this notebook as an interactive binder session in your browser following this link: \\\n",
"[https://mybinder.org/v2/gh/BAMWelDX/IIW2021_AA_CXII/main?urlpath=lab/tree/iiw2021_CXII_fabry_cagtay_01.ipynb](https://mybinder.org/v2/gh/BAMWelDX/IIW2021_AA_CXII/main?urlpath=lab/tree/iiw2021_CXII_fabry_cagtay_01.ipynb)\n",
"\n",
"The `weldx` documentation and code is available online:\\\n",
"[https://weldx.readthedocs.io/en/latest/](https://weldx.readthedocs.io/en/latest/) \\\n",
"[https://github.com/BAMWelDX/weldx](https://github.com/BAMWelDX/weldx)\n",
"\n",
"The `weldx` documentation and GitHub links for this specific code version `v0.6.9` can be found here:\\\n",
"[https://weldx.readthedocs.io/en/v0.6.9/index.html](https://weldx.readthedocs.io/en/v0.6.9/index.html) \\\n",
"[https://github.com/BAMWelDX/weldx/tree/v0.6.9](https://github.com/BAMWelDX/weldx/tree/v0.6.9)"
]
},
{
"cell_type": "markdown",
"id": "9b2f11ee",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## Process Video\n",
"To give an ovierview of this welding example, here is a video recording of the welding experiment conducted at BAM.\n",
"\n",
"We can see the pre- and post-welding scan of the workpiece geometry as well as the position of the temperature measurements.\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"id": "bd751bb8",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## Imports\n",
"We start with some general python package imports used throughout this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da9d46b1",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"import pprint\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from weldx import Q_, WeldxFile\n",
"from weldx.asdf.util import get_schema_path, view_tree\n",
"\n",
"pp = pprint.PrettyPrinter(indent=2)\n",
"pprint = pp.pprint"
]
},
{
"cell_type": "markdown",
"id": "dd91fc73",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Some helper functions for this notebook are included in the `helpers.py` file."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "94086c4f",
"metadata": {},
"outputs": [],
"source": [
"# default plotting styles\n",
"plt.rcParams.update({\"axes.grid\": True, \"figure.figsize\": (10, 6)})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7183a4e",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"from helpers import (\n",
" ax_setup,\n",
" build_base_csm,\n",
" create_geometry,\n",
" cs_colors,\n",
" plot_gmaw,\n",
" plot_measurements,\n",
" plot_signal,\n",
" welding_wire_geo_data,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "f90d953c",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"tags": []
},
"source": [
"## 1. Opening the file\n",
"We define the `weldx` filename that contains the data used for this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b7dc739",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"filename = \"./single_pass_weld.weldx\""
]
},
{
"cell_type": "markdown",
"id": "f901892d",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To get an overview of the file contents we can use the `view_tree` function of the `weldx` library to create an interactive tree view.\n",
"\n",
"Try searching for a specific term like `wire_feedrate` using the ***Filter...*** box in the upper right."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "495fb12a",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"view_tree(filename)"
]
},
{
"cell_type": "markdown",
"id": "d5da52ea",
"metadata": {},
"source": [
"To open and access the example dataset we will use the `WeldxFile` class.\n",
"\n",
"```python\n",
"wx_file = WeldxFile(filename, \"r\", sync=False)\n",
"```\n",
"\n",
"You can find more infos about handling `weldx` files in the tutorial: https://weldx.readthedocs.io/en/latest/tutorials/weldxfile.html"
]
},
{
"cell_type": "markdown",
"id": "b451fcf2",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The file is expected to validate against the schema `single_pass_weld-0.1.0.yaml`.\\\n",
"The schema ensures that all elements of the `weldx` file pass the requirements defined in the schema, including:\n",
"\n",
"- all requirement entries are present in the file:\n",
" - `workpiece`\n",
" - `TCP`\n",
" - `welding_current`\n",
" - `welding_voltage`\n",
" - `measurement chains`\n",
" - `equipment`\n",
"- all entries and objects stored in the file have the correct type\n",
"- all additional restrictions defined in `single_pass_weld-0.1.0.yaml` are met\n",
"\n",
"The details describing the schema requirements can be found here: https://weldx.readthedocs.io/en/v0.5.0/generated/datamodels/single_pass_weld-0.1.0.html"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4b59cd99",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"file_schema = get_schema_path(\"single_pass_weld-0.1.0\")"
]
},
{
"cell_type": "markdown",
"id": "13bde8f9",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We open the `weldx` file and run a validation agains the `single_pass_weld-0.1.0.yaml` schema."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81d8180d",
"metadata": {},
"outputs": [],
"source": [
"with WeldxFile(\n",
" filename,\n",
" \"r\",\n",
" custom_schema=file_schema,\n",
" sync=False,\n",
" asdffile_kwargs={\"copy_arrays\": True},\n",
") as file:\n",
" wx_file = file"
]
},
{
"cell_type": "markdown",
"id": "883068fa",
"metadata": {},
"source": [
"We can now access and explore the contents of the file interactively in our notebook."
]
},
{
"cell_type": "markdown",
"id": "67d442f8",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"tags": []
},
"source": [
"## 2. General metadata\n",
"First let's look at some general simple metadata stored in the WelDX-file.\n",
"\n",
"The (optional) `reference_timestamp` field is used to indicate the start time of the experiment (the moment of arc ignition). All time data that is not given as absolute time are interpreted as relative to the given reference time."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8231f139",
"metadata": {},
"outputs": [],
"source": [
"wx_file.get(\"reference_timestamp\")"
]
},
{
"cell_type": "markdown",
"id": "6905bdb3",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"We can deduce the total runtime of the experiment from the TCP movement of the welding."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "70a9249c",
"metadata": {},
"outputs": [],
"source": [
"wx_file[\"TCP\"].time"
]
},
{
"cell_type": "markdown",
"id": "69b05a32",
"metadata": {},
"source": [
"The **WelDX** standard introduces the `wx_user` field to store user specific content."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a7826bff",
"metadata": {},
"outputs": [],
"source": [
"wx_file.get(\"wx_user\")"
]
},
{
"cell_type": "markdown",
"id": "ae3fcc38",
"metadata": {},
"source": [
"We define a time index from start to end of the experiment."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a1747fdb",
"metadata": {},
"outputs": [],
"source": [
"t = wx_file[\"TCP\"].time.as_timedelta_index()"
]
},
{
"cell_type": "markdown",
"id": "9ef0164e",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 3. Workpiece definition\n",
"The file schema mandates that the user provides workpiece information with the following properties:\n",
"- `base_metal` referenced by a common name and the associated standard\n",
"- the `geometry` consisting of a groove description following ISO 9692-1 and the seam length"
]
},
{
"cell_type": "markdown",
"id": "4e626b01",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Here is how this information is stored the `workpiece` entry of the example dataset `weldx` file:\n",
"```yaml\n",
"workpiece:\n",
" base_metal: {common_name: S355J2+N, standard: 'DIN EN 10225-2:2011'}\n",
" geometry:\n",
" groove_shape: !weldx!groove/iso_9692_1_2013_12/VGroove-0.1.0\n",
" t: !weldx!units/quantity-0.1.0 {value: 8, units: !weldx!units/units-0.1.0 millimeter}\n",
" alpha: !weldx!units/quantity-0.1.0 {value: 45, units: !weldx!units/units-0.1.0 degree}\n",
" b: !weldx!units/quantity-0.1.0 {value: 1, units: !weldx!units/units-0.1.0 millimeter}\n",
" c: !weldx!units/quantity-0.1.0 {value: 1, units: !weldx!units/units-0.1.0 millimeter}\n",
" code_number: ['1.3', '1.5']\n",
" seam_length: !weldx!units/quantity-0.1.0 {value: 350, units: !weldx!units/units-0.1.0 millimeter}\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "7f751a9d",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"### workpiece material\n",
"\n",
"Since we know exactly where to find the information in the file, we can access the metadata directly for all files that validate against the file schema."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dfc98bf2",
"metadata": {},
"outputs": [],
"source": [
"wx_file[\"workpiece\"][\"base_metal\"][\"common_name\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9f47068e",
"metadata": {},
"outputs": [],
"source": [
"wx_file[\"workpiece\"][\"base_metal\"][\"standard\"]"
]
},
{
"cell_type": "markdown",
"id": "54094a3a",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"### seam length\n",
"\n",
"The total seam length of the workpiece is also stored.\\\n",
"As throughout most of the functionality of the `weldx` API, physical units must be used where appropriate to avoid ambiguity."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b18da284",
"metadata": {},
"outputs": [],
"source": [
"seam_length = wx_file[\"workpiece\"][\"geometry\"][\"seam_length\"]\n",
"print(seam_length)"
]
},
{
"cell_type": "markdown",
"id": "2bae6a95",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### welding groove\n",
"\n",
"The groove shape will be loaded into a specific `weldx` type:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c84e70e0",
"metadata": {},
"outputs": [],
"source": [
"groove = wx_file[\"workpiece\"][\"geometry\"][\"groove_shape\"]\n",
"str(groove)"
]
},
{
"cell_type": "markdown",
"id": "2bc98f56",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The `weldx` API includes convinient functions to create and visualize different welding groove shapes.\\\n",
"Many examples and details are available in this tutorial: https://weldx.readthedocs.io/en/v0.5.0/tutorials/groove_types_01.html"
]
},
{
"cell_type": "markdown",
"id": "36e1a78e",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"To get a picture of the groove shape we can simply call the `plot` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3891712e",
"metadata": {},
"outputs": [],
"source": [
"groove.plot()\n",
"fig = plt.gcf()\n",
"fig.set_size_inches(7, 7);"
]
},
{
"cell_type": "markdown",
"id": "88c89c91",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### 3D Geometry\n",
"With all the metadata of the workpiece available, it is easy to visualize a simple 3D model of the specimen."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f9040da9",
"metadata": {},
"outputs": [],
"source": [
"geometry = create_geometry(groove, seam_length, Q_(10, \"mm\"))\n",
"geometry.plot(profile_raster_width=Q_(4, \"mm\"), trace_raster_width=Q_(60, \"mm\"))\n",
"ax_setup(plt.gca())"
]
},
{
"cell_type": "markdown",
"id": "d0e8f925",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## 4. Welding TCP movement description\n",
"\n",
"The path of the welding wire along the weld seam is given by the `TCP` property.\n",
"\n",
"The weld path is a linear movement between two points at a constant weld speed. The TCP reference frame is the workpiece base coordinate system, starting at the beginning of the weld seam. The x-axis coordinates will indicate the start- and end-point of the welding process along the workpiece length. The y- and z-coordinates determine the position of the TCP in relation to the cross-sectional groove plane.\n",
"\n",
"The information is stored in a [LocalCoordinateSystem](https://weldx.readthedocs.io/en/v0.5.0/_autosummary/weldx.transformations.LocalCoordinateSystem.html#weldx.transformations.LocalCoordinateSystem) instance with two points and the start and end time relative to the `reference_timestamp`.\n",
"\n",
"The YAML section of the `weldx` file describing the TCP movement looks like this:\n",
"\n",
"```yaml\n",
"TCP: !weldx!core/transformations/local_coordinate_system-0.1.0\n",
" reference_time: !weldx!time/timestamp-0.1.0 2021-03-17T11:06:42.334400\n",
" time: !weldx!time/timedeltaindex-0.1.0\n",
" values: !core/ndarray-1.0.0\n",
" data: [0, 41333333333]\n",
" datatype: int64\n",
" shape: [2]\n",
" start: !weldx!time/timedelta-0.1.0 P0DT0H0M0S\n",
" end: !weldx!time/timedelta-0.1.0 P0DT0H0M41.333333333S\n",
" min: !weldx!time/timedelta-0.1.0 P0DT0H0M0S\n",
" max: !weldx!time/timedelta-0.1.0 P0DT0H0M41.333333333S\n",
" coordinates: !weldx!core/variable-0.1.0\n",
" name: coordinates\n",
" dimensions: [time, c]\n",
" dtype: