Multi-ControlNet Curve Coordinator
Four ControlNets, four independent schedules, one graph
- SLOT_A
- SLOT_B
- SLOT_C
- SLOT_D
- combined_graph
- info
Most multi-ControlNet workflows have a subtle problem: you stack a pose net and a depth net, give both a start and end percent, and hope they don't trip over each other. This node attacks that directly - up to four ControlNet slots, each with its own timing window, its own strength curve, and its own preset, all generated in one place and visualized on a single combined graph so you can see the handoffs. It's the pack's answer to "when does each ControlNet get to talk?"
How it works
Each slot (A through D) is a complete mini-scheduler: enable_slot_X turns it on, start_percent_X / end_percent_X define when in the generation that ControlNet is active, preset_X or the manual trio (start_strength_X, end_strength_X, curve_type_X, curve_param_X) define how strong it is across that window. num_keyframes applies to all slots at once so the four streams line up. The node builds a TimestepKeyframeGroup per enabled slot and returns them as four separate outputs - SLOT_A through SLOT_D - each wired into its own Apply Advanced ControlNet instance.
The feature that earns the name "coordinator" is combined_graph: one chart plotting all four strength curves, with the active windows shaded, so a "smooth handoff" is something you can verify at a glance instead of trusting. The info output is the text summary.
The shapes of a good schedule
The README's use cases are worth internalizing because they're the actual reasons this node exists:
- Sequential control - pose guides 0–40%, then depth takes over 40–100%. No overlap, no argument.
- Overlapping transitions - give the two curves overlapping windows and opposite directions (pose fading out while depth fades in) for a smooth handoff instead of a cut.
- Targeted bursts - a slot enabled only for a 20% window where a specific structure problem lives.
Installing it
Same pack, same Advanced ControlNet dependency:
cd ComfyUI/custom_nodes
git clone https://github.com/diffussy69/comfyui-curved_weight_schedule
pip install matplotlib pillow numpy torch scipy
The outputs are TimestepKeyframes, so Kosinkadink's ComfyUI-Advanced-ControlNet must be installed or you'll get the familiar import error. Restart, hard-refresh.
Where people get burned
The divider inputs (divider_a etc.) are just visual separators - they do nothing, which is easy to forget when a workflow insists on them. Bigger trap: four slots all with default 0–1 windows is four ControlNets fighting for the whole generation, which is how you get mush. The whole point is giving each slot a different window. Start with two slots and hand-check the combined graph before adding more - the graph is the feature; use it.
Inputs (37)
| Name | Type | Default | Description |
|---|---|---|---|
| num_keyframes | INT | 102–100 | Number of keyframes (applies to all slots) |
| divider_a | STRING | ━━━━━━━ SLOT A ━━━━━━━ | — |
| enable_slot_a | BOOLEAN | true | Enable ControlNet Slot A |
| start_percent_a | FLOAT | 0.0000–1 | Start point for Slot A |
| end_percent_a | FLOAT | 1.0000–1 | End point for Slot A |
| preset_a | COMBO | Fade Out | Preset for Slot A (overrides settings below) |
| curve_type_a | COMBO | ease_out | Curve type for Slot A |
| start_strength_a | FLOAT | 1.000–10 | Start strength for Slot A |
| end_strength_a | FLOAT | 0.000–10 | End strength for Slot A |
| curve_param_a | FLOAT | 2.00.1–10 | Curve parameter for Slot A |
| divider_b | STRING | ━━━━━━━ SLOT B ━━━━━━━ | — |
| enable_slot_b | BOOLEAN | true | Enable ControlNet Slot B |
| start_percent_b | FLOAT | 0.0000–1 | Start point for Slot B |
| end_percent_b | FLOAT | 1.0000–1 | End point for Slot B |
| preset_b | COMBO | Fade In | Preset for Slot B |
| curve_type_b | COMBO | ease_in | Curve type for Slot B |
| start_strength_b | FLOAT | 0.000–10 | Start strength for Slot B |
| end_strength_b | FLOAT | 1.000–10 | End strength for Slot B |
| curve_param_b | FLOAT | 2.00.1–10 | Curve parameter for Slot B |
| divider_c | STRING | ━━━━━━━ SLOT C ━━━━━━━ | — |
| enable_slot_c | BOOLEAN | false | Enable ControlNet Slot C |
| start_percent_c | FLOAT | 0.0000–1 | Start point for Slot C |
| end_percent_c | FLOAT | 1.0000–1 | End point for Slot C |
| preset_c | COMBO | Peak Control | Preset for Slot C |
| curve_type_c | COMBO | bell_curve | Curve type for Slot C |
| start_strength_c | FLOAT | 0.500–10 | Start strength for Slot C |
| end_strength_c | FLOAT | 0.500–10 | End strength for Slot C |
| curve_param_c | FLOAT | 2.00.1–10 | Curve parameter for Slot C |
| divider_d | STRING | ━━━━━━━ SLOT D ━━━━━━━ | — |
| enable_slot_d | BOOLEAN | false | Enable ControlNet Slot D |
| start_percent_d | FLOAT | 0.0000–1 | Start point for Slot D |
| end_percent_d | FLOAT | 1.0000–1 | End point for Slot D |
| preset_d | COMBO | Custom | Preset for Slot D |
| curve_type_d | COMBO | linear | Curve type for Slot D |
| start_strength_d | FLOAT | 1.000–10 | Start strength for Slot D |
| end_strength_d | FLOAT | 0.500–10 | End strength for Slot D |
| curve_param_d | FLOAT | 2.00.1–10 | Curve parameter for Slot D |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| SLOT_A | TIMESTEP_KEYFRAME | — |
| SLOT_B | TIMESTEP_KEYFRAME | — |
| SLOT_C | TIMESTEP_KEYFRAME | — |
| SLOT_D | TIMESTEP_KEYFRAME | — |
| combined_graph | IMAGE | — |
| info | STRING | — |