How could I use "batteryChart" to plot Simscape battery objects on UIAxes in AppDesigner?

63 views (last 30 days)
Hi everyone,
the "batteryChart" command plots battery objects created with Simscape Battery (e.g. cell, module, pack).
However, when trying to use "batteryChart" in AppDesigner to plot on a UIAxes object, this does not work.
Assume that
cell
contains all relevant information on a cell object.
Then
batteryChart(app.UIAxes,app.cell)
yields the following error message:
simscape.battery.builder.BatteryChart cannot be a child of matlab.ui.control.UIAxes.
This is because the syntax of "batteryChart" is as follows:
chart = batteryChart(Parent,Battery)
where "Parent" is a Figure Object, according to MATLAB Help:
Parent Container for battery visualization
Figure object (default)
My problem is: I don't have figure objects in AppDesigner, as AppDesigner plots on UIAxes objects.
Any help or workaround would be highly appreciated!
Thanks in advance,
Hartmuth
  4 Comments
Umar
Umar on 23 Oct 2024
Hi @Harmuth,
Thank you for your kind words and for taking the time to review my work. I appreciate your efforts in providing detailed feedback, and I look forward to hearing your thoughts after you have had a chance to examine everything closely.
Paul
Paul on 26 Oct 2024 at 11:59
Hi Hartmuth,
As I understand it from reading the doc, the uiaxes object has a parent container, which by default is created from uifigure. Does batteryChart work if the first argument is the handle to the parent of the uiaxes into which you want to plot, assuming the uiaxes were created using the default settings or specifying a figure as its parent?

Sign in to comment.

Accepted Answer

Oliver Jaehrig
Oliver Jaehrig on 29 Oct 2024 at 9:46
Hi Hartmuth,
in the following I will provide information on how this works:
You are correct that the documentation shows only "figure" as a valid Parent. I will create an enhancement request for our development team to review this part of the documentation in order to make it easier to understand how this works and to also describe what is supported.
In general you can also input a uifigure or a different container, like uipanel or uigridlayout as a Parent.
So the following would work:
myCell = batteryCell(batteryCylindricalGeometry);
myUiFigure = uifigure;
batteryChart(myUiFigure,myCell);
or with uigridlayout
fig = uifigure('Position',[100 100 440 320]);
g = uigridlayout(fig);
g.RowHeight = {220,220,'1x'};
g.ColumnWidth = {1500,'1x'};
dd1 = uidropdown(g);
dd1.Items = {'Select a device'};
myCell = batteryCell(batteryCylindricalGeometry);
dd2 = batteryChart(g,myCell);
dd2.Layout.Row = 2;
dd2.Layout.Column = 1;
Thanks for reaching out to us in a Technical Support case.
If there are any further question, please let us know.
Best Regards,
Oliver
  9 Comments
Oliver Jaehrig
Oliver Jaehrig on 31 Oct 2024 at 13:11
I hope the following provides some clarity to your open questions:
  1. Same Object Type: Both figure and uifigure commands create objects of the same type, matlab.ui.Figure. This is why they both have the Type property set to 'figure'. The distinction between them lies primarily in their default property values, such as HandleVisibility and AutoResizeChildren, rather than in their fundamental object type.
  2. Current Differences: While there are some differences in functionalities between figure and uifigure due to their historical development paths, these are temporary. The goal is to unify these functionalities in a future release.
  3. Using findobj: The results from using findobj are influenced by the HandleVisibility property. Typically, uifigure objects are created with different HandleVisibility (is "off" for uifigures, which is why you did not find these) settings compared to figure objects. This is intentional, as uifigure is often used for building apps where you might not want all components to appear in findobj results.
  4. In an upcoming release, the differences between figure and uifigure will mainly be about the default property values upon creation. The long-term aim is to make them functionally equivalent, making it unnecessary to differentiate between them.
For now, if you need to specifically target uifigure objects, you might consider checking their properties or default settings that are unique to them, such as AutoResizeChildren or their initial HandleVisibility.
Paul
Paul on 31 Oct 2024 at 21:10
Ok. Regarding 1 and 2: If they have different functionalities then it seems like they would be different types of objects. But I gather that this difference is temporary, so I can see why the current situation is what it is.
Regarding 3, thanks for that clarification.

Sign in to comment.

More Answers (1)

Umar
Umar on 22 Oct 2024

Hi @Hartmuth,

You mentioned, “Any help or workaround would be highly appreciated!”

After reviewing your comments, it sounds like that the challenge you are facing arises from the fact that the batteryChart function is designed to work with Figure objects, while AppDesigner primarily utilizes UIAxes for plotting. However, there are workarounds that can help you achieve your goal. One effective method is to create a hidden Figure object in the background, plot the battery chart there, and then transfer the visual output to the UIAxes. Below is a detailed step-by-step guide along with a complete code example.

Create a Hidden Figure: This figure will serve as the parent for the batteryChart.

Plot the Battery Chart: Use the batteryChart function to plot the battery data on the hidden figure.

Copy the Chart to UIAxes: Extract the chart data and render it on the UIAxes.

Here is a complete example that demonstrates how to implement this workaround in AppDesigner:

 classdef BatteryApp < matlab.apps.AppBase
    % Properties that correspond to app components
    properties (Access = public)
        UIFigure  matlab.ui.Figure
        UIAxes    matlab.ui.control.UIAxes
        PlotButton matlab.ui.control.Button
    end
    properties (Access = private)
        Cell % Battery cell object
    end
    methods (Access = private)
        % Button pushed function: PlotButton
        function PlotButtonPushed(app, event)
            % Create a hidden figure
            hiddenFig = figure('Visible', 'off');
            % Create a battery cell object (example parameters)
            app.Cell = simscape.battery.Cell('NominalVoltage', 3.7, ...
                                              'Capacity', 2.5, ...
                                              'InternalResistance', 0.05);
            % Plot the battery chart on the hidden figure
            batteryChart(hiddenFig, app.Cell);
            % Get the current axes from the hidden figure
            ax = hiddenFig.CurrentAxes;
            % Copy the chart data to the UIAxes
            copyobj(allchild(ax), app.UIAxes);
            % Close the hidden figure
            close(hiddenFig);
        end
    end
    % Construct app
    methods (Access = public)
        % Create UI components and initialize the app
        function app = BatteryApp
            % Create and configure components
            createComponents(app)
        end
        % Create UI components
        function createComponents(app)
            % Create UIFigure
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.Position = [100 100 400 300];
            app.UIFigure.Name = 'Battery Chart App';
            % Create UIAxes
            app.UIAxes = uiaxes(app.UIFigure);
            app.UIAxes.Position = [50 50 300 200];
            % Create PlotButton
            app.PlotButton = uibutton(app.UIFigure, 'push');
            app.PlotButton.Position = [150 10 100 30];
            app.PlotButton.Text = 'Plot Battery';
            app.PlotButton.ButtonPushedFcn = @(src, event) PlotButtonPushed(app, 
            event);
            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end
  end

So, in the above code, the main application class inherits from matlab.apps.AppBase. The app contains properties for the UI components and the battery cell object. PlotButtonPushed Method is triggered when the button is pressed. It creates a hidden figure, plots the battery chart, and then copies the chart to the UIAxes and createComponents Method initializes the UI components, including the figure, axes, and button.

By following the above steps and utilizing the provided code, you can successfully plot battery objects using batteryChart within AppDesigner. This workaround will allow you to leverage the capabilities of batteryChart while adhering to the UI design principles of AppDesigner.

Hope this helps.

If you have any further questions or need additional assistance, feel free to ask!

  5 Comments
Umar
Umar on 24 Oct 2024

Hi @Hartmuth,

If that is the case then it should not have provided link to mathworks. I am trying to help you out here and this is how you are appreciating my contributions.

Sign in to comment.

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!